summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@skysql.com>2014-06-19 13:12:38 -0400
committerNirbhay Choubey <nirbhay@skysql.com>2014-06-19 13:12:38 -0400
commita76a6601ecb63d452c89202d8ca7f11bf2e0194f (patch)
tree80cefcea92a47dff8c41220411ea237022a82d4c
parent0f5522c44f9ebb002f203ad1f983b77e3925581c (diff)
parent0c64cd83eb392a0d2085eb6340623273a3402d4d (diff)
downloadmariadb-git-a76a6601ecb63d452c89202d8ca7f11bf2e0194f.tar.gz
bzr merge -rtag:mariadb-10.0.12 maria/10.0
-rw-r--r--.bzrignore2
-rw-r--r--CMakeLists.txt7
-rw-r--r--EXCEPTIONS-CLIENT136
-rw-r--r--client/mysqltest.cc4
-rw-r--r--cmake/os/WindowsCache.cmake3
-rw-r--r--dbug/CMakeLists.txt2
-rw-r--r--debian/additions/msql2mysql.116
-rw-r--r--debian/additions/my_print_defaults.116
-rw-r--r--debian/additions/myisam_ftdump.116
-rw-r--r--debian/additions/myisamchk.117
-rw-r--r--debian/additions/myisamlog.116
-rw-r--r--debian/additions/myisampack.119
-rw-r--r--debian/additions/mysql_config.117
-rw-r--r--debian/additions/mysql_convert_table_format.117
-rw-r--r--debian/additions/mysql_find_rows.118
-rw-r--r--debian/additions/mysql_fix_extensions.118
-rw-r--r--debian/additions/mysql_install_db.116
-rw-r--r--debian/additions/mysql_secure_installation.117
-rw-r--r--debian/additions/mysql_setpermission.123
-rw-r--r--debian/additions/mysql_tableinfo.1322
-rw-r--r--debian/additions/mysql_waitpid.120
-rw-r--r--debian/additions/mysqlbinlog.117
-rw-r--r--debian/additions/mysqlbug.114
-rw-r--r--debian/additions/mysqlcheck.128
-rw-r--r--debian/additions/mysqldumpslow.150
-rw-r--r--debian/additions/mysqlimport.120
-rw-r--r--debian/additions/mysqltest.116
-rw-r--r--debian/additions/pack_isam.119
-rw-r--r--debian/additions/resolve_stack_dump.116
-rw-r--r--debian/additions/resolveip.116
-rw-r--r--include/errmsg.h6
-rw-r--r--include/my_time.h2
-rw-r--r--include/mysql_com.h2
-rw-r--r--libmysql/CMakeLists.txt1
-rw-r--r--libmysql/errmsg.c6
-rw-r--r--libmysql/libmysql.c8
-rw-r--r--libmysqld/CMakeLists.txt1
-rw-r--r--man/CMakeLists.txt6
-rw-r--r--man/aria_chk.1245
-rw-r--r--man/aria_dump_log.154
-rw-r--r--man/aria_ftdump.129
-rw-r--r--man/aria_pack.176
-rw-r--r--man/aria_read_log.1108
-rw-r--r--man/mysql-test-run.pl.12
-rw-r--r--man/mysql_fix_privilege_tables.1175
-rw-r--r--man/mysqladmin.14
-rw-r--r--man/mysqlbinlog.1103
-rw-r--r--man/mysqldump.13
-rw-r--r--man/mysqlman.115
-rw-r--r--man/mysqlmanager.82078
-rw-r--r--mysql-test/collections/default.experimental1
-rw-r--r--[-rwxr-xr-x]mysql-test/collections/default.weekly0
-rw-r--r--mysql-test/extra/rpl_tests/rpl_ddl.test4
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_basic.test4
-rw-r--r--mysql-test/include/wait_until_count_sessions.inc2
-rw-r--r--mysql-test/lib/mtr_cases.pm2
-rwxr-xr-xmysql-test/mysql-test-run.pl5
-rw-r--r--mysql-test/r/alter_table.result27
-rw-r--r--mysql-test/r/cast.result16
-rw-r--r--mysql-test/r/connect.result14
-rw-r--r--mysql-test/r/derived.result14
-rw-r--r--mysql-test/r/derived_view.result2
-rw-r--r--mysql-test/r/dyncol.result31
-rw-r--r--mysql-test/r/fulltext.result4
-rw-r--r--mysql-test/r/func_misc.result588
-rw-r--r--mysql-test/r/func_str.result11
-rw-r--r--mysql-test/r/func_time.result52
-rw-r--r--mysql-test/r/grant.result26
-rw-r--r--mysql-test/r/group_min_max.result59
-rw-r--r--mysql-test/r/index_merge_myisam.result6
-rw-r--r--mysql-test/r/information_schema.result2
-rw-r--r--mysql-test/r/join_cache.result27
-rw-r--r--mysql-test/r/loaddata.result12
-rw-r--r--mysql-test/r/myisam_explain_non_select_all.result16
-rw-r--r--mysql-test/r/myisampack.result54
-rw-r--r--mysql-test/r/mysqld--help.result47
-rw-r--r--mysql-test/r/old-mode.result3
-rw-r--r--mysql-test/r/order_by.result13
-rw-r--r--mysql-test/r/outfile_loaddata.result16
-rw-r--r--mysql-test/r/partition_pruning.result52
-rw-r--r--mysql-test/r/ps.result6
-rw-r--r--mysql-test/r/ps_2myisam.result8
-rw-r--r--mysql-test/r/ps_3innodb.result8
-rw-r--r--mysql-test/r/ps_4heap.result8
-rw-r--r--mysql-test/r/ps_5merge.result16
-rw-r--r--mysql-test/r/range.result54
-rw-r--r--mysql-test/r/range_mrr_icp.result54
-rw-r--r--mysql-test/r/select_found.result34
-rw-r--r--mysql-test/r/selectivity.result6
-rw-r--r--mysql-test/r/selectivity_innodb.result6
-rw-r--r--mysql-test/r/selectivity_no_engine.result82
-rw-r--r--mysql-test/r/subselect.result32
-rw-r--r--mysql-test/r/subselect_extra.result34
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result34
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result (renamed from mysql-test/r/subselect_exists_to_in.result)42
-rw-r--r--mysql-test/r/subselect_no_mat.result28
-rw-r--r--mysql-test/r/subselect_no_opts.result12
-rw-r--r--mysql-test/r/subselect_no_scache.result32
-rw-r--r--mysql-test/r/subselect_no_semijoin.result18
-rw-r--r--mysql-test/r/subselect_sj.result6
-rw-r--r--mysql-test/r/subselect_sj2.result30
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result30
-rw-r--r--mysql-test/r/subselect_sj2_mat.result30
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result6
-rw-r--r--mysql-test/r/type_datetime.result15
-rw-r--r--mysql-test/r/type_time.result58
-rw-r--r--mysql-test/r/type_time_6065.result2310
-rw-r--r--mysql-test/r/type_time_hires.result18
-rw-r--r--mysql-test/r/union.result13
-rw-r--r--mysql-test/r/update.result2
-rw-r--r--mysql-test/r/view.result220
-rw-r--r--mysql-test/suite/binlog/r/binlog_truncate_kill.result38
-rw-r--r--mysql-test/suite/binlog/t/binlog_truncate_kill.test57
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_func_view.result16
-rw-r--r--mysql-test/suite/funcs_1/r/memory_func_view.result16
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_func_view.result16
-rw-r--r--mysql-test/suite/funcs_1/views/func_view.inc2
-rw-r--r--mysql-test/suite/funcs_1/views/views_master.inc2
-rw-r--r--mysql-test/suite/innodb/r/count_distinct.result12
-rw-r--r--mysql-test/suite/innodb/t/count_distinct.test15
-rw-r--r--mysql-test/suite/innodb_fts/r/fulltext.result6
-rw-r--r--mysql-test/suite/maria/ps_maria.result8
-rw-r--r--mysql-test/suite/perfschema/r/mks_timer-6258.result3
-rw-r--r--mysql-test/suite/perfschema/t/mks_timer-6258.test5
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_create_select.result28
-rw-r--r--mysql-test/suite/rpl/t/rpl_ddl.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat_basic.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_create_select.test28
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_basic.result16
-rw-r--r--mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc12
-rw-r--r--mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result16
-rw-r--r--mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result16
-rw-r--r--mysql-test/t/alter_table.test10
-rw-r--r--mysql-test/t/connect.test29
-rw-r--r--mysql-test/t/derived.test19
-rw-r--r--mysql-test/t/dyncol.test7
-rw-r--r--mysql-test/t/func_misc.test294
-rw-r--r--mysql-test/t/func_str.test12
-rw-r--r--mysql-test/t/func_time.test25
-rw-r--r--mysql-test/t/grant.test39
-rw-r--r--mysql-test/t/information_schema.test2
-rw-r--r--mysql-test/t/join_cache.test21
-rw-r--r--mysql-test/t/loaddata.test21
-rw-r--r--mysql-test/t/myisampack.test47
-rw-r--r--mysql-test/t/order_by.test12
-rw-r--r--mysql-test/t/outfile_loaddata.test4
-rw-r--r--mysql-test/t/partition_pruning.test57
-rw-r--r--mysql-test/t/ps.test6
-rw-r--r--mysql-test/t/range.test40
-rw-r--r--mysql-test/t/select_found.test39
-rw-r--r--mysql-test/t/selectivity_no_engine.test69
-rw-r--r--mysql-test/t/subselect_exists_to_in.test11
-rw-r--r--mysql-test/t/subselect_no_exists_to_in.test11
-rw-r--r--mysql-test/t/subselect_sj.test8
-rw-r--r--mysql-test/t/subselect_sj2.test29
-rw-r--r--mysql-test/t/type_datetime.test12
-rw-r--r--mysql-test/t/type_time.test39
-rw-r--r--mysql-test/t/type_time_6065.test177
-rw-r--r--mysql-test/t/union.test12
-rw-r--r--mysql-test/t/view.test229
-rw-r--r--mysys/my_thr_init.c3
-rw-r--r--mysys/psi_noop.c2
-rwxr-xr-x[-rw-r--r--]packaging/rpm-oel/filter-provides.sh0
-rwxr-xr-x[-rw-r--r--]packaging/rpm-oel/filter-requires.sh0
-rw-r--r--packaging/rpm-oel/mysql.spec.in89
-rw-r--r--packaging/solaris/CMakeLists.txt6
-rw-r--r--pcre/AUTHORS6
-rw-r--r--pcre/CMakeLists.txt2
-rw-r--r--pcre/ChangeLog120
-rw-r--r--pcre/INSTALL4
-rw-r--r--pcre/LICENCE6
-rw-r--r--pcre/NEWS11
-rw-r--r--pcre/README21
-rwxr-xr-xpcre/RunGrepTest818
-rwxr-xr-xpcre/RunTest42
-rw-r--r--pcre/configure.ac32
-rw-r--r--pcre/doc/html/README.txt21
-rw-r--r--pcre/doc/html/pcre.html15
-rw-r--r--pcre/doc/html/pcreapi.html114
-rw-r--r--pcre/doc/html/pcregrep.html8
-rw-r--r--pcre/doc/html/pcrepattern.html25
-rw-r--r--pcre/doc/html/pcresyntax.html79
-rw-r--r--pcre/doc/html/pcretest.html21
-rw-r--r--pcre/doc/pcre.317
-rw-r--r--pcre/doc/pcre.txt1323
-rw-r--r--pcre/doc/pcreapi.3104
-rw-r--r--pcre/doc/pcregrep.112
-rw-r--r--pcre/doc/pcregrep.txt709
-rw-r--r--pcre/doc/pcrepattern.327
-rw-r--r--pcre/doc/pcresyntax.360
-rw-r--r--pcre/doc/pcretest.124
-rw-r--r--pcre/doc/pcretest.txt375
-rw-r--r--pcre/maria-patches/pcre_stack_guard.diff57
-rw-r--r--pcre/pcre.h.in6
-rw-r--r--pcre/pcre_byte_order.c6
-rw-r--r--pcre/pcre_chartables.c198
-rw-r--r--pcre/pcre_compile.c151
-rw-r--r--pcre/pcre_dfa_exec.c69
-rw-r--r--pcre/pcre_exec.c102
-rw-r--r--pcre/pcre_globals.c2
-rw-r--r--pcre/pcre_internal.h118
-rw-r--r--pcre/pcre_jit_compile.c1921
-rw-r--r--pcre/pcre_jit_test.c72
-rw-r--r--pcre/pcre_printint.c15
-rw-r--r--pcre/pcre_string_utils.c8
-rw-r--r--pcre/pcre_stringpiece.h179
-rw-r--r--pcre/pcre_study.c62
-rw-r--r--pcre/pcre_xclass.c5
-rw-r--r--pcre/pcrecpparg.h174
-rw-r--r--pcre/pcregrep.c4
-rw-r--r--pcre/pcreposix.c6
-rw-r--r--pcre/pcretest.c92
-rw-r--r--pcre/testdata/saved16BE-1bin410 -> 418 bytes
-rw-r--r--pcre/testdata/saved16LE-1bin410 -> 418 bytes
-rw-r--r--pcre/testdata/saved32BE-1bin552 -> 560 bytes
-rw-r--r--pcre/testdata/saved32LE-1bin552 -> 560 bytes
-rw-r--r--pcre/testdata/testinput182
-rw-r--r--pcre/testdata/testinput217
-rw-r--r--pcre/testdata/testinput252
-rw-r--r--pcre/testdata/testinput311
-rw-r--r--pcre/testdata/testinput46
-rw-r--r--pcre/testdata/testinput52
-rw-r--r--pcre/testdata/testinput69
-rw-r--r--pcre/testdata/testinput76
-rw-r--r--pcre/testdata/testoutput128
-rw-r--r--pcre/testdata/testoutput132
-rw-r--r--pcre/testdata/testoutput1412
-rw-r--r--pcre/testdata/testoutput1536
-rw-r--r--pcre/testdata/testoutput168
-rw-r--r--pcre/testdata/testoutput1728
-rw-r--r--pcre/testdata/testoutput18-1642
-rw-r--r--pcre/testdata/testoutput18-3242
-rw-r--r--pcre/testdata/testoutput192
-rw-r--r--pcre/testdata/testoutput2192
-rw-r--r--pcre/testdata/testoutput21-164
-rw-r--r--pcre/testdata/testoutput21-324
-rw-r--r--pcre/testdata/testoutput22-164
-rw-r--r--pcre/testdata/testoutput22-324
-rw-r--r--pcre/testdata/testoutput2334
-rw-r--r--pcre/testdata/testoutput2536
-rw-r--r--pcre/testdata/testoutput315
-rw-r--r--pcre/testdata/testoutput3A174
-rw-r--r--pcre/testdata/testoutput3B174
-rw-r--r--pcre/testdata/testoutput48
-rw-r--r--pcre/testdata/testoutput533
-rw-r--r--pcre/testdata/testoutput612
-rw-r--r--pcre/testdata/testoutput728
-rw-r--r--pcre/testdata/testoutput82
-rw-r--r--pcre/testdata/wintestoutput34
-rw-r--r--scripts/mysql_install_db.pl.in2
-rw-r--r--scripts/mysql_install_db.sh2
-rw-r--r--scripts/mysql_system_tables.sql28
-rw-r--r--sql-common/client.c30
-rw-r--r--sql-common/my_time.c12
-rw-r--r--sql/CMakeLists.txt2
-rw-r--r--sql/field.cc124
-rw-r--r--sql/field.h56
-rw-r--r--sql/filesort.cc12
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item.cc11
-rw-r--r--sql/item_cmpfunc.cc44
-rw-r--r--sql/item_create.cc139
-rw-r--r--sql/item_func.cc71
-rw-r--r--sql/item_func.h10
-rw-r--r--sql/item_inetfunc.cc830
-rw-r--r--sql/item_inetfunc.h244
-rw-r--r--sql/item_strfunc.cc48
-rw-r--r--sql/item_strfunc.h15
-rw-r--r--sql/item_timefunc.cc10
-rw-r--r--sql/item_xmlfunc.cc2
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/multi_range_read.cc8
-rw-r--r--sql/mysqld.cc10
-rw-r--r--sql/opt_range.cc11
-rw-r--r--sql/opt_subselect.cc1
-rw-r--r--sql/password.c4
-rw-r--r--sql/rpl_gtid.cc2
-rw-r--r--sql/rpl_utility.cc2
-rw-r--r--sql/share/errmsg-utf8.txt4
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/sql_acl.cc13
-rw-r--r--sql/sql_connect.cc2
-rw-r--r--sql/sql_derived.cc17
-rw-r--r--sql/sql_error.h11
-rw-r--r--sql/sql_join_cache.cc36
-rw-r--r--sql/sql_join_cache.h15
-rw-r--r--sql/sql_load.cc64
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_priv.h3
-rw-r--r--sql/sql_select.cc99
-rw-r--r--sql/sql_select.h24
-rw-r--r--sql/sql_show.cc67
-rw-r--r--sql/sql_string.cc36
-rw-r--r--sql/sql_string.h3
-rw-r--r--sql/sql_table.cc108
-rw-r--r--sql/sql_time.cc24
-rw-r--r--sql/sql_time.h3
-rw-r--r--sql/sql_truncate.cc52
-rw-r--r--sql/sql_truncate.h10
-rw-r--r--sql/sql_update.cc7
-rw-r--r--sql/sql_yacc.yy6
-rw-r--r--sql/sys_vars.cc4
-rw-r--r--sql/table.cc5
-rw-r--r--sql/table.h2
-rw-r--r--sql/tztime.cc2
-rw-r--r--storage/archive/ha_archive.cc4
-rw-r--r--storage/connect/colblk.h1
-rw-r--r--storage/connect/connect.cc2
-rw-r--r--storage/connect/filamap.cpp2
-rw-r--r--storage/connect/filamdbf.cpp58
-rw-r--r--storage/connect/filamfix.cpp6
-rw-r--r--storage/connect/filamtxt.cpp2
-rwxr-xr-xstorage/connect/filamvct.cpp12
-rw-r--r--storage/connect/ha_connect.cc12
-rw-r--r--storage/connect/mysql-test/connect/r/csv.result4
-rw-r--r--storage/connect/mysql-test/connect/r/dbf.result4
-rw-r--r--storage/connect/mysql-test/connect/r/fix.result4
-rw-r--r--storage/connect/mysql-test/connect/r/ini.result4
-rw-r--r--storage/connect/mysql-test/connect/r/vec.result4
-rw-r--r--storage/connect/mysql-test/connect/t/csv.test370
-rw-r--r--storage/connect/mysql-test/connect/t/dbf.test4
-rw-r--r--storage/connect/mysql-test/connect/t/fix.test4
-rw-r--r--storage/connect/mysql-test/connect/t/ini.test312
-rw-r--r--storage/connect/mysql-test/connect/t/vec.test160
-rw-r--r--storage/connect/reldef.h2
-rw-r--r--storage/connect/tabdos.cpp37
-rw-r--r--storage/connect/tabdos.h3
-rw-r--r--storage/connect/tabfmt.cpp63
-rw-r--r--storage/connect/tabmysql.cpp3
-rw-r--r--storage/innobase/handler/handler0alter.cc8
-rw-r--r--storage/maria/ma_checkpoint.c4
-rw-r--r--storage/maria/ma_rnext.c2
-rw-r--r--storage/maria/maria_chk.c2
-rw-r--r--storage/myisam/mi_delete_table.c9
-rw-r--r--storage/myisam/mi_open.c7
-rw-r--r--storage/myisam/mi_rnext.c2
-rw-r--r--storage/myisam/myisampack.c11
-rw-r--r--storage/perfschema/ha_perfschema.cc2
-rw-r--r--storage/perfschema/pfs_digest.cc4
-rw-r--r--storage/spider/ha_spider.cc402
-rw-r--r--storage/spider/ha_spider.h1
-rw-r--r--storage/spider/mysql-test/spider/bg/r/direct_aggregate.result10
-rw-r--r--storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result10
-rw-r--r--storage/spider/mysql-test/spider/bg/r/spider_fixes.result1
-rw-r--r--storage/spider/mysql-test/spider/r/direct_aggregate.result10
-rw-r--r--storage/spider/mysql-test/spider/r/direct_aggregate_part.result10
-rw-r--r--storage/spider/mysql-test/spider/r/spider_fixes.result1
-rw-r--r--storage/spider/spd_conn.cc51
-rw-r--r--storage/spider/spd_db_conn.cc28
-rw-r--r--storage/spider/spd_db_handlersocket.cc32
-rw-r--r--storage/spider/spd_db_handlersocket.h5
-rw-r--r--storage/spider/spd_db_include.h14
-rw-r--r--storage/spider/spd_db_mysql.cc275
-rw-r--r--storage/spider/spd_db_mysql.h5
-rw-r--r--storage/spider/spd_db_oracle.cc36
-rw-r--r--storage/spider/spd_db_oracle.h5
-rw-r--r--storage/spider/spd_include.h32
-rw-r--r--storage/spider/spd_malloc.cc40
-rw-r--r--storage/spider/spd_ping_table.cc248
-rw-r--r--storage/spider/spd_table.cc294
-rw-r--r--storage/spider/spd_table.h24
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result2
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test4
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test4
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test4
-rw-r--r--storage/tokudb/mysql-test/tokudb_mariadb/r/mrr.result132
-rw-r--r--storage/tokudb/mysql-test/tokudb_mariadb/t/mrr.test62
-rw-r--r--storage/xtradb/handler/handler0alter.cc8
-rw-r--r--support-files/CMakeLists.txt3
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/mysql_client_fw.c70
-rw-r--r--tests/mysql_client_test.c116
-rw-r--r--win/packaging/heidisql.cmake4
379 files changed, 15238 insertions, 8317 deletions
diff --git a/.bzrignore b/.bzrignore
index 525efc10624..f3eea45467b 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1468,3 +1468,5 @@ storage/connect/connect.cnf
storage/cassandra/cassandra.cnf
libmysql/libmysql_versions.ld
scripts/mysql_config.pl
+pcre/pcre_chartables.c
+pcre/test*grep
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 393aff64faa..3aafc852f16 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,6 +61,7 @@ IF(UNIX AND NOT APPLE)
# Compiling with PIC speeds up embedded build, on PIC sensitive systems
# Predefine it to OFF in release builds, because of the performance penalty
SET(WITH_PIC ${WITH_PIC_DEFAULT} CACHE BOOL "Compile with PIC.")
+ MARK_AS_ADVANCED(WITH_PIC)
ENDIF()
# Optionally set project name, e.g.
@@ -266,6 +267,10 @@ IF (ENABLE_GCOV AND NOT WIN32 AND NOT APPLE)
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov")
ENDIF()
+MY_CHECK_C_COMPILER_FLAG(-ggdb3 HAVE_GGDB3)
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb3")
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3")
+
OPTION(ENABLED_LOCAL_INFILE
"If we should should enable LOAD DATA LOCAL by default" ${IF_WIN})
MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE)
@@ -487,7 +492,7 @@ ADD_CUSTOM_TARGET(INFO_BIN ALL
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
-INSTALL_DOCUMENTATION(README TODO CREDITS COPYING COPYING.LESSER
+INSTALL_DOCUMENTATION(README CREDITS COPYING COPYING.LESSER EXCEPTIONS-CLIENT
COMPONENT Readme)
INSTALL_DOCUMENTATION(${CMAKE_BINARY_DIR}/Docs/INFO_SRC
${CMAKE_BINARY_DIR}/Docs/INFO_BIN)
diff --git a/EXCEPTIONS-CLIENT b/EXCEPTIONS-CLIENT
new file mode 100644
index 00000000000..11ba42c422f
--- /dev/null
+++ b/EXCEPTIONS-CLIENT
@@ -0,0 +1,136 @@
+ FOSS License Exception
+
+ http://www.mysql.com/about/legal/licensing/foss-exception/
+ Updated February 23, 2012
+
+What is the FOSS License Exception?
+
+ Oracle's Free and Open Source Software ("FOSS") License Exception
+ (formerly known as the FLOSS License Exception) allows developers of FOSS
+ applications to include Oracle's MySQL Client Libraries (also referred to
+ as "MySQL Drivers" or "MySQL Connectors") with their FOSS applications.
+ MySQL Client Libraries are typically licensed pursuant to version 2 of the
+ General Public License ("GPL"), but this exception permits distribution of
+ certain MySQL Client Libraries with a developer's FOSS applications
+ licensed under the terms of another FOSS license listed below, even though
+ such other FOSS license may be incompatible with the GPL.
+
+ The following terms and conditions describe the circumstances under which
+ Oracle's FOSS License Exception applies.
+
+Oracle's FOSS License Exception Terms and Conditions
+
+ 1. Definitions. "Derivative Work" means a derivative work, as defined
+ under applicable copyright law, formed entirely from the Program and
+ one or more FOSS Applications.
+
+ "FOSS Application" means a free and open source software application
+ distributed subject to a license listed in the section below titled
+ "FOSS License List."
+
+ "FOSS Notice" means a notice placed by Oracle or MySQL in a copy of
+ the MySQL Client Libraries stating that such copy of the MySQL Client
+ Libraries may be distributed under Oracle's or MySQL's FOSS (or FLOSS)
+ License Exception.
+
+ "Independent Work" means portions of the Derivative Work that are not
+ derived from the Program and can reasonably be considered independent
+ and separate works.
+
+ "Program" means a copy of Oracle's MySQL Client Libraries that
+ contains a FOSS Notice.
+
+ 2. A FOSS application developer ("you" or "your") may distribute a
+ Derivative Work provided that you and the Derivative Work meet all of
+ the following conditions:
+
+ a. You obey the GPL in all respects for the Program and all portions
+ (including modifications) of the Program included in the
+ Derivative Work (provided that this condition does not apply to
+ Independent Works);
+ b. The Derivative Work does not include any work licensed under the
+ GPL other than the Program;
+ c. You distribute Independent Works subject to a license listed in
+ the section below titled "FOSS License List";
+ d. You distribute Independent Works in object code or executable
+ form with the complete corresponding machine-readable source code
+ on the same medium and under the same FOSS license applying to
+ the object code or executable forms;
+ e. All works that are aggregated with the Program or the Derivative
+ Work on a medium or volume of storage are not derivative works of
+ the Program, Derivative Work or FOSS Application, and must
+ reasonably be considered independent and separate works.
+
+ 3. Oracle reserves all rights not expressly granted in these terms and
+ conditions. If all of the above conditions are not met, then this FOSS
+ License Exception does not apply to you or your Derivative Work.
+
+FOSS License List
+
++------------------------------------------------------------------------+
+|License Name |Version(s)/Copyright Date|
+|----------------------------------------------+-------------------------|
+|Academic Free License |2.0 |
+|----------------------------------------------+-------------------------|
+|Apache Software License |1.0/1.1/2.0 |
+|----------------------------------------------+-------------------------|
+|Apple Public Source License |2.0 |
+|----------------------------------------------+-------------------------|
+|Artistic license |From Perl 5.8.0 |
+|----------------------------------------------+-------------------------|
+|BSD license |"July 22 1999" |
+|----------------------------------------------+-------------------------|
+|Common Development and Distribution License |1.0 |
+|(CDDL) | |
+|----------------------------------------------+-------------------------|
+|Common Public License |1.0 |
+|----------------------------------------------+-------------------------|
+|Eclipse Public License |1.0 |
+|----------------------------------------------+-------------------------|
+|European Union Public License (EUPL)¹ |1.1 |
+|----------------------------------------------+-------------------------|
+|GNU Affero General Public License (AGPL) |3.0 |
+|----------------------------------------------+-------------------------|
+|GNU Library or "Lesser" General Public License|2.0/2.1/3.0 |
+|(LGPL) | |
+|----------------------------------------------+-------------------------|
+|GNU General Public License (GPL) |3.0 |
+|----------------------------------------------+-------------------------|
+|IBM Public License |1.0 |
+|----------------------------------------------+-------------------------|
+|Jabber Open Source License |1.0 |
+|----------------------------------------------+-------------------------|
+|MIT License (As listed in file |- |
+|MIT-License.txt) | |
+|----------------------------------------------+-------------------------|
+|Mozilla Public License (MPL) |1.0/1.1 |
+|----------------------------------------------+-------------------------|
+|Open Software License |2.0 |
+|----------------------------------------------+-------------------------|
+|OpenSSL license (with original SSLeay license)|"2003" ("1998") |
+|----------------------------------------------+-------------------------|
+|PHP License |3.0/3.01 |
+|----------------------------------------------+-------------------------|
+|Python license (CNRI Python License) |- |
+|----------------------------------------------+-------------------------|
+|Python Software Foundation License |2.1.1 |
+|----------------------------------------------+-------------------------|
+|Sleepycat License |"1999" |
+|----------------------------------------------+-------------------------|
+|University of Illinois/NCSA Open Source |- |
+|License | |
+|----------------------------------------------+-------------------------|
+|W3C License |"2001" |
+|----------------------------------------------+-------------------------|
+|X11 License |"2001" |
+|----------------------------------------------+-------------------------|
+|Zlib/libpng License |- |
+|----------------------------------------------+-------------------------|
+|Zope Public License |2.0 |
++------------------------------------------------------------------------+
+
+¹) When an Independent Work is licensed under a "Compatible License"
+pursuant to the EUPL, the Compatible License rather than the EUPL is the
+applicable license for purposes of these FOSS License Exception Terms and
+Conditions.
+
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index efece866ef5..ef339d17a42 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -949,9 +949,13 @@ static int do_read_query_result(struct st_connection *cn)
{
DBUG_ASSERT(cn->has_thread);
wait_query_thread_done(cn);
+ if (cn->result)
+ goto exit_func;
+
signal_connection_thd(cn, EMB_READ_QUERY_RESULT);
wait_query_thread_done(cn);
+exit_func:
return cn->result;
}
diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake
index 2a6fb5ae31f..1453cc55053 100644
--- a/cmake/os/WindowsCache.cmake
+++ b/cmake/os/WindowsCache.cmake
@@ -370,4 +370,5 @@ SET(HAVE_SYS_UTSNAME_H CACHE INTERNAL "")
SET(HAVE_PTHREAD_ATTR_GETGUARDSIZE CACHE INTERNAL "")
SET(HAVE_UCONTEXT_H CACHE INTERNAL "")
SET(HAVE_SOCKPEERCRED CACHE INTERNAL "")
-ENDIF()
+SET(HAVE_GGDB3 CACHE INTERNAL "")
+ENDIF(MSVC)
diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt
index fddf234a4f1..3d0b0801132 100644
--- a/dbug/CMakeLists.txt
+++ b/dbug/CMakeLists.txt
@@ -30,6 +30,8 @@ TARGET_LINK_LIBRARIES(factorial dbug)
IF(NOT WIN32 AND NOT CMAKE_GENERATOR MATCHES Xcode)
FIND_PROGRAM(GROFF groff)
FIND_PROGRAM(NROFF nroff)
+ MARK_AS_ADVANCED(GROFF)
+ MARK_AS_ADVANCED(NROFF)
SET(OUTPUT_INC output1.r output2.r output3.r output4.r output5.r)
SET(SOURCE_INC factorial.r main.r example1.r example2.r example3.r)
ADD_CUSTOM_COMMAND(OUTPUT ${OUTPUT_INC}
diff --git a/debian/additions/msql2mysql.1 b/debian/additions/msql2mysql.1
deleted file mode 100644
index 8fe05e7415d..00000000000
--- a/debian/additions/msql2mysql.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-msql2mysql \- MySQL importer for msql style data.
-.SH SYNOPSIS
-msql2mysql [options]
-.SH DESCRIPTION
-This program imports old msql database files.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/my_print_defaults.1 b/debian/additions/my_print_defaults.1
deleted file mode 100644
index ebef4157016..00000000000
--- a/debian/additions/my_print_defaults.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-my_print_defaults \- MySQL helper script that prints defaults.
-.SH SYNOPSIS
-my_print_defaults [options]
-.SH DESCRIPTION
-Prints all arguments that is give to some program using the default files.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/myisam_ftdump.1 b/debian/additions/myisam_ftdump.1
deleted file mode 100644
index e2de358efcc..00000000000
--- a/debian/additions/myisam_ftdump.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-myisam_ftdump \- Dumps full text tables.
-.SH SYNOPSIS
-myisam_ftdump [options]
-.SH DESCRIPTION
-Dumps information and contents of full text tables.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/myisamchk.1 b/debian/additions/myisamchk.1
deleted file mode 100644
index fe7f34961e0..00000000000
--- a/debian/additions/myisamchk.1
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-myisamchk \- Checks MySQL myisam type databases.
-.SH SYNOPSIS
-myisamchk [options]
-.SH DESCRIPTION
-Description, check and repair of ISAM tables.
-Used without options all tables on the command will be checked for errors
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/myisamlog.1 b/debian/additions/myisamlog.1
deleted file mode 100644
index 959d547df94..00000000000
--- a/debian/additions/myisamlog.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-myisamlog \- MySQL helper script.
-.SH SYNOPSIS
-myisamlog [options]
-.SH DESCRIPTION
-Function unknown. Mail to ch@debian.org.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/myisampack.1 b/debian/additions/myisampack.1
deleted file mode 100644
index 93168304a17..00000000000
--- a/debian/additions/myisampack.1
+++ /dev/null
@@ -1,19 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-myisampack \- Compresses MySQL database files.
-.SH SYNOPSIS
-myisampack [options]
-.SH DESCRIPTION
-Pack a MyISAM-table to take much less space.
-Keys are not updated, you must run myisamchk -rq on the datafile
-afterwards to update the keys.
-You should give the .MYI file as the filename argument.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_config.1 b/debian/additions/mysql_config.1
deleted file mode 100644
index 88095e22b9e..00000000000
--- a/debian/additions/mysql_config.1
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqlconfig \- MySQL compile settings.
-.SH SYNOPSIS
-mysqlconfig [options]
-.SH DESCRIPTION
-This program is only useful for people who want to compile agains
-libmysqlclient.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_convert_table_format.1 b/debian/additions/mysql_convert_table_format.1
deleted file mode 100644
index 3c23581df43..00000000000
--- a/debian/additions/mysql_convert_table_format.1
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_convert_table_format \- MySQL table converter.
-.SH SYNOPSIS
-mysql_convert_table_format [options]
-.SH DESCRIPTION
-Conversion of a MySQL tables to other table types.
-If no tables has been specifed, all tables in the database will be converted.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_find_rows.1 b/debian/additions/mysql_find_rows.1
deleted file mode 100644
index 35a70b1f960..00000000000
--- a/debian/additions/mysql_find_rows.1
+++ /dev/null
@@ -1,18 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_find_rows \- MySQL shell skript for searching in update logs.
-.SH SYNOPSIS
-mysql_find_rows [options]
-.SH DESCRIPTION
-Prints all SQL queries that matches a regexp or contains a 'use
-database' or 'set ..' command to stdout. A SQL query may contain
-newlines. This is useful to find things in a MySQL update log.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_fix_extensions.1 b/debian/additions/mysql_fix_extensions.1
deleted file mode 100644
index 3f0a028ca3f..00000000000
--- a/debian/additions/mysql_fix_extensions.1
+++ /dev/null
@@ -1,18 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_fix_extensions \- Corrects MySQL database file names.
-.SH SYNOPSIS
-mysql_fix_extensions <datadir>
-.SH DESCRIPTION
-Makes .frm lowercase and .MYI/MYD/ISM/ISD uppercase
-useful when datafiles are copied from windows.
-Does not work with RAID, with InnoDB or BDB tables.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (8)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_install_db.1 b/debian/additions/mysql_install_db.1
deleted file mode 100644
index 11f1f2967a2..00000000000
--- a/debian/additions/mysql_install_db.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_install_db \- MySQL helper program.
-.SH SYNOPSIS
-mysql_install_db [options]
-.SH DESCRIPTION
-This program is normally not needed by any user.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_secure_installation.1 b/debian/additions/mysql_secure_installation.1
deleted file mode 100644
index d65b7f5d09d..00000000000
--- a/debian/additions/mysql_secure_installation.1
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_secure_installation \- Secures the MySQL access control lists.
-.SH SYNOPSIS
-mysql_secure_installation [options]
-.SH DESCRIPTION
-This interactive programm suggests changes like removing anonymous users that
-are supposed to make your installation more secure.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (8)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_setpermission.1 b/debian/additions/mysql_setpermission.1
deleted file mode 100644
index 77167e0d58f..00000000000
--- a/debian/additions/mysql_setpermission.1
+++ /dev/null
@@ -1,23 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_setpermission \- Adds MySQL users or changes passwords.
-.SH SYNOPSIS
-mysql_setpermission [options]
-.SH DESCRIPTION
-The permission setter is a little program which can help you add users
-or databases or change passwords in MySQL. Keep in mind that we don't
-check permissions which already been set in MySQL. So if you can't
-connect to MySQL using the permission you just added, take a look at
-the permissions which have already been set in MySQL.
-
-The permission setter first reads your .my.cnf file in your Home
-directory if it exists.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysql_tableinfo.1 b/debian/additions/mysql_tableinfo.1
deleted file mode 100644
index 1de4f5d5943..00000000000
--- a/debian/additions/mysql_tableinfo.1
+++ /dev/null
@@ -1,322 +0,0 @@
-.\" Automatically generated by Pod::Man v1.34, Pod::Parser v1.13
-.\"
-.\" Standard preamble:
-.\" ========================================================================
-.de Sh \" Subsection heading
-.br
-.if t .Sp
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp \" Vertical space (when we can't use .PP)
-.if t .sp .5v
-.if n .sp
-..
-.de Vb \" Begin verbatim text
-.ft CW
-.nf
-.ne \\$1
-..
-.de Ve \" End verbatim text
-.ft R
-.fi
-..
-.\" Set up some character translations and predefined strings. \*(-- will
-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
-.\" double quote, and \*(R" will give a right double quote. | will give a
-.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
-.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
-.\" expand to `' in nroff, nothing in troff, for use with C<>.
-.tr \(*W-|\(bv\*(Tr
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
-.ie n \{\
-. ds -- \(*W-
-. ds PI pi
-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-. ds L" ""
-. ds R" ""
-. ds C` ""
-. ds C' ""
-'br\}
-.el\{\
-. ds -- \|\(em\|
-. ds PI \(*p
-. ds L" ``
-. ds R" ''
-'br\}
-.\"
-.\" If the F register is turned on, we'll generate index entries on stderr for
-.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
-.\" entries marked with X<> in POD. Of course, you'll have to process the
-.\" output yourself in some meaningful fashion.
-.if \nF \{\
-. de IX
-. tm Index:\\$1\t\\n%\t"\\$2"
-..
-. nr % 0
-. rr F
-.\}
-.\"
-.\" For nroff, turn off justification. Always turn off hyphenation; it makes
-.\" way too many mistakes in technical documents.
-.hy 0
-.if n .na
-.\"
-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
-.\" Fear. Run. Save yourself. No user-serviceable parts.
-. \" fudge factors for nroff and troff
-.if n \{\
-. ds #H 0
-. ds #V .8m
-. ds #F .3m
-. ds #[ \f1
-. ds #] \fP
-.\}
-.if t \{\
-. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
-. ds #V .6m
-. ds #F 0
-. ds #[ \&
-. ds #] \&
-.\}
-. \" simple accents for nroff and troff
-.if n \{\
-. ds ' \&
-. ds ` \&
-. ds ^ \&
-. ds , \&
-. ds ~ ~
-. ds /
-.\}
-.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
-.\}
-. \" troff and (daisy-wheel) nroff accents
-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
-.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
-.ds ae a\h'-(\w'a'u*4/10)'e
-.ds Ae A\h'-(\w'A'u*4/10)'E
-. \" corrections for vroff
-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
-. \" for low resolution devices (crt and lpr)
-.if \n(.H>23 .if \n(.V>19 \
-\{\
-. ds : e
-. ds 8 ss
-. ds o a
-. ds d- d\h'-1'\(ga
-. ds D- D\h'-1'\(hy
-. ds th \o'bp'
-. ds Th \o'LP'
-. ds ae ae
-. ds Ae AE
-.\}
-.rm #[ #] #H #V #F C
-.\" ========================================================================
-.\"
-.IX Title "MYSQL_TABLEINFO 1"
-.TH MYSQL_TABLEINFO 1 "2003-04-05" "perl v5.8.0" "User Contributed Perl Documentation"
-.SH "NAME"
-mysql_tableinfo \- creates and populates information tables with
-the output of SHOW DATABASES, SHOW TABLES (or SHOW TABLE STATUS),
-SHOW COLUMNS and SHOW INDEX.
-.PP
-This is version 1.1.
-.SH "SYNOPSIS"
-.IX Header "SYNOPSIS"
-.Vb 1
-\& mysql_tableinfo [OPTIONS] database_to_write [database_like_wild] [table_like_wild]
-.Ve
-.PP
-.Vb 2
-\& Do not backquote (``) database_to_write,
-\& and do not quote ('') database_like_wild or table_like_wild
-.Ve
-.PP
-.Vb 1
-\& Examples:
-.Ve
-.PP
-.Vb 1
-\& mysql_tableinfo info
-.Ve
-.PP
-.Vb 1
-\& mysql_tableinfo info this_db
-.Ve
-.PP
-.Vb 1
-\& mysql_tableinfo info %a% b%
-.Ve
-.PP
-.Vb 1
-\& mysql_tableinfo info --clear-only
-.Ve
-.PP
-.Vb 1
-\& mysql_tableinfo info --col --idx --table-status
-.Ve
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-mysql_tableinfo asks a MySQL server information about its
-databases, tables, table columns and index, and stores this
-in tables called `db`, `tbl` (or `tbl_status`), `col`, `idx`
-(with an optional prefix specified with \-\-prefix).
-After that, you can query these information tables, for example
-to build your admin scripts with \s-1SQL\s0 queries, like
-.PP
-\&\s-1SELECT\s0 \s-1CONCAT\s0(\*(L"\s-1CHECK\s0 \s-1TABLE\s0 \*(R",`database`,\*(L".\*(R",`table`,\*(L" \s-1EXTENDED\s0;\*(R")
-\&\s-1FROM\s0 info.tbl \s-1WHERE\s0 ... ;
-.PP
-as people usually do with some other \s-1RDBMS\s0
-(note: to increase the speed of your queries on the info tables,
-you may add some index on them).
-.PP
-The database_like_wild and table_like_wild instructs the program
-to gather information only about databases and tables
-whose names match these patterns. If the info
-tables already exist, their rows matching the patterns are simply
-deleted and replaced by the new ones. That is,
-old rows not matching the patterns are not touched.
-If the database_like_wild and table_like_wild arguments
-are not specified on the command-line they default to \*(L"%\*(R".
-.PP
-The program :
-.PP
-\&\- does \s-1CREATE\s0 \s-1DATABASE\s0 \s-1IF\s0 \s-1NOT\s0 \s-1EXISTS\s0 database_to_write
-where database_to_write is the database name specified on the command\-line.
-.PP
-\&\- does \s-1CREATE\s0 \s-1TABLE\s0 \s-1IF\s0 \s-1NOT\s0 \s-1EXISTS\s0 database_to_write.`db`
-.PP
-\&\- fills database_to_write.`db` with the output of
-\&\s-1SHOW\s0 \s-1DATABASES\s0 \s-1LIKE\s0 database_like_wild
-.PP
-\&\- does \s-1CREATE\s0 \s-1TABLE\s0 \s-1IF\s0 \s-1NOT\s0 \s-1EXISTS\s0 database_to_write.`tbl`
-(respectively database_to_write.`tbl_status`
-if the \-\-tbl\-status option is on)
-.PP
-\&\- for every found database,
-fills database_to_write.`tbl` (respectively database_to_write.`tbl_status`)
-with the output of
-\&\s-1SHOW\s0 \s-1TABLES\s0 \s-1FROM\s0 found_db \s-1LIKE\s0 table_like_wild
-(respectively \s-1SHOW\s0 \s-1TABLE\s0 \s-1STATUS\s0 \s-1FROM\s0 found_db \s-1LIKE\s0 table_like_wild)
-.PP
-\&\- if the \-\-col option is on,
- * does \s-1CREATE\s0 \s-1TABLE\s0 \s-1IF\s0 \s-1NOT\s0 \s-1EXISTS\s0 database_to_write.`col`
- * for every found table,
- fills database_to_write.`col` with the output of
- \s-1SHOW\s0 \s-1COLUMNS\s0 \s-1FROM\s0 found_tbl \s-1FROM\s0 found_db
-.PP
-\&\- if the \-\-idx option is on,
- * does \s-1CREATE\s0 \s-1TABLE\s0 \s-1IF\s0 \s-1NOT\s0 \s-1EXISTS\s0 database_to_write.`idx`
- * for every found table,
- fills database_to_write.`idx` with the output of
- \s-1SHOW\s0 \s-1INDEX\s0 \s-1FROM\s0 found_tbl \s-1FROM\s0 found_db
-.PP
-Some options may modify this general scheme (see below).
-.PP
-As mentioned, the contents of the info tables are the output of
-\&\s-1SHOW\s0 commands. In fact the contents are slightly more complete :
-.PP
-\&\- the `tbl` (or `tbl_status`) info table
- has an extra column which contains the database name,
-.PP
-\&\- the `col` info table
- has an extra column which contains the table name,
- and an extra column which contains, for each described column,
- the number of this column in the table owning it (this extra column
- is called `Seq_in_table`). `Seq_in_table` makes it possible for you
- to retrieve your columns in sorted order, when you are querying
- the `col` table.
-.PP
-\&\- the `index` info table
- has an extra column which contains the database name.
-.PP
-Caution: info tables contain certain columns (e.g.
-Database, Table, Null...) whose names, as they are MySQL reserved words,
-need to be backquoted (`...`) when used in \s-1SQL\s0 statements.
-.PP
-Caution: as information fetching and info tables filling happen at the
-same time, info tables may contain inaccurate information about
-themselves.
-.SH "OPTIONS"
-.IX Header "OPTIONS"
-.IP "\-\-clear" 4
-.IX Item "--clear"
-Does \s-1DROP\s0 \s-1TABLE\s0 on the info tables (only those that the program is
-going to fill, for example if you do not use \-\-col it won't drop
-the `col` table) and processes normally. Does not drop database_to_write.
-.IP "\-\-clear\-only" 4
-.IX Item "--clear-only"
-Same as \-\-clear but exits after the DROPs.
-.IP "\-\-col" 4
-.IX Item "--col"
-Adds columns information (into table `col`).
-.IP "\-\-idx" 4
-.IX Item "--idx"
-Adds index information (into table `idx`).
-.IP "\-\-prefix prefix" 4
-.IX Item "--prefix prefix"
-The info tables are named from the concatenation of prefix and,
-respectively, db, tbl (or tbl_status), col, idx. Do not quote ('')
-or backquote (``) prefix.
-.IP "\-q, \-\-quiet" 4
-.IX Item "-q, --quiet"
-Does not warn you about what the script is going to do (\s-1DROP\s0 \s-1TABLE\s0 etc)
-and does not ask for a confirmation before starting.
-.IP "\-\-tbl\-status" 4
-.IX Item "--tbl-status"
-Instead of using \s-1SHOW\s0 \s-1TABLES\s0, uses \s-1SHOW\s0 \s-1TABLE\s0 \s-1STATUS\s0
-(much more complete information, but slower).
-.IP "\-\-help" 4
-.IX Item "--help"
-Display helpscreen and exit
-.IP "\-u, \-\-user=#" 4
-.IX Item "-u, --user=#"
-user for database login if not current user. Give a user
-who has sufficient privileges (\s-1CREATE\s0, ...).
-.IP "\-p, \-\-password=# (INSECURE)" 4
-.IX Item "-p, --password=# (INSECURE)"
-password to use when connecting to server.
-WARNING: Providing a password on command line is insecure as it is visible through /proc to anyone for a short time.
-.IP "\-h, \-\-host=#" 4
-.IX Item "-h, --host=#"
-host to connect to
-.IP "\-P, \-\-port=#" 4
-.IX Item "-P, --port=#"
-port to use when connecting to server
-.IP "\-S, \-\-socket=#" 4
-.IX Item "-S, --socket=#"
-\&\s-1UNIX\s0 domain socket to use when connecting to server
-.SH "WARRANTY"
-.IX Header "WARRANTY"
-This software is free and comes without warranty of any kind. You
-should never trust backup software without studying the code yourself.
-Study the code inside this script and only rely on it if \fIyou\fR believe
-that it does the right thing for you.
-.Sp
-Patches adding bug fixes, documentation and new features are welcome.
-.SH "TO DO"
-.IX Header "TO DO"
-Use extended inserts to be faster (for servers with many databases
-or tables). But to do that, must care about net\-buffer\-length.
-.SH "AUTHOR"
-.IX Header "AUTHOR"
-2002\-06\-18 Guilhem Bichot (guilhem.bichot@mines\-paris.org)
-.Sp
-And all the authors of mysqlhotcopy, which served as a model for
-the structure of the program.
diff --git a/debian/additions/mysql_waitpid.1 b/debian/additions/mysql_waitpid.1
deleted file mode 100644
index f6877865ba8..00000000000
--- a/debian/additions/mysql_waitpid.1
+++ /dev/null
@@ -1,20 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysql_waitpid \- Waits a specified amount of seconds for a PID to terminate.
-.SH SYNOPSIS
-mysql_waitpid [options] <pid> <seconds>
-.SH DESCRIPTION
-Description: Waits for a program, which program id is #pid, to
-terminate within #time seconds. If the program terminates within
-this time, or if the #pid no longer exists, value 0 is returned.
-Otherwise 1 is returned. Both #pid and #time must be positive
-integer arguments.
-
-See mysql_waitpid for options.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysqlbinlog.1 b/debian/additions/mysqlbinlog.1
deleted file mode 100644
index fcdf2a083f4..00000000000
--- a/debian/additions/mysqlbinlog.1
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqlbinlog \- Dumps MySQL binary logs.
-.SH SYNOPSIS
-mysqlbinlog [options]
-.SH DESCRIPTION
-Dumps a MySQL binary log in a format usable for viewing or for pipeing to
-the mysql command line client
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysqlbug.1 b/debian/additions/mysqlbug.1
deleted file mode 100644
index 133330dd897..00000000000
--- a/debian/additions/mysqlbug.1
+++ /dev/null
@@ -1,14 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqlbug \- MySQL bug reporting tool.
-.SH SYNOPSIS
-mysqlbug [options]
-.SH DESCRIPTION
-Interactive bug reporting tool. Use reportbug on Debian systems.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysqlcheck.1 b/debian/additions/mysqlcheck.1
deleted file mode 100644
index b36ba2d1eb1..00000000000
--- a/debian/additions/mysqlcheck.1
+++ /dev/null
@@ -1,28 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqlcheck \- MySQL program for repairing, checking and optimizing tables.
-.SH SYNOPSIS
-mysqlcheck | mysqlanalyze | mysqloptimize [options]
-.SH DESCRIPTION
-This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)
-or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be
-used same time. It works on MyISAM and in some cases on BDB tables.
-Please consult the MySQL manual for latest information about the
-above. The options -c,-r,-a and -o are exclusive to each other, which
-means that the last option will be used, if several was specified.
-
-The option -c will be used by default, if none was specified. You
-can change the default behavior by making a symbolic link, or
-copying this file somewhere with another name, the alternatives are:
-mysqlrepair: The default option will be -r
-mysqlanalyze: The default option will be -a
-mysqloptimize: The default option will be -o
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (8)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysqldumpslow.1 b/debian/additions/mysqldumpslow.1
deleted file mode 100644
index 0431ef04cbb..00000000000
--- a/debian/additions/mysqldumpslow.1
+++ /dev/null
@@ -1,50 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqldumpslow \- Parse and summarize the MySQL slow query log.
-.SH SYNOPSIS
-mysqldumpslow [options]
-.SH DESCRIPTION
-This program parses and summarizes a 'slow query log'.
-
-.TP
-\fB\-v\fR
-verbose
-.TP
-\fB\-d\fR
-debug
-.TP
-\fB\-s=WORD\fR
-what to sort by (t, at, l, al, r, ar etc)
-.TP
-\fB\-r\fR
-reverse the sort order (largest last instead of first)
-.TP
-\fB\-t=NUMBER\fR
-just show the top n queries
-.TP
-\fB\-a\fR
-don't abstract all numbers to N and strings to 'S'
-.TP
-\fB\-n=NUMBER\fR
-abstract numbers with at least n digits within names
-.TP
-\fB\-g=WORD\fR
-grep: only consider stmts that include this string
-.TP
-\fB\-h=WORD\fR
-hostname of db server for *-slow.log filename (can be wildcard)
-.TP
-\fB\-i=WORD\fR
-name of server instance (if using mysql.server startup script)
-.TP
-\fB\-l\fR
-don't subtract lock time from total time
-
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org> based on
-the commends in the code.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysqlimport.1 b/debian/additions/mysqlimport.1
deleted file mode 100644
index 9007307a328..00000000000
--- a/debian/additions/mysqlimport.1
+++ /dev/null
@@ -1,20 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqlimport \- Imports text files with MySQL database queries.
-.SH SYNOPSIS
-mysqlimport [options]
-.SH DESCRIPTION
-Loads tables from text files in various formats. The base name of the
-text file must be the name of the table that should be used.
-If one uses sockets to connect to the MySQL server, the server will open and
-read the text file directly. In other cases the client will open the text
-file. The SQL command 'LOAD DATA INFILE' is used to import the rows.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/mysqltest.1 b/debian/additions/mysqltest.1
deleted file mode 100644
index 3469765fe3b..00000000000
--- a/debian/additions/mysqltest.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-mysqltest \- Regressiontest program for MySQL.
-.SH SYNOPSIS
-mysqltest [options]
-.SH DESCRIPTION
-Runs a test against the mysql server and compares output with a results file.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/pack_isam.1 b/debian/additions/pack_isam.1
deleted file mode 100644
index cad153eedee..00000000000
--- a/debian/additions/pack_isam.1
+++ /dev/null
@@ -1,19 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-myisampack \- Compresses MySQL database files.
-.SH SYNOPSIS
-myisampack [options]
-.SH DESCRIPTION
-Pack a ISAM-table to take much smaller space
-Keys are not updated, so you must run isamchk -rq on any table
-that has keys after you have compressed it
-You should give the .ISM file as the filename argument
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/resolve_stack_dump.1 b/debian/additions/resolve_stack_dump.1
deleted file mode 100644
index 2a1e2770275..00000000000
--- a/debian/additions/resolve_stack_dump.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-resolve_stack_dump \- MySQL helper program for reporting bugs.
-.SH SYNOPSIS
-resolve_stack_dump [options]
-.SH DESCRIPTION
-Resolve numeric stack strace dump into symbols.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/debian/additions/resolveip.1 b/debian/additions/resolveip.1
deleted file mode 100644
index 7aa9439394d..00000000000
--- a/debian/additions/resolveip.1
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH mysql 1 "17 March 2003" "MySQL 3.23" "MySQL database"
-.SH NAME
-resolveip \- MySQL helper program to retrive IP addresses.
-.SH SYNOPSIS
-resolveip [options]
-.SH DESCRIPTION
-Get hostname based on IP-address or IP-address based on hostname.
-
-For more information start the program with '--help'.
-.SH "SEE ALSO"
-mysql (1), mysqld (1)
-.SH AUTHOR
-This manpage was written by Christian Hammers <ch@debian.org>.
-
-MySQL is available at http://www.mysql.com/.
-.\" end of man page
diff --git a/include/errmsg.h b/include/errmsg.h
index b839060a881..be4203b7f75 100644
--- a/include/errmsg.h
+++ b/include/errmsg.h
@@ -1,7 +1,7 @@
#ifndef ERRMSG_INCLUDED
#define ERRMSG_INCLUDED
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,7 +36,9 @@ extern const char *client_errors[]; /* Error messages */
#define CR_MIN_ERROR 2000 /* For easier client code */
#define CR_MAX_ERROR 2999
#if !defined(ER)
-#define ER(X) client_errors[(X)-CR_MIN_ERROR]
+#define ER(X) (((X) >= CR_ERROR_FIRST && (X) <= CR_ERROR_LAST)? \
+ client_errors[(X)-CR_ERROR_FIRST]: client_errors[CR_UNKNOWN_ERROR])
+
#endif
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
diff --git a/include/my_time.h b/include/my_time.h
index 3c45d1d9235..557dcdd5670 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -125,7 +125,7 @@ longlong double_to_datetime(double nr, MYSQL_TIME *ltime, uint flags, int *cut)
ltime, flags, cut);
}
-int number_to_time(my_bool neg, longlong nr, ulong sec_part,
+int number_to_time(my_bool neg, ulonglong nr, ulong sec_part,
MYSQL_TIME *ltime, int *was_cut);
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
diff --git a/include/mysql_com.h b/include/mysql_com.h
index be1d222eb07..9486bd3ebb7 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -111,7 +111,7 @@ enum enum_server_command
#define MYSQL_TYPE_VIRTUAL 245
/*
Length of random string sent by server on handshake; this is also length of
- obfuscated password, recieved from client
+ obfuscated password, received from client
*/
#define SCRAMBLE_LENGTH 20
#define SCRAMBLE_LENGTH_323 8
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 9ed89c5e081..6897031b1f9 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -138,6 +138,7 @@ my_print_help
)
SET(CLIENT_API_FUNCTIONS_5_5
+my_progname
mysql_stmt_next_result
# Charsets
my_charset_bin
diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c
index 9985fa2233c..84884f9565a 100644
--- a/libmysql/errmsg.c
+++ b/libmysql/errmsg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -81,7 +81,7 @@ const char *client_errors[]=
"Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %M",
- "Statement closed indirectly because of a preceeding %s() call",
+ "Statement closed indirectly because of a preceding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
"This handle is already connected. Use a separate handle for each connection.",
"Authentication plugin '%s' cannot be loaded: %s",
@@ -107,6 +107,8 @@ const char** get_client_errmsgs()
void init_client_errs(void)
{
+ compile_time_assert(array_elements(client_errors) ==
+ (CR_ERROR_LAST - CR_ERROR_FIRST + 2));
(void) my_error_register(get_client_errmsgs, CR_ERROR_FIRST, CR_ERROR_LAST);
}
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 3d8a2bebc75..554c3fc0ab6 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates
- Copyright (c) 2009, 2013, Monty Program Ab
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
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
@@ -1340,6 +1340,10 @@ static my_bool my_realloc_str(NET *net, ulong length)
res= net_realloc(net, buf_length + length);
if (res)
{
+ if (net->last_errno == ER_OUT_OF_RESOURCES)
+ net->last_errno= CR_OUT_OF_MEMORY;
+ else if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
+ net->last_errno= CR_NET_PACKET_TOO_LARGE;
strmov(net->sqlstate, unknown_sqlstate);
strmov(net->last_error, ER(net->last_errno));
}
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index d0c3fafdf69..0920be53baf 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -104,6 +104,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/sql_explain.cc ../sql/sql_explain.h
../sql/compat56.cc
../sql/table_cache.cc
+ ../sql/item_inetfunc.cc
${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE}
)
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index 38048263b34..f2842959c3f 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -16,13 +16,13 @@
SET(MAN1_SERVER innochecksum.1 my_print_defaults.1 myisam_ftdump.1 myisamchk.1
myisamlog.1 myisampack.1 mysql.server.1
mysql_convert_table_format.1 mysql_fix_extensions.1
- mysql_fix_privilege_tables.1 mysql_install_db.1
+ mysql_install_db.1
mysql_secure_installation.1 mysql_setpermission.1
mysql_tzinfo_to_sql.1 mysql_upgrade.1 mysql_zap.1
mysqld_multi.1 mysqld_safe.1 mysqldumpslow.1 mysqlhotcopy.1
- mysqlman.1 mysqltest.1 perror.1 replace.1 resolve_stack_dump.1
+ mysqltest.1 perror.1 replace.1 resolve_stack_dump.1
resolveip.1 mysqlbug.1)
-SET(MAN8_SERVER mysqld.8 mysqlmanager.8)
+SET(MAN8_SERVER mysqld.8)
SET(MAN1_CLIENT msql2mysql.1 mysql.1 mysql_find_rows.1 mysql_waitpid.1
mysqlaccess.1 mysqladmin.1 mysqlbinlog.1 mysqlcheck.1
mysqldump.1 mysqlimport.1 mysqlshow.1 mysqlslap.1
diff --git a/man/aria_chk.1 b/man/aria_chk.1
new file mode 100644
index 00000000000..4dc5bf8c78f
--- /dev/null
+++ b/man/aria_chk.1
@@ -0,0 +1,245 @@
+.TH ARIA_CHK "1" "May 2014" "aria_chk Ver 1.2" "User Commands"
+.SH NAME
+aria_chk \- Aria table\-maintenance utility
+.SH SYNOPSIS
+.B aria_chk
+[\fIOPTIONS\fR] \fItables\fR[\fI.MAI\fR]
+.SH DESCRIPTION
+Describe, check and repair of Aria tables.
+Used without options all tables on the command will be checked for errors
+.SS "Global options"
+.TP
+\fB\-#\fR, \fB\-\-debug=\fR...
+Output debug log. Often this is 'd:t:o,filename'.
+.TP
+\fB\-H\fR, \fB\-\-HELP\fR
+Print all argument options sorted alphabetically.
+.TP
+\fB\-?\fR, \fB\-\-help\fR
+Print all options by groups
+.TP
+\fB\-\-datadir\fR=\fIpath\fR
+Path for control file (and logs if \fB\-\-logdir\fR not used)
+.TP
+\fB\-\-logdir\fR=\fIpath\fR
+Path for log files
+.TP
+\fB\-\-ignore\-control\-file\fR
+Don't open the control file. Only use this if you
+are sure the tables are not in use by another
+program!
+.TP
+\fB\-\-require\-control\-file\fR
+Abort if we can't find/read the maria_log_control
+file
+.TP
+\fB\-s\fR, \fB\-\-silent\fR
+Only print errors. One can use two \fB\-s\fR to make
+maria_chk very silent.
+.TP
+\fB\-t\fR, \fB\-\-tmpdir\fR=\fIpath\fR
+Path for temporary files. Multiple paths can be
+specified, separated by colon (:), they will be used
+in a round\-robin fashion.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Print more information. This can be used with
+\fB\-\-description\fR and \fB\-\-check\fR. Use many \fB\-v\fR for more verbosity.
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Print version and exit.
+.TP
+\fB\-w\fR, \fB\-\-wait\fR
+Wait if table is locked.
+.SS "Check options (check is the default action for aria_chk)"
+.TP
+\fB\-c\fR, \fB\-\-check\fR
+Check table for errors.
+.TP
+\fB\-e\fR, \fB\-\-extend\-check\fR
+Check the table VERY throughly. Only use this in
+extreme cases as aria_chk should normally be able to
+find out if the table is ok even without this switch.
+.TP
+\fB\-F\fR, \fB\-\-fast\fR
+Check only tables that haven't been closed properly.
+.TP
+\fB\-C\fR, \fB\-\-check\-only\-changed\fR
+Check only tables that have changed since last check.
+.TP
+\fB\-f\fR, \fB\-\-force\fR
+Restart with '\-r' if there are any errors in the table.
+States will be updated as with '\-\-update\-state'.
+.TP
+\fB\-i\fR, \fB\-\-information\fR
+Print statistics information about table that is checked.
+.TP
+\fB\-m\fR, \fB\-\-medium\-check\fR
+Faster than extend\-check, but only finds 99.99% of
+all errors. Should be good enough for most cases.
+.TP
+\fB\-T\fR, \fB\-\-read\-only\fR
+Don't mark table as checked.
+.TP
+\fB\-U\fR, \fB\-\-update\-state\fR
+Mark tables as crashed if any errors were found and
+clean if check didn't find any errors but table was
+marked as 'not clean' before. This allows one to get
+rid of warnings like 'table not properly closed'. If
+table was updated, update also the timestamp for when
+the check was made. This option is on by default!
+Use \fB\-\-skip\-update\-state\fR to disable.
+.HP
+\fB\-\-warning\-for\-wrong\-transaction\-id\fR
+.IP
+Give a warning if we find a transaction id in the table that is bigger
+than what exists in the control file. Use \fB\-\-skip\-\fR... to disable warning
+.SS "Recover (repair)/ options (When using '--recover' or '--safe-recover')"
+.TP
+\fB\-B\fR, \fB\-\-backup\fR
+Make a backup of the .MAD file as 'filename\-time.BAK'.
+.TP
+\fB\-\-correct\-checksum\fR
+Correct checksum information for table.
+.TP
+\fB\-D\fR, \fB\-\-data\-file\-length=\fR#
+Max length of data file (when recreating data
+file when it's full).
+.TP
+\fB\-e\fR, \fB\-\-extend\-check\fR
+Try to recover every possible row from the data file
+Normally this will also find a lot of garbage rows;
+Don't use this option if you are not totally desperate.
+.TP
+\fB\-f\fR, \fB\-\-force\fR
+Overwrite old temporary files.
+.TP
+\fB\-k\fR, \fB\-\-keys\-used=\fR#
+Tell Aria to update only some specific keys. # is a
+bit mask of which keys to use. This can be used to
+get faster inserts.
+.TP
+\fB\-\-max\-record\-length=\fR#
+Skip rows bigger than this if aria_chk can't allocate
+memory to hold it.
+.TP
+\fB\-r\fR, \fB\-\-recover\fR
+Can fix almost anything except unique keys that aren't
+unique.
+.TP
+\fB\-n\fR, \fB\-\-sort\-recover\fR
+Forces recovering with sorting even if the temporary
+file would be very big.
+.TP
+\fB\-p\fR, \fB\-\-parallel\-recover\fR
+Uses the same technique as '\-r' and '\-n', but creates
+all the keys in parallel, in different threads.
+.TP
+\fB\-o\fR, \fB\-\-safe\-recover\fR
+Uses old recovery method; Slower than '\-r' but can
+handle a couple of cases where '\-r' reports that it
+can't fix the data file.
+.TP
+\fB\-\-transaction\-log\fR
+Log repair command to transaction log. This is needed
+if one wants to use the aria_read_log to repeat the
+repair
+.TP
+\fB\-\-character\-sets\-dir=\fR...
+Directory where character sets are.
+.TP
+\fB\-\-set\-collation\fR=\fIname\fR
+Change the collation used by the index.
+.TP
+\fB\-q\fR, \fB\-\-quick\fR
+Faster repair by not modifying the data file.
+One can give a second '\-q' to force aria_chk to
+modify the original datafile in case of duplicate keys.
+NOTE: Tables where the data file is currupted can't be
+fixed with this option.
+.TP
+\fB\-u\fR, \fB\-\-unpack\fR
+Unpack file packed with ariapack.
+.SS "Other actions"
+.TP
+\fB\-a\fR, \fB\-\-analyze\fR
+Analyze distribution of keys. Will make some joins in
+MariaDB faster. You can check the calculated distribution
+by using '\-\-description \fB\-\-verbose\fR table_name'.
+.TP
+\fB\-\-stats_method\fR=\fIname\fR
+Specifies how index statistics collection code should
+treat NULLs. Possible values of name are "nulls_unequal"
+(default for 4.1/5.0), "nulls_equal" (emulate 4.0), and
+"nulls_ignored".
+.TP
+\fB\-d\fR, \fB\-\-description\fR
+Prints some information about table.
+.TP
+\fB\-A\fR, \fB\-\-set\-auto\-increment\fR[=\fIvalue\fR]
+Force auto_increment to start at this or higher value
+If no value is given, then sets the next auto_increment
+value to the highest used value for the auto key + 1.
+.TP
+\fB\-S\fR, \fB\-\-sort\-index\fR
+Sort index blocks. This speeds up 'read\-next' in
+applications.
+.TP
+\fB\-R\fR, \fB\-\-sort\-records=\fR#
+Sort records according to an index. This makes your
+data much more localized and may speed up things
+(It may be VERY slow to do a sort the first time!).
+.TP
+\fB\-b\fR, \fB\-\-block\-search=\fR#
+Find a record, a block at given offset belongs to.
+.TP
+\fB\-z\fR, \fB\-\-zerofill\fR
+Fill empty space in data and index files with zeroes.
+This makes the data file movable between different
+servers.
+.TP
+\fB\-\-zerofill\-keep\-lsn\fR
+Like \fB\-\-zerofill\fR but does not zero out LSN of
+data/index pages.
+.PP
+.SS "Variables"
+.TP
+\fB\-\-page_buffer_size=\fR#
+Size of page buffer. Used by \fB\-\-safe\-repair\fR
+.TP
+\fB\-\-read_buffer_size=\fR#
+Read buffer size for sequential reads during scanning
+.TP
+\fB\-\-sort_buffer_size=\fR#
+Size of sort buffer. Used by \fB\-\-recover\fR
+.TP
+\fB\-\-sort_key_blocks=\fR#
+Internal buffer for sorting keys; Don't touch.
+.TP
+\fB\-\-write_buffer_size=\fR#
+Write buffer size for sequential writes during repair
+.PP
+Default options are read from the following files in the given order:
+\fB/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf\fR
+.PP
+The following groups are read: \fBaria_chk\fR
+.PP
+The following options may be given as the first argument:
+.TP
+\fB\-\-print\-defaults\fR
+Print the program argument list and exit.
+.TP
+\fB\-\-no\-defaults\fR
+Don't read default options from any option file.
+.TP
+\fB\-\-defaults\-file=\fR#
+Only read default options from the given file #.
+.TP
+\fB\-\-defaults\-extra\-file=\fR#
+Read this file after the global files are read.
+.PP
+.SH "SEE ALSO"
+\fBmyisamchk(1)\fR
+.PP
+For more information, please refer to the MariaDB Knowledge Base,
+which is available online at http://mariadb.com/kb/
diff --git a/man/aria_dump_log.1 b/man/aria_dump_log.1
new file mode 100644
index 00000000000..41318d97f7a
--- /dev/null
+++ b/man/aria_dump_log.1
@@ -0,0 +1,54 @@
+.TH ARIA_DUMP_LOG "1" "May 2014" "aria_dump_log Ver 1.0" "User Commands"
+.SH NAME
+aria_dump_log \- Dump content of Aria log pages.
+.SH SYNOPSIS
+.B aria_dump_log
+\fI-f file OPTIONS\fR
+.SH DESCRIPTION
+Dump content of Aria log pages.
+.TP
+\fB\-#\fR, \fB\-\-debug\fR[=\fIname\fR]
+Output debug log. Often the argument is 'd:t:o,filename'.
+.TP
+\fB\-f\fR, \fB\-\-file\fR=\fIname\fR
+Path to file which will be read
+.TP
+\fB\-?\fR, \fB\-\-help\fR
+Display this help and exit.
+.TP
+\fB\-o\fR, \fB\-\-offset=\fR#
+Start reading log from this offset
+.TP
+\fB\-n\fR, \fB\-\-pages=\fR#
+Number of pages to read
+.TP
+\fB\-U\fR, \fB\-\-unit\-test\fR
+Use unit test record table (for logs created by unittests
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Print version and exit.
+.PP
+Default options are read from the following files in the given order:
+\fB/etc/my.cnf\fB
+\fB/etc/mysql/my.cnf\fB
+\fB~/.my.cnf\fB
+.PP
+The following groups are read: \fBaria_dump_log\fR
+.PP
+The following options may be given as the first argument:
+.TP
+\fB\-\-print\-defaults\fR
+Print the program argument list and exit.
+.TP
+\fB\-\-no\-defaults\fR
+Don't read default options from any option file.
+.TP
+\fB\-\-defaults\-file=\fR#
+Only read default options from the given file #.
+.TP
+\fB\-\-defaults\-extra\-file=\fR#
+Read this file after the global files are read.
+.PP
+.SH "SEE ALSO"
+For more information, please refer to the MariaDB Knowledge Base,
+which is available online at http://mariadb.com/kb/
diff --git a/man/aria_ftdump.1 b/man/aria_ftdump.1
new file mode 100644
index 00000000000..4d6c1373e31
--- /dev/null
+++ b/man/aria_ftdump.1
@@ -0,0 +1,29 @@
+.TH ARIA_FTDUMP "1" "May 2014" "aria_ftdump Ver 1.0" "User Commands"
+.SH NAME
+aria_ftdump \- display full\-text index information
+.SH DESCRIPTION
+Use: aria_ft_dump <table_name> <index_num>
+.TP
+\fB\-?\fR, \fB\-h\fR, \fB\-\-help\fR
+Display help and exit.
+.TP
+\fB\-c\fR, \fB\-\-count\fR
+Calculate per\-word stats (counts and global weights).
+.TP
+\fB\-d\fR, \fB\-\-dump\fR
+Dump index (incl. data offsets and word weights).
+.TP
+\fB\-l\fR, \fB\-\-length\fR
+Report length distribution.
+.TP
+\fB\-s\fR, \fB\-\-stats\fR
+Report global stats.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Be verbose.
+.PP
+.SH "SEE ALSO"
+\fBmyisam_ftdump(1)\fR
+.PP
+For more information, please refer to the MariaDB Knowledge Base,
+which is available online at http://mariadb.com/kb/
diff --git a/man/aria_pack.1 b/man/aria_pack.1
new file mode 100644
index 00000000000..9cec33a3818
--- /dev/null
+++ b/man/aria_pack.1
@@ -0,0 +1,76 @@
+.TH ARIA_PACK "1" "May 2014" "aria_pack Ver 1.0" "User Commands"
+.SH NAME
+aria_pack \- manual page for aria_pack Ver 1.0
+.SH SYNOPSIS
+.B aria_pack
+[\fIOPTIONS\fR] \fIfilename\fR...
+.SH DESCRIPTION
+Pack a Aria\-table to take much less space.
+Keys are not updated, you must run \fBaria_chk \-rq\fR on the index (.MAI) file
+afterwards to update the keys.
+You should give the .MAI file as the filename argument.
+To unpack a packed table, run \fBaria_chk \-u\fR on the table
+.TP
+\fB\-b\fR, \fB\-\-backup\fR
+Make a backup of the table as table_name.OLD.
+.TP
+\fB\-\-character\-sets\-dir\fR=\fIname\fR
+Directory where character sets are.
+.TP
+\fB\-#\fR, \fB\-\-debug\fR[=\fIname\fR]
+Output debug log. Often this is 'd:t:o,filename'.
+.TP
+\fB\-f\fR, \fB\-\-force\fR
+Force packing of table even if it gets bigger or if
+tempfile exists.
+.TP
+\fB\-j\fR, \fB\-\-join\fR=\fIname\fR
+Join all given tables into 'new_table_name'. All tables
+MUST have identical layouts.
+.TP
+\fB\-?\fR, \fB\-\-help\fR
+Display this help and exit.
+.TP
+\fB\-s\fR, \fB\-\-silent\fR
+Be more silent.
+.TP
+\fB\-T\fR, \fB\-\-tmpdir\fR=\fIname\fR
+Use temporary directory to store temporary table.
+.TP
+\fB\-t\fR, \fB\-\-test\fR
+Don't pack table, only test packing it.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Write info about progress and packing result. Use many \fB\-v\fR
+for more verbosity!
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Output version information and exit.
+.TP
+\fB\-w\fR, \fB\-\-wait\fR
+Wait and retry if table is in use.
+.PP
+Default options are read from the following files in the given order:
+\fB/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf\fR
+.PP
+The following groups are read: \fBariapack\fR
+.PP
+The following options may be given as the first argument:
+.TP
+\fB\-\-print\-defaults\fR
+Print the program argument list and exit.
+.TP
+\fB\-\-no\-defaults\fR
+Don't read default options from any option file.
+.TP
+\fB\-\-defaults\-file=\fR#
+Only read default options from the given file #.
+.TP
+\fB\-\-defaults\-extra\-file=\fR#
+Read this file after the global files are read.
+.PP
+.SH "SEE ALSO"
+\fBmyisampack(1)\fR
+.PP
+For more information, please refer to the MariaDB Knowledge Base,
+which is available online at http://mariadb.com/kb/
diff --git a/man/aria_read_log.1 b/man/aria_read_log.1
new file mode 100644
index 00000000000..701104fe047
--- /dev/null
+++ b/man/aria_read_log.1
@@ -0,0 +1,108 @@
+.TH ARIA_READ_LOG "1" "May 2014" "aria_read_log Ver 1.3" "User Commands"
+.SH NAME
+aria_read_log \- display Aria log file contents
+.SH SYNOPSIS
+.B aria_read_log
+\fIOPTIONS\fR
+.SH DESCRIPTION
+Display and apply log records from a Aria transaction log
+found in the current directory (for now)
+.PP
+Note: Aria is compiled without \fB\-DIDENTICAL_PAGES_AFTER_RECOVERY\fR
+which means that the table files are not byte\-to\-byte identical to
+files created during normal execution. This should be ok, except for
+test scripts that tries to compare files before and after recovery.
+.PP
+You need to use one of \fB\-d\fR or \fB\-a\fR
+.TP
+\fB\-a\fR, \fB\-\-apply\fR
+Apply log to tables: modifies tables! you should make a
+backup first! Displays a lot of information if not run
+with \fB\-\-silent\fR
+.TP
+\fB\-\-character\-sets\-dir\fR=\fIname\fR
+Directory where character sets are.
+.TP
+\fB\-c\fR, \fB\-\-check\fR
+if \fB\-\-display\-only\fR, check if record is fully readable (for
+debugging)
+.TP
+\fB\-#\fR, \fB\-\-debug\fR[=\fIname\fR]
+Output debug log. Often the argument is 'd:t:o,filename'.
+.TP
+\fB\-\-force\-crash=\fR#
+Force crash after # recovery events
+.TP
+\fB\-?\fR, \fB\-\-help\fR
+Display this help and exit.
+.TP
+\fB\-d\fR, \fB\-\-display\-only\fR
+display brief info read from records' header
+.TP
+\fB\-e\fR, \fB\-\-end\-lsn=\fR#
+Stop applying at this lsn. If end\-lsn is used, UNDO:s
+will not be applied
+.TP
+\fB\-h\fR, \fB\-\-aria\-log\-dir\-path\fR=\fIname\fR
+Path to the directory where to store transactional log
+.TP
+\fB\-P\fR, \fB\-\-page\-buffer\-size=\fR#
+The size of the buffer used for index blocks for Aria
+tables
+.TP
+\fB\-o\fR, \fB\-\-start\-from\-lsn=\fR#
+Start reading log from this lsn
+.TP
+\fB\-C\fR, \fB\-\-start\-from\-checkpoint\fR
+Start applying from last checkpoint
+.TP
+\fB\-s\fR, \fB\-\-silent\fR
+Print less information during apply/undo phase
+.TP
+\fB\-T\fR, \fB\-\-tables\-to\-redo\fR=\fIname\fR
+List of tables sepearated with , that we should apply
+REDO on. Use this if you only want to recover some tables
+.TP
+\fB\-t\fR, \fB\-\-tmpdir\fR=\fIname\fR
+Path for temporary files. Multiple paths can be
+specified, separated by colon (:)
+.TP
+\fB\-\-translog\-buffer\-size=\fR#
+The size of the buffer used for transaction log for Aria
+tables
+.TP
+\fB\-u\fR, \fB\-\-undo\fR
+Apply UNDO records to tables. (disable with
+\fB\-\-disable\-undo\fR)
+(Defaults to on; use \fB\-\-skip\-undo\fR to disable.)
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Print more information during apply/undo phase
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Print version and exit.
+.PP
+Default options are read from the following files in the given order:
+\fB/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf\fR
+.PP
+The following groups are read: \fBaria_read_log\fR
+.PP
+The following options may be given as the first argument:
+.TP
+\fB\-\-print\-defaults\fR
+Print the program argument list and exit.
+.TP
+\fB\-\-no\-defaults\fR
+Don't read default options from any option file.
+.TP
+\fB\-\-defaults\-file=\fR#
+Only read default options from the given file #.
+.TP
+\fB\-\-defaults\-extra\-file=\fR#
+Read this file after the global files are read.
+.PP
+.SH "SEE ALSO"
+\fBmyisamlog(1)\fR
+.PP
+For more information, please refer to the MariaDB Knowledge Base,
+which is available online at http://mariadb.com/kb/
diff --git a/man/mysql-test-run.pl.1 b/man/mysql-test-run.pl.1
index ebf17746b68..20abc250b15 100644
--- a/man/mysql-test-run.pl.1
+++ b/man/mysql-test-run.pl.1
@@ -332,7 +332,7 @@ is defined so that
can invoke itself with
exec $MYSQL_TEST\&.
.PP
-Other tests may refer to the last three variables listed in the preceeding table, to locate files to read or write\&. For example, tests that need to create files will typically put them in
+Other tests may refer to the last three variables listed in the preceding table, to locate files to read or write\&. For example, tests that need to create files will typically put them in
$MYSQL_TMP_DIR/\fIfile_name\fR\&.
.PP
If you are running
diff --git a/man/mysql_fix_privilege_tables.1 b/man/mysql_fix_privilege_tables.1
deleted file mode 100644
index 99b126047fb..00000000000
--- a/man/mysql_fix_privilege_tables.1
+++ /dev/null
@@ -1,175 +0,0 @@
-'\" t
-.\" Title: \fBmysql_fix_privilege_tables\fR
-.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 04/06/2010
-.\" Manual: MySQL Database System
-.\" Source: MySQL 5.1
-.\" Language: English
-.\"
-.TH "\FBMYSQL_FIX_PRIVILE" "1" "04/06/2010" "MySQL 5\&.1" "MySQL Database System"
-.\" -----------------------------------------------------------------
-.\" * set default formatting
-.\" -----------------------------------------------------------------
-.\" disable hyphenation
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.\" mysql_fix_privilege_tables
-.\" upgrading: grant tables
-.\" grant tables: upgrading
-.SH "NAME"
-mysql_fix_privilege_tables \- upgrade MySQL system tables
-.SH "SYNOPSIS"
-.HP \w'\fBmysql_fix_privilege_tables\ \-\-password=\fR\fB\fIroot_password\fR\fR\ 'u
-\fBmysql_fix_privilege_tables \-\-password=\fR\fB\fIroot_password\fR\fR
-.SH "DESCRIPTION"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBNote\fR
-.ps -1
-.br
-.PP
-In MySQL 5\&.1\&.7,
-\fBmysql_fix_privilege_tables\fR
-was superseded by
-\fBmysql_upgrade\fR, which should be used instead\&. See
-\fBmysql_upgrade\fR(1)\&.
-.sp .5v
-.RE
-.PP
-Some releases of MySQL introduce changes to the structure of the system tables in the
-mysql
-database to add new privileges or support new features\&. When you update to a new version of MySQL, you should update your system tables as well to make sure that their structure is up to date\&. Otherwise, there might be capabilities that you cannot take advantage of\&.
-.PP
-\fBmysql_fix_privilege_tables\fR
-is an older script that previously was used to uprade the system tables in the
-mysql
-database after a MySQL upgrade\&.
-.PP
-Before running
-\fBmysql_fix_privilege_tables\fR, make a backup of your
-mysql
-database\&.
-.PP
-On Unix or Unix\-like systems, update the system tables by running the
-\fBmysql_fix_privilege_tables\fR
-script:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysql_fix_privilege_tables\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-You must run this script while the server is running\&. It attempts to connect to the server running on the local host as
-root\&. If your
-root
-account requires a password, indicate the password on the command line like this:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysql_fix_privilege_tables \-\-password=\fR\fB\fIroot_password\fR\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-The
-\fBmysql_fix_privilege_tables\fR
-script performs any actions necessary to convert your system tables to the current format\&. You might see some
-Duplicate column name
-warnings as it runs; you can ignore them\&.
-.PP
-After running the script, stop the server and restart it so that any changes made to the system tables take effect\&.
-.PP
-On Windows systems, MySQL distributions include a
-mysql_fix_privilege_tables\&.sql
-SQL script that you can run using the
-\fBmysql\fR
-client\&. For example, if your MySQL installation is located at
-C:\eProgram Files\eMySQL\eMySQL Server 5\&.1, the commands look like this:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-C:\e> \fBcd "C:\eProgram Files\eMySQL\eMySQL Server 5\&.1"\fR
-C:\e> \fBbin\emysql \-u root \-p mysql\fR
-mysql> \fBSOURCE share/mysql_fix_privilege_tables\&.sql\fR
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBNote\fR
-.ps -1
-.br
-.PP
-Prior to version 5\&.1\&.17, the
-mysql_fix_privilege_tables\&.sql
-script is found in the
-scripts
-directory\&.
-.sp .5v
-.RE
-.PP
-The
-\fBmysql\fR
-command will prompt you for the
-root
-password; enter it when prompted\&.
-.PP
-If your installation is located in some other directory, adjust the path names appropriately\&.
-.PP
-As with the Unix procedure, you might see some
-Duplicate column name
-warnings as
-\fBmysql\fR
-processes the statements in the
-mysql_fix_privilege_tables\&.sql
-script; you can ignore them\&.
-.PP
-After running the script, stop the server and restart it\&.
-.SH "COPYRIGHT"
-.br
-.PP
-Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.
-.PP
-This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
-.PP
-This documentation is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-.PP
-You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see http://www.gnu.org/licenses/.
-.sp
-.SH "SEE ALSO"
-For more information, please refer to the MySQL Reference Manual,
-which may already be installed locally and which is also available
-online at http://dev.mysql.com/doc/.
-.SH AUTHOR
-Sun Microsystems, Inc. (http://www.mysql.com/).
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
index 738ecef418d..25b561ffdce 100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -24,8 +24,8 @@
.SH "NAME"
mysqladmin \- client for administering a MySQL server
.SH "SYNOPSIS"
-.HP \w'\fBmysqladmin\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIcommand\fR\fR\fB\ [\fR\fB\fIcommand\-options\fR\fR\fB]\ [\fR\fB\fIcommand\fR\fR\fB\ [\fR\fB\fIcommand\-options\fR\fR\fB]]\ \&.\&.\&.\fR\ 'u
-\fBmysqladmin [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIcommand\fR\fR\fB [\fR\fB\fIcommand\-options\fR\fR\fB] [\fR\fB\fIcommand\fR\fR\fB [\fR\fB\fIcommand\-options\fR\fR\fB]] \&.\&.\&.\fR
+.HP \w'\fBmysqladmin\ [\fR\fB\fIoptions\fR\fR\fB]\ \fR\fB\fIcommand\fR\fR\fB\ [\fR\fB\fIcommand\-arg\fR\fR\fB]\ [\fR\fB\fIcommand\fR\fR\fB\ [\fR\fB\fIcommand\-arg\fR\fR\fB]]\ \&.\&.\&.\fR\ 'u
+\fBmysqladmin [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIcommand\fR\fR\fB [\fR\fB\fIcommand\-arg\fR\fR\fB] [\fR\fB\fIcommand\fR\fR\fB [\fR\fB\fIcommand\-arg\fR\fR\fB]] \&.\&.\&.\fR
.SH "DESCRIPTION"
.PP
\fBmysqladmin\fR
diff --git a/man/mysqlbinlog.1 b/man/mysqlbinlog.1
index 20f80fd8f6e..cc0f62485b5 100644
--- a/man/mysqlbinlog.1
+++ b/man/mysqlbinlog.1
@@ -1255,33 +1255,6 @@ indicates a
FORMAT_DESCRIPTION_EVENT\&. The following table lists the possible type codes\&.
.TS
allbox tab(:);
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
-l l l
l l l.
T{
Type
@@ -1310,7 +1283,7 @@ T}:T{
QUERY_EVENT
T}:T{
The most common type of events\&. These contain statements executed on the
- master\&.
+master\&.
T}
T{
03
@@ -1332,8 +1305,8 @@ T}:T{
INTVAR_EVENT
T}:T{
Used for AUTO_INCREMENT values or when the
- LAST_INSERT_ID()
- function is used in the statement\&.
+LAST_INSERT_ID()
+function is used in the statement\&.
T}
T{
06
@@ -1341,7 +1314,7 @@ T}:T{
LOAD_EVENT
T}:T{
Used for LOAD DATA
- INFILE in MySQL 3\&.23\&.
+INFILE in MySQL 3\&.23\&.
T}
T{
07
@@ -1356,9 +1329,9 @@ T}:T{
CREATE_FILE_EVENT
T}:T{
Used for LOAD DATA
- INFILE statements\&. This indicates the
- start of execution of such a statement\&. A temporary
- file is created on the slave\&. Used in MySQL 4 only\&.
+INFILE statements\&. This indicates the
+start of execution of such a statement\&. A temporary
+file is created on the slave\&. Used in MySQL 4 only\&.
T}
T{
09
@@ -1366,9 +1339,9 @@ T}:T{
APPEND_BLOCK_EVENT
T}:T{
Contains data for use in a
- LOAD DATA
- INFILE statement\&. The data is stored in
- the temporary file on the slave\&.
+LOAD DATA
+INFILE statement\&. The data is stored in
+the temporary file on the slave\&.
T}
T{
0a
@@ -1376,9 +1349,9 @@ T}:T{
EXEC_LOAD_EVENT
T}:T{
Used for LOAD DATA
- INFILE statements\&. The contents of the
- temporary file is stored in the table on the slave\&.
- Used in MySQL 4 only\&.
+INFILE statements\&. The contents of the
+temporary file is stored in the table on the slave\&.
+Used in MySQL 4 only\&.
T}
T{
0b
@@ -1386,8 +1359,8 @@ T}:T{
DELETE_FILE_EVENT
T}:T{
Rollback of a LOAD DATA
- INFILE statement\&. The temporary file
- should be deleted on the slave\&.
+INFILE statement\&. The temporary file
+should be deleted on the slave\&.
T}
T{
0c
@@ -1395,7 +1368,7 @@ T}:T{
NEW_LOAD_EVENT
T}:T{
Used for LOAD DATA
- INFILE in MySQL 4 and earlier\&.
+INFILE in MySQL 4 and earlier\&.
T}
T{
0d
@@ -1403,8 +1376,8 @@ T}:T{
RAND_EVENT
T}:T{
Used to send information about random values if the
- RAND() function is
- used in the statement\&.
+RAND() function is
+used in the statement\&.
T}
T{
0e
@@ -1433,7 +1406,7 @@ T}:T{
BEGIN_LOAD_QUERY_EVENT
T}:T{
Used for LOAD DATA
- INFILE statements in MySQL 5 and later\&.
+INFILE statements in MySQL 5 and later\&.
T}
T{
12
@@ -1441,7 +1414,7 @@ T}:T{
EXECUTE_LOAD_QUERY_EVENT
T}:T{
Used for LOAD DATA
- INFILE statements in MySQL 5 and later\&.
+INFILE statements in MySQL 5 and later\&.
T}
T{
13
@@ -1456,7 +1429,7 @@ T}:T{
PRE_GA_WRITE_ROWS_EVENT
T}:T{
Row data for a single table that should be created\&. Used in MySQL 5\&.1\&.5
- to 5\&.1\&.17\&.
+to 5\&.1\&.17\&.
T}
T{
15
@@ -1464,7 +1437,7 @@ T}:T{
PRE_GA_UPDATE_ROWS_EVENT
T}:T{
Row data for a single table that needs to be updated\&. Used in MySQL
- 5\&.1\&.5 to 5\&.1\&.17\&.
+5\&.1\&.5 to 5\&.1\&.17\&.
T}
T{
16
@@ -1472,7 +1445,7 @@ T}:T{
PRE_GA_DELETE_ROWS_EVENT
T}:T{
Row data for a single table that should be deleted\&. Used in MySQL 5\&.1\&.5
- to 5\&.1\&.17\&.
+to 5\&.1\&.17\&.
T}
T{
17
@@ -1480,7 +1453,7 @@ T}:T{
WRITE_ROWS_EVENT
T}:T{
Row data for a single table that should be created\&. Used in MySQL 5\&.1\&.18
- and later\&.
+and later\&.
T}
T{
18
@@ -1488,7 +1461,7 @@ T}:T{
UPDATE_ROWS_EVENT
T}:T{
Row data for a single table that needs to be updated\&. Used in MySQL
- 5\&.1\&.18 and later\&.
+5\&.1\&.18 and later\&.
T}
T{
19
@@ -1496,7 +1469,7 @@ T}:T{
DELETE_ROWS_EVENT
T}:T{
Row data for a single table that should be deleted\&. Used in MySQL 5\&.1\&.18
- and later\&.
+and later\&.
T}
T{
1a
@@ -1553,10 +1526,6 @@ Master Pos: The position of the next event in the original master log file\&.
Flags: 16 flags\&. Currently, the following flags are used\&. The others are reserved for future use\&.
.TS
allbox tab(:);
-l l l
-l l l
-l l l
-l l l
l l l.
T{
Flag
@@ -1571,13 +1540,13 @@ T}:T{
LOG_EVENT_BINLOG_IN_USE_F
T}:T{
Log file correctly closed\&. (Used only in
- FORMAT_DESCRIPTION_EVENT\&.) If
- this flag is set (if the flags are, for example,
- \'01 00\') in a
- FORMAT_DESCRIPTION_EVENT, the log
- file has not been properly closed\&. Most probably
- this is because of a master crash (for example, due
- to power failure)\&.
+FORMAT_DESCRIPTION_EVENT\&.) If
+this flag is set (if the flags are, for example,
+\'01 00\') in a
+FORMAT_DESCRIPTION_EVENT, the log
+file has not been properly closed\&. Most probably
+this is because of a master crash (for example, due
+to power failure)\&.
T}
T{
02
@@ -1592,8 +1561,8 @@ T}:T{
LOG_EVENT_THREAD_SPECIFIC_F
T}:T{
Set if the event is dependent on the connection it was executed in (for
- example, \'04 00\'), for example,
- if the event uses temporary tables\&.
+example, \'04 00\'), for example,
+if the event uses temporary tables\&.
T}
T{
08
@@ -1601,7 +1570,7 @@ T}:T{
LOG_EVENT_SUPPRESS_USE_F
T}:T{
Set in some circumstances when the event is not dependent on the default
- database\&.
+database\&.
T}
.TE
.sp 1
diff --git a/man/mysqldump.1 b/man/mysqldump.1
index f27e1552313..59d2416b25e 100644
--- a/man/mysqldump.1
+++ b/man/mysqldump.1
@@ -2027,9 +2027,6 @@ value, an empty string, and the string value
are distinguished from one another in the output generated by this option as follows\&.
.TS
allbox tab(:);
-l l
-l l
-l l
l l.
T{
\fBValue\fR:
diff --git a/man/mysqlman.1 b/man/mysqlman.1
deleted file mode 100644
index 2170942ebd9..00000000000
--- a/man/mysqlman.1
+++ /dev/null
@@ -1,15 +0,0 @@
-.TH mysqlman 1 "20 July 2004" "MySQL" "MySQL database"
-.SH NAME
-mysqlman \- default man page for mysql
-.SH "DESCRIPTION"
-Certain executables distributed with the MySQL database management system do
-not have specific man pages.
-.SH "SEE ALSO"
-In most cases, you can run the executable from the command line with a "--help"
-argument to display a brief summary of the executable's arguments and function.
-For more information about MySQL, please refer to the MySQL reference manual,
-which may already be installed locally and which is also available online at
-http://dev.mysql.com/doc/mysql/en
-.SH BUGS
-Please refer to http://bugs.mysql.com/ to report bugs.
-.\" end of man page
diff --git a/man/mysqlmanager.8 b/man/mysqlmanager.8
deleted file mode 100644
index 8d3e6efd85e..00000000000
--- a/man/mysqlmanager.8
+++ /dev/null
@@ -1,2078 +0,0 @@
-'\" t
-.\" Title: \fBmysqlmanager\fR
-.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 04/06/2010
-.\" Manual: MySQL Database System
-.\" Source: MySQL 5.1
-.\" Language: English
-.\"
-.TH "\FBMYSQLMANAGER\FR" "8" "04/06/2010" "MySQL 5\&.1" "MySQL Database System"
-.\" -----------------------------------------------------------------
-.\" * set default formatting
-.\" -----------------------------------------------------------------
-.\" disable hyphenation
-.nh
-.\" disable justification (adjust text to left margin only)
-.ad l
-.\" -----------------------------------------------------------------
-.\" * MAIN CONTENT STARTS HERE *
-.\" -----------------------------------------------------------------
-.\" mysqlmanager
-.\" MySQL Instance Manager
-.SH "NAME"
-mysqlmanager \- the MySQL Instance Manager
-.SH "SYNOPSIS"
-.HP \w'\fBmysqlmanager\ [\fR\fB\fIoptions\fR\fR\fB]\fR\ 'u
-\fBmysqlmanager [\fR\fB\fIoptions\fR\fR\fB]\fR
-.SH "DESCRIPTION"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-\fBmysqlmanager\fR
-is the MySQL Instance Manager (IM)\&. This program monitors and manages MySQL Database Server instances\&. MySQL Instance Manager is available for Unix\-like operating systems, as well as Windows\&. It runs as a daemon that listens on a TCP/IP port\&. On Unix, it also listens on a Unix socket file\&.
-.PP
-MySQL Instance Manager can be used in place of the
-mysqld_safe
-script to start and stop one or more instances of MySQL Server\&. Because Instance Manager can manage multiple server instances, it can also be used in place of the
-\fBmysqld_multi\fR
-script\&. Instance Manager offers these capabilities:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Instance Manager can start and stop instances, and report on the status of instances\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Server instances can be treated as guarded or unguarded:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-When Instance Manager starts, it starts each guarded instance\&. If the instance crashes, Instance Manager detects this and restarts it\&. When Instance Manager stops, it stops the instance\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-A nonguarded instance is not started when Instance Manager starts or monitored by it\&. If the instance crashes after being started, Instance Manager does not restart it\&. When Instance Manager exits, it does not stop the instance if it is running\&.
-.RE
-.RS 4
-Instances are guarded by default\&. An instance can be designated as nonguarded by including the
-\fBnonguarded\fR
-option in the configuration file\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Instance Manager provides an interactive interface for configuring instances, so that the need to edit the configuration file manually is reduced or eliminated\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Instance Manager provides remote instance management\&. That is, it runs on the host where you want to control MySQL Server instances, but you can connect to it from a remote host to perform instance\-management operations\&.
-.RE
-.PP
-The following sections describe MySQL Instance Manager operation in more detail\&.
-.SH "MYSQL INSTANCE MANAGER COMMAND OPTIONS"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-The MySQL Instance Manager supports a number of command options\&. For a brief listing, invoke
-\fBmysqlmanager\fR
-with the
-\fB\-\-help\fR
-option\&. Options may be given on the command line or in the Instance Manager configuration file\&. On Windows, the standard configuration file is
-my\&.ini
-in the directory where Instance Manager is installed\&. On Unix, the standard file is
-/etc/my\&.cnf\&. To specify a different configuration file, start Instance Manager with the
-\fB\-\-defaults\-file\fR
-option\&.
-.PP
-\fBmysqlmanager\fR
-supports the following options\&. The options for managing entries in the password file are described further in
-the section called \(lqINSTANCE MANAGER USER AND PASSWORD MANAGEMENT\(rq\&.
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: help option
-.\" help option: mysqlmanager
-\fB\-\-help\fR,
-\fB\-?\fR
-.sp
-Display a help message and exit\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: add-user option
-.\" add-user option: mysqlmanager
-\fB\-\-add\-user\fR
-.sp
-Add a new user (specified with the
-\fB\-\-username\fR
-option) to the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: angel-pid-file option
-.\" angel-pid-file option: mysqlmanager
-\fB\-\-angel\-pid\-file=\fR\fB\fIfile_name\fR\fR
-.sp
-The file in which the angel process records its process ID when
-\fBmysqlmanager\fR
-runs in daemon mode (that is, when the
-\fB\-\-run\-as\-service\fR
-option is given)\&. The default file name is
-mysqlmanager\&.angel\&.pid\&.
-.sp
-If the
-\fB\-\-angel\-pid\-file\fR
-option is not given, the default angel PID file has the same name as the PID file except that any PID file extension is replaced with an extension of
-\&.angel\&.pid\&. (For example,
-mysqlmanager\&.pid
-becomes
-mysqlmanager\&.angel\&.pid\&.)
-.sp
-This option was added in MySQL 5\&.1\&.11\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: bind-address option
-.\" bind-address option: mysqlmanager
-\fB\-\-bind\-address=\fR\fB\fIIP\fR\fR
-.sp
-The IP address to bind to\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: check-password-file option
-.\" check-password-file option: mysqlmanager
-\fB\-\-check\-password\-file\fR
-.sp
-Check the validity and consistency of the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: clean-password-file option
-.\" clean-password-file option: mysqlmanager
-\fB\-\-clean\-password\-file\fR
-.sp
-Drop all users from the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: debug option
-.\" debug option: mysqlmanager
-\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR,
-\fB\-# \fR\fB\fIdebug_options\fR\fR
-.sp
-Write a debugging log\&. A typical
-\fIdebug_options\fR
-string is
-\'d:t:o,\fIfile_name\fR\'\&. This option was added in MySQL 5\&.1\&.10\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: default-mysqld-path option
-.\" default-mysqld-path option: mysqlmanager
-\fB\-\-default\-mysqld\-path=\fR\fB\fIpath\fR\fR
-.sp
-The path name of the MySQL Server binary\&. This path name is used for all server instance sections in the configuration file for which no
-\fBmysqld\-path\fR
-option is present\&. The default value of this option is the compiled\-in path name, which depends on how the MySQL distribution was configured\&. Example:
-\fB\-\-default\-mysqld\-path=/usr/sbin/mysqld\fR
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: defaults-file option
-.\" defaults-file option: mysqlmanager
-\fB\-\-defaults\-file=\fR\fB\fIfile_name\fR\fR
-.sp
-Read Instance Manager and MySQL Server settings from the given file\&. All configuration changes made by the Instance Manager will be written to this file\&. This must be the first option on the command line if it is used, and the file must exist\&.
-.sp
-If this option is not given, Instance Manager uses its standard configuration file\&. On Windows, the standard file is
-my\&.ini
-in the directory where Instance Manager is installed\&. On Unix, the standard file is
-/etc/my\&.cnf\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: drop-user option
-.\" drop-user option: mysqlmanager
-\fB\-\-drop\-user\fR
-.sp
-Drop a user (specified with the
-\fB\-\-username\fR
-option) from the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: edit-user option
-.\" edit-user option: mysqlmanager
-\fB\-\-edit\-user\fR
-.sp
-Change an entry for an existing user (specified with the
-\fB\-\-username\fR
-option) in the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: install option
-.\" install option: mysqlmanager
-\fB\-\-install\fR
-.sp
-On Windows, install Instance Manager as a Windows service\&. The service name is
-MySQL Manager\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: list-users option
-.\" list-users option: mysqlmanager
-\fB\-\-list\-users\fR
-.sp
-List the users in the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: log option
-.\" log option: mysqlmanager
-\fB\-\-log=\fR\fB\fIfile_name\fR\fR
-.sp
-The path to the Instance Manager log file\&. This option has no effect unless the
-\fB\-\-run\-as\-service\fR
-option is also given\&. If the file name specified for the option is a relative name, the log file is created under the directory from which Instance Manager is started\&. To ensure that the file is created in a specific directory, specify it as a full path name\&.
-.sp
-If
-\fB\-\-run\-as\-service\fR
-is given without
-\fB\-\-log\fR, the log file is
-mysqlmanager\&.log
-in the data directory\&.
-.sp
-If
-\fB\-\-run\-as\-service\fR
-is not given, log messages go to the standard output\&. To capture log output, you can redirect Instance Manager output to a file:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager > im\&.log
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: monitoring-interval option
-.\" monitoring-interval option: mysqlmanager
-\fB\-\-monitoring\-interval=\fR\fB\fIseconds\fR\fR
-.sp
-The interval in seconds for monitoring server instances\&. The default value is 20 seconds\&. Instance Manager tries to connect to each monitored (guarded) instance using the nonexisting
-MySQL_Instance_Manager
-user account to check whether it is alive/not hanging\&. If the result of the connection attempt indicates that the instance is unavailable, Instance Manager performs several attempts to restart the instance\&.
-.sp
-Normally, the
-MySQL_Instance_Manager
-account does not exist, so the connection attempts by Instance Manager cause the monitored instance to produce messages in its general query log similar to the following:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-Access denied for user \'MySQL_Instance_M\'@\'localhost\' \(Fc
- (using password: YES)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-The
-nonguarded
-option in the appropriate server instance section disables monitoring for a particular instance\&. If the instance dies after being started, Instance Manager will not restart it\&. Instance Manager tries to connect to a nonguarded instance only when you request the instance\'s status (for example, with the
-SHOW INSTANCES
-status\&.
-.sp
-See
-the section called \(lqMYSQL SERVER INSTANCE STATUS MONITORING\(rq, for more information\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: mysqld-safe-compatible option
-.\" mysqld-safe-compatible option: mysqlmanager
-\fB\-\-mysqld\-safe\-compatible\fR
-.sp
-Run in a
-\fBmysqld_safe\fR\-compatible manner\&. For details, see
-the section called \(lqSTARTING THE MYSQL SERVER WITH MYSQL INSTANCE MANAGER\(rq\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: password option
-.\" password option: mysqlmanager
-\fB\-\-password=\fR\fB\fIpassword\fR\fR,
-\fB\-p \fR\fB\fIpassword\fR\fR
-.sp
-Specify the password for an entry to be added to or modified in the password file\&. Unlike the
-\fB\-\-password\fR/\fB\-P\fR
-option for most MySQL programs, the password value is required, not optional\&. See also
-the section called \(lqINSTANCE MANAGER USER AND PASSWORD MANAGEMENT\(rq\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: password-file option
-.\" password-file option: mysqlmanager
-\fB\-\-password\-file=\fR\fB\fIfile_name\fR\fR
-.sp
-The name of the file where the Instance Manager looks for users and passwords\&. On Windows, the default is
-mysqlmanager\&.passwd
-in the directory where Instance Manager is installed\&. On Unix, the default file is
-/etc/mysqlmanager\&.passwd\&. See also
-the section called \(lqINSTANCE MANAGER USER AND PASSWORD MANAGEMENT\(rq\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: pid-file option
-.\" pid-file option: mysqlmanager
-\fB\-\-pid\-file=\fR\fB\fIfile_name\fR\fR
-.sp
-The process ID file to use\&. On Windows, the default file is
-mysqlmanager\&.pid
-in the directory where Instance Manager is installed\&. On Unix, the default is
-mysqlmanager\&.pid
-in the data directory\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: port option
-.\" port option: mysqlmanager
-\fB\-\-port=\fR\fB\fIport_num\fR\fR
-.sp
-The port number to use when listening for TCP/IP connections from clients\&. The default port number (assigned by IANA) is 2273\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: print-defaults option
-.\" print-defaults option: mysqlmanager
-\fB\-\-print\-defaults\fR
-.sp
-Print the current defaults and exit\&. This must be the first option on the command line if it is used\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: print-password-line option
-.\" print-password-line option: mysqlmanager
-\fB\-\-print\-password\-line\fR
-.sp
-Prepare an entry for the password file, print it to the standard output, and exit\&. You can redirect the output from Instance Manager to a file to save the entry in the file\&.
-.sp
-Prior to MySQL 5\&.1\&.12, this option was named
-\fB\-\-passwd\fR\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: remove option
-.\" remove option: mysqlmanager
-\fB\-\-remove\fR
-.sp
-On Windows, removes Instance Manager as a Windows service\&. This assumes that Instance Manager has been run with
-\fB\-\-install\fR
-previously\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: run-as-service option
-.\" run-as-service option: mysqlmanager
-\fB\-\-run\-as\-service\fR
-.sp
-On Unix, daemonize and start an angel process\&. The angel process monitors Instance Manager and restarts it if it crashes\&. (The angel process itself is simple and unlikely to crash\&.)
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: socket option
-.\" socket option: mysqlmanager
-\fB\-\-socket=\fR\fB\fIpath\fR\fR
-.sp
-On Unix, the socket file to use for incoming connections\&. The default file is named
-/tmp/mysqlmanager\&.sock\&. This option has no meaning on Windows\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: standalone option
-.\" standalone option: mysqlmanager
-\fB\-\-standalone\fR
-.sp
-This option is used on Windows to run Instance Manager in standalone mode\&. You should specify it when you start Instance Manager from the command line\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: user option
-.\" user option: mysqlmanager
-\fB\-\-user=\fR\fB\fIuser_name\fR\fR
-.sp
-On Unix, the user name of the system account to use for starting and running
-\fBmysqlmanager\fR\&. This option generates a warning and has no effect unless you start
-\fBmysqlmanager\fR
-as
-root
-(so that it can change its effective user ID), or as the named user\&. It is recommended that you configure
-\fBmysqlmanager\fR
-to run using the same account used to run the
-\fBmysqld\fR
-server\&. (\(lqUser\(rq
-in this context refers to a system login account, not a MySQL user listed in the grant tables\&.)
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: username option
-.\" username option: mysqlmanager
-\fB\-\-username=\fR\fB\fIuser_name\fR\fR,
-\fB\-u \fR\fB\fIuser_name\fR\fR
-.sp
-Specify the user name for an entry to be added to or modified in the password file\&. This option was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: version option
-.\" version option: mysqlmanager
-\fB\-\-version\fR,
-\fB\-V\fR
-.sp
-Display version information and exit\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-.\" mysqlmanager: wait-timeout option
-.\" wait-timeout option: mysqlmanager
-\fB\-\-wait\-timeout=\fR\fB\fIN\fR\fR
-.sp
-The number of seconds to wait for activity on an incoming connection before closing it\&. The default is 28800 seconds (8 hours)\&.
-.sp
-This option was added in MySQL 5\&.1\&.7\&. Before that, the timeout is 30 seconds and cannot be changed\&.
-.RE
-.SH "MYSQL INSTANCE MANAGER CONFIGURATION FILES"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-Instance Manager uses its standard configuration file unless it is started with a
-\fB\-\-defaults\-file\fR
-option that specifies a different file\&. On Windows, the standard file is
-my\&.ini
-in the directory where Instance Manager is installed\&. On Unix, the standard file is
-/etc/my\&.cnf\&.
-.PP
-Instance Manager reads options for itself from the
-[manager]
-section of the configuration file, and options for server instances from
-[mysqld]
-or
-[mysqld\fIN\fR]
-sections\&. The
-[manager]
-section contains any of the options listed in
-the section called \(lqMYSQL INSTANCE MANAGER COMMAND OPTIONS\(rq, except for those specified as having to be given as the first option on the command line\&. Here is a sample
-[manager]
-section:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-# MySQL Instance Manager options section
-[manager]
-default\-mysqld\-path = /usr/local/mysql/libexec/mysqld
-socket=/tmp/manager\&.sock
-pid\-file=/tmp/manager\&.pid
-password\-file = /home/cps/\&.mysqlmanager\&.passwd
-monitoring\-interval = 2
-port = 1999
-bind\-address = 192\&.168\&.1\&.5
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-Each
-[mysqld]
-or
-[mysqld\fIN\fR]
-instance section specifies options given by Instance Manager to a server instance at startup\&. These are mainly common MySQL Server options (see
-Section\ \&5.1.2, \(lqServer Command Options\(rq)\&. In addition, a
-[mysqld\fIN\fR]
-section can contain the options in the following list, which are specific to Instance Manager\&. These options are interpreted by Instance Manager itself; it does not pass them to the server when it attempts to start that server\&.
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBWarning\fR
-.ps -1
-.br
-.PP
-The Instance Manager\-specific options must not be used in a
-[mysqld]
-section\&. If a server is started without using Instance Manager, it will not recognize these options and will fail to start properly\&.
-.sp .5v
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-mysqld\-path = \fIpath\fR
-.sp
-The path name of the
-\fBmysqld\fR
-server binary to use for the server instance\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-nonguarded
-.sp
-This option disables Instance Manager monitoring functionality for the server instance\&. By default, an instance is guarded: At Instance Manager start time, it starts the instance\&. It also monitors the instance status and attempts to restart it if it fails\&. At Instance Manager exit time, it stops the instance\&. None of these things happen for nonguarded instances\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-shutdown\-delay = \fIseconds\fR
-.sp
-The number of seconds Instance Manager should wait for the server instance to shut down\&. The default value is 35 seconds\&. After the delay expires, Instance Manager assumes that the instance is hanging and attempts to terminate it\&. If you use
-InnoDB
-with large tables, you should increase this value\&.
-.RE
-.PP
-Here are some sample instance sections:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-[mysqld1]
-mysqld\-path=/usr/local/mysql/libexec/mysqld
-socket=/tmp/mysql\&.sock
-port=3307
-server_id=1
-skip\-stack\-trace
-core\-file
-log\-bin
-log\-error
-log=mylog
-log\-slow\-queries
-[mysqld2]
-nonguarded
-port=3308
-server_id=2
-mysqld\-path= /home/cps/mysql/trees/mysql\-5\&.1/sql/mysqld
-socket = /tmp/mysql\&.sock5
-pid\-file = /tmp/hostname\&.pid5
-datadir= /home/cps/mysql_data/data_dir1
-language=/home/cps/mysql/trees/mysql\-5\&.1/sql/share/english
-log\-bin
-log=/tmp/fordel\&.log
-.fi
-.if n \{\
-.RE
-.\}
-.SH "STARTING THE MYSQL SERVER WITH MYSQL INSTANCE MANAGER"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-This section discusses how Instance Manager starts server instances when it starts\&. However, before you start Instance Manager, you should set up a password file for it\&. Otherwise, you will not be able to connect to Instance Manager to control it after it starts\&. For details about creating Instance Manager accounts, see
-the section called \(lqINSTANCE MANAGER USER AND PASSWORD MANAGEMENT\(rq\&.
-.PP
-On Unix, the
-\fBmysqld\fR
-MySQL database server normally is started with the
-\fBmysql\&.server\fR
-script, which usually resides in the
-/etc/init\&.d/
-folder\&. That script invokes the
-\fBmysqld_safe\fR
-script by default\&. However, you can use Instance Manager instead if you modify the
-/etc/my\&.cnf
-configuration file by adding
-use\-manager
-to the
-[mysql\&.server]
-section:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-[mysql\&.server]
-use\-manager
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-Before MySQL 5\&.1\&.12, Instance Manager always tries to start at least one server instance: When it starts, it reads its configuration file if it exists to find server instance sections and prepare a list of instances\&. Instance sections have names of the form
-[mysqld]
-or
-[mysqld\fIN\fR], where
-\fIN\fR
-is an unsigned integer (for example,
-[mysqld1],
-[mysqld2], and so forth)\&.
-.PP
-After preparing the list of instances, Instance Manager starts the guarded instances in the list\&. If there are no instances, Instance Manager creates an instance named
-mysqld
-and attempts to start it with default (compiled\-in) configuration values\&. This means that the Instance Manager cannot find the
-\fBmysqld\fR
-program if it is not installed in the default location\&. (Section\ \&2.1.5, \(lqInstallation Layouts\(rq, describes default locations for components of MySQL distributions\&.) If you have installed the MySQL server in a nonstandard location, you should create the Instance Manager configuration file\&.
-.PP
-The startup behavior just described is similar to that of
-\fBmysqld_safe\fR, which always attempts to start a server\&. However, it lacks the flexibility required for some operations because it is not possible to run Instance Manager in such a way that it refrains from starting any server instances\&. For example, you cannot invoke Instance Manager for the purpose of configuring an instance without also starting it (a task that a MySQL installer application might want to perform)\&. Consequently, MySQL 5\&.1\&.12 introduces the following changes:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-A new option,
-\fB\-\-mysqld\-safe\-compatible\fR, may be used to cause Instance Manager to run with startup behavior similar to that used before MySQL 5\&.1\&.12: If Instance Manager finds a
-[mysqld]
-instance section in the configuration file, it will start it\&. If Instance Manager finds no
-[mysqld]
-section, it creates one using default configuration values, writes a
-[mysqld]
-section to the configuration file if it is accessible, and starts the
-mysqld
-instance\&. Instance Manager also starts any other guarded instances listed in the configuration file\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Without
-\fB\-\-mysqld\-safe\-compatible\fR, Instance Manager reads its configuration file if it exists and starts instances for any guarded instance sections that it finds\&. If there are none, it starts no instances\&.
-.RE
-.PP
-Instance Manager also stops all guarded server instances when it shuts down\&.
-.PP
-The allowable options for
-[mysqld\fIN\fR]
-server instance sections are described in
-the section called \(lqMYSQL INSTANCE MANAGER CONFIGURATION FILES\(rq\&. In these sections, you can use a special
-\fBmysqld\-path=\fR\fB\fIpath\-to\-mysqld\-binary\fR\fR
-option that is recognized only by Instance Manager\&. Use this option to let Instance Manager know where the
-\fBmysqld\fR
-binary resides\&. If there are multiple instances, it may also be necessary to set other options such as
-\fBdatadir\fR
-and
-\fBport\fR, to ensure that each instance has a different data directory and TCP/IP port number\&.
-Section\ \&5.6, \(lqRunning Multiple MySQL Servers on the Same Machine\(rq, discusses the configuration values that must differ for each instance when you run multiple instance on the same machine\&.
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBWarning\fR
-.ps -1
-.br
-.PP
-The
-[mysqld]
-instance section, if it exists, must not contain any Instance Manager\-specific options\&.
-.sp .5v
-.RE
-.PP
-The typical Unix startup/shutdown cycle for a MySQL server with the MySQL Instance Manager enabled is as follows:
-.sp
-.RS 4
-.ie n \{\
-\h'-04' 1.\h'+01'\c
-.\}
-.el \{\
-.sp -1
-.IP " 1." 4.2
-.\}
-The
-\fB/etc/init\&.d/mysql\fR
-script starts MySQL Instance Manager\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04' 2.\h'+01'\c
-.\}
-.el \{\
-.sp -1
-.IP " 2." 4.2
-.\}
-Instance Manager starts the guarded server instances and monitors them\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04' 3.\h'+01'\c
-.\}
-.el \{\
-.sp -1
-.IP " 3." 4.2
-.\}
-If a server instance fails, Instance Manager restarts it\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04' 4.\h'+01'\c
-.\}
-.el \{\
-.sp -1
-.IP " 4." 4.2
-.\}
-If Instance Manager is shut down (for example, with the
-\fB/etc/init\&.d/mysql stop\fR
-command), it shuts down all server instances\&.
-.RE
-.SH "INSTANCE MANAGER USER AND PASSWORD MANAGEMENT"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-The Instance Manager stores its user information in a password file\&. On Windows, the default is
-mysqlmanager\&.passwd
-in the directory where Instance Manager is installed\&. On Unix, the default file is
-/etc/mysqlmanager\&.passwd\&. To specify a different location for the password file, use the
-\fB\-\-password\-file\fR
-option\&.
-.PP
-If the password file does not exist or contains no password entries, you cannot connect to the Instance Manager\&.
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBNote\fR
-.ps -1
-.br
-.PP
-Any Instance Manager process that is running to monitor server instances does not notice changes to the password file\&. You must stop it and restart it after making password entry changes\&.
-.sp .5v
-.RE
-.PP
-Entries in the password file have the following format, where the two fields are the account user name and encrypted password, separated by a colon:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-petr:*35110DC9B4D8140F5DE667E28C72DD2597B5C848
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-Instance Manager password encryption is the same as that used by MySQL Server\&. It is a one\-way operation; no means are provided for decrypting encrypted passwords\&.
-.PP
-Instance Manager accounts differ somewhat from MySQL Server accounts:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-MySQL Server accounts are associated with a host name, user name, and password (see
-Section\ \&5.5.1, \(lqUser Names and Passwords\(rq)\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Instance Manager accounts are associated with a user name and password only\&.
-.RE
-.PP
-This means that a client can connect to Instance Manager with a given user name from any host\&. To limit connections so that clients can connect only from the local host, start Instance Manager with the
-\fB\-\-bind\-address=127\&.0\&.0\&.1\fR
-option so that it listens only to the local network interface\&. Remote clients will not be able to connect\&. Local clients can connect like this:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysql \-h 127\&.0\&.0\&.1 \-P 2273\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-Before MySQL 5\&.1\&.12, the only option for creating password file entries is
-\fB\-\-passwd\fR, which causes Instance Manager to prompt for user name and password values and display the resulting entry\&. You can save the output in the
-/etc/mysqlmanager\&.passwd
-password file to store it\&. Here is an example:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysqlmanager \-\-passwd >> /etc/mysqlmanager\&.passwd\fR
-Creating record for new user\&.
-Enter user name: \fBmike\fR
-Enter password: \fBmikepass\fR
-Re\-type password: \fBmikepass\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-At the prompts, enter the user name and password for the new Instance Manager user\&. You must enter the password twice\&. It does not echo to the screen, so double entry guards against entering a different password than you intend (if the two passwords do not match, no entry is generated)\&.
-.PP
-The preceding command causes the following line to be added to
-/etc/mysqlmanager\&.passwd:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mike:*BBF1F551DD9DD96A01E66EC7DDC073911BAD17BA
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-Use of the
-\fB\-\-password\fR
-option fails if
-\fBmysqlmanager\fR
-is invoked directly from an IBM 5250 terminal\&. To work around this, use a command like the following from the command line to generate the password entry:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysql \-B \-\-skip\-column\-name \e\fR
- \fB\-e \'SELECT CONCAT("\fR\fB\fIuser_name\fR\fR\fB",":",PASSWORD("\fR\fB\fIpass_val\fR\fR\fB"));\'\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-The output from the command can be used an entry in the
-/etc/mysqlmanager\&.passwd
-file\&.
-.PP
-Beginning with MySQL 5\&.1\&.12, the
-\fB\-\-passwd\fR
-option is renamed to
-\fB\-\-print\-password\-line\fR
-and there are several other options for managing user accounts from the command line\&. For example, the
-\fB\-\-username\fR
-and
-\fB\-\-password\fR
-options are available on the command line for specifying the user name and password for an account entry\&. You can use them to generate an entry with no prompting like this (type the command on a single line):
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysqlmanager \-\-print\-password\-line\fR
- \fB\-\-username=mike \-\-password=mikepass >> /etc/mysqlmanager\&.passwd\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-If you omit the
-\fB\-\-username\fR
-or
-\fB\-\-password\fR
-option, Instance Manager prompts for the required value\&.
-.PP
-\fB\-\-print\-password\-line\fR
-causes Instance Manager to send the resulting account entry to its output, which you can append to the password file\&. The following list describes other account\-management options that cause Instance Manager to operate directly on the password file\&. (These options make Instance Manager scriptable for account\-management purposes\&.) For operations on the password file to succeed, the file must exist and it must be accessible by Instance Manager\&. (The exception is
-\fB\-\-clean\-password\-file\fR, which creates the file if it does not exist\&. Alternatively, if there is no password file, manually create it as an empty file and ensure that its ownership and access modes allow it to be read and written by Instance Manager\&.) The default password file is used unless you specify a
-\fB\-\-password\-file\fR
-option\&.
-.PP
-To ensure consistent treatment of the password file, it should be owned by the system account that you use for running Instance Manager to manage server instances, and you should invoke it from that account when you use it to manage accounts in the password file\&.
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Create a new user:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager \-\-add\-user \-\-username=\fIuser_name\fR [\-\-password=\fIpassword\fR]
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-This command adds a new entry with the given user name and password to the password file\&. The
-\fB\-\-username\fR
-(or
-\fB\-u\fR) option is required\&.
-\fBmysqlmanager\fR
-prompts for the password if it is not given on the command line with the
-\fB\-\-password\fR
-(or
-\fB\-p\fR) option\&. The command fails if the user already exists\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Drop an existing user:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager \-\-drop\-user \-\-username=\fIuser_name\fR
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-This command removes the entry with the given user name from the password file\&. The user name is required\&. The command fails if the user does not exist\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Change the password for an existing user:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager \-\-edit\-user \-\-username=\fIuser_name\fR [\-\-password=\fIpassword\fR]
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-This command changes the given user\'s password in the password file\&. The user name is required\&.
-\fBmysqlmanager\fR
-prompts for the password it is not given on the command line\&. The command fails if the user does not exist\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-List existing users:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager \-\-list\-users
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-This command lists the user names of the accounts in the password file\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Check the password file:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager \-\-check\-password\-file
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-This command performs a consistency and validity check of the password file\&. The command fails if there is something wrong with the file\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Empty the password file:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysqlmanager \-\-clean\-password\-file
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-This command empties the password file, which has the effect of dropping all users listed in it\&. The option creates the password file if it does not exist, so it can be used to initialize a new password file to be used for other account\-management operations\&. Take care not to use this option to reinitialize a file containing accounts that you do not want to drop\&.
-.RE
-.SH "MYSQL SERVER INSTANCE STATUS MONITORING"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-To monitor the status of each guarded server instance, the MySQL Instance Manager attempts to connect to the instance at regular intervals using the
-MySQL_Instance_Manager@localhost
-user account with a password of
-check_connection\&.
-.PP
-You are
-\fInot\fR
-required to create this account for MySQL Server; in fact, it is expected that it will not exist\&. Instance Manager can tell that a server is operational if the server accepts the connection attempt but refuses access for the account by returning a login error\&. However, these failed connection attempts are logged by the server to its general query log (see
-Section\ \&5.2.3, \(lqThe General Query Log\(rq)\&.
-.PP
-Instance Manager also attempts a connection to nonguarded server instances when you use the
-SHOW INSTANCES
-or
-SHOW INSTANCE STATUS
-command\&. This is the only status monitoring done for nonguarded instances\&.
-.PP
-Instance Manager knows if a server instance fails at startup because it receives a status from the attempt\&. For an instance that starts but later crashes, Instance Manager receives a signal because it is the parent process of the instance\&.
-.PP
-Beginning with MySQL 5\&.1\&.12, Instance Manager tracks instance states so that it can determine which commands are allowed for each instance\&. For example, commands that modify an instance\'s configuration are allowed only while the instance is offline\&.
-.PP
-Each instance is in one of the states described in the following table\&. Guarded instances can be in any of the states\&. Nonguarded instances can only be offline or online\&. Instance state information is displayed in the
-status
-column of the
-SHOW INSTANCES
-and
-SHOW INSTANCE STATUS
-commands\&.
-.TS
-allbox tab(:);
-l l
-l l
-l l
-l l
-l l
-l l
-l l
-l l.
-T{
-\fBState\fR
-T}:T{
-\fBMeaning\fR
-T}
-T{
-offline
-T}:T{
-The instance has not been started and is not running\&.
-T}
-T{
-starting
-T}:T{
-The instance is starting (initializing)\&. Nonguarded instances cannot be
- in this state\&. A nonguarded instance goes directly from
- offline to online\&.
-T}
-T{
-stopping
-T}:T{
-The instance is stopping\&. Nonguarded instances cannot be in this state\&.
- A nonguarded instance goes directly from online to
- offline, or stays offline if startup fails\&.
-T}
-T{
-online
-T}:T{
-The instance has started and is running\&.
-T}
-T{
-failed
-T}:T{
-The instance was online but it crashed and is being restarted by
- Instance Manager, or else the instance failed to start
- at all and Instance Manager is again attempting to start
- it\&. Nonguarded instances cannot be in this state\&.
-T}
-T{
-crashed
-T}:T{
-Instance Manager failed to start the instance after several attempts\&.
- (Instance Manager will try again later\&.) Nonguarded
- instances cannot be in this state\&.
-T}
-T{
-abandoned
-T}:T{
-Instance Manager was not able to start the instance, has given up, and
- will make no further attempts until instructed
- otherwise\&. To tell Instance Manager to try again, you
- must first use STOP INSTANCE to put
- the instance in offline state, and then use
- START INSTANCE to start the instance\&.
- If it is necessary to make configuration changes for the
- instance, you must do so after putting the instance
- offline and before starting it\&. (Instance Manager
- accepts configuration\-changing commands only for offline
- instances\&.) Nonguarded instances cannot be in this
- state\&.
-T}
-.TE
-.sp 1
-.SH "CONNECTING TO MYSQL INSTANCE MANAGER"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-After you set up a password file for the MySQL Instance Manager and Instance Manager is running, you can connect to it\&. The MySQL client\-server protocol is used to communicate with the Instance Manager\&. For example, you can connect to it using the standard
-\fBmysql\fR
-client program:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-shell> \fBmysql \-\-port=2273 \-\-host=im\&.example\&.org \-\-user=mysql \-\-password\fR
-.fi
-.if n \{\
-.RE
-.\}
-.PP
-Instance Manager supports the version of the MySQL client\-server protocol used by the client tools and libraries distributed with MySQL 4\&.1 or later, so other programs that use the MySQL C API also can connect to it\&.
-.SH "MYSQL INSTANCE MANAGER COMMANDS"
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
-.PP
-MySQL Instance Manager has been deprecated and is removed in MySQL 5\&.4\&.
-.sp .5v
-.RE
-.PP
-After you connect to MySQL Instance Manager, you can issue commands\&. The following general principles apply to Instance Manager command execution:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Commands that take an instance name fail if the name is not a valid instance name\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Commands that take an instance name (other than
-CREATE INSTANCE) fail if the instance does not exist\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-As of MySQL 5\&.1\&.12, commands for an instance require that the instance be in an appropriate state\&. You cannot configure or start an instance that is not offline\&. You cannot start an instance that is online\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-Instance Manager maintains information about instance configuration in an internal (in\-memory) cache\&. Initially, this information comes from the configuration file if it exists, but some commands change the configuration of an instance\&. Commands that modify the configuration file fail if the file does not exist or is not accessible to Instance Manager\&.
-.sp
-As of MySQL 5\&.1\&.12, configuration\-changing commands modify both the in\-memory cache and the server instance section recorded in the configuration file to maintain consistency between them\&. For this to occur, the instance must be offline and the configuration file must be accessible and not malformed\&. If the configuration file cannot be updated, the command fails and the cache remains unchanged\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-On Windows, the standard file is
-my\&.ini
-in the directory where Instance Manager is installed\&. On Unix, the standard configuration file is
-/etc/my\&.cnf\&. To specify a different configuration file, start Instance Manager with the
-\fB\-\-defaults\-file\fR
-option\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-If a
-[mysqld]
-instance section exists in the configuration file, it must not contain any Instance Manager\-specific options (see
-the section called \(lqMYSQL INSTANCE MANAGER CONFIGURATION FILES\(rq)\&. Therefore, you must not add any of these options if you change the configuration for an instance named
-mysqld\&.
-.RE
-.PP
-The following list describes the commands that Instance Manager accepts, with examples\&.
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-CREATE INSTANCE \fIinstance_name\fR [\fIoption_name\fR[=\fIoption_value\fR], \&.\&.\&.]
-.sp
-This command configures a new instance by creating an
-[\fIinstance_name\fR]
-section in the configuration file\&. The command fails if
-\fIinstance_name\fR
-is not a valid instance name or the instance already exists\&.
-.sp
-The created section instance is empty if no options are given\&. Otherwise, the options are added to the section\&. Options should be given in the same format used when you write options in option files\&. (See
-Section\ \&4.2.3.3, \(lqUsing Option Files\(rq
-for a description of the allowable syntax\&.) If you specify multiple options, separate them by commas\&.
-.sp
-For example, to create an instance section named
-[mysqld98], you might write something like this were you to modify the configuration file directly:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-[mysqld98]
-basedir=/var/mysql98
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-To achieve the same effect via
-CREATE INSTANCE, issue this command to Instance Manager:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBCREATE INSTANCE mysqld98 basedir="/var/mysql98";\fR
-Query OK, 0 rows affected (0,00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-CREATE INSTANCE
-creates the instance but does not start it\&.
-.sp
-If the instance name is the (deprecated) name
-mysqld, the option list cannot include any options that are specific to Instance Manager, such as
-nonguarded
-(see
-the section called \(lqMYSQL INSTANCE MANAGER CONFIGURATION FILES\(rq)\&.
-.sp
-This command was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-DROP INSTANCE \fIinstance_name\fR
-.sp
-This command removes the configuration for
-\fIinstance_name\fR
-from the configuration file\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBDROP INSTANCE mysqld98;\fR
-Query OK, 0 rows affected (0,00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-The command fails if
-\fIinstance_name\fR
-is not a valid instance name, the instance does not exist, or is not offline\&.
-.sp
-This command was added in MySQL 5\&.1\&.12\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-START INSTANCE \fIinstance_name\fR
-.sp
-This command attempts to start an offline instance\&. The command is asynchronous; it does not wait for the instance to start\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSTART INSTANCE mysqld4;\fR
-Query OK, 0 rows affected (0,00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-STOP INSTANCE \fIinstance_name\fR
-.sp
-This command attempts to stop an instance\&. The command is synchronous; it waits for the instance to stop\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSTOP INSTANCE mysqld4;\fR
-Query OK, 0 rows affected (0,00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-SHOW INSTANCES
-.sp
-Shows the names and status of all loaded instances\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSHOW INSTANCES;\fR
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+
-| instance_name | status |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+
-| mysqld3 | offline |
-| mysqld4 | online |
-| mysqld2 | offline |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-SHOW INSTANCE STATUS \fIinstance_name\fR
-.sp
-Shows status and version information for an instance\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSHOW INSTANCE STATUS mysqld3;\fR
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+
-| instance_name | status | version |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+
-| mysqld3 | online | unknown |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-SHOW INSTANCE OPTIONS \fIinstance_name\fR
-.sp
-Shows the options used by an instance\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSHOW INSTANCE OPTIONS mysqld3;\fR
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
-| option_name | value |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
-| instance_name | mysqld3 |
-| mysqld\-path | /home/cps/mysql/trees/mysql\-4\&.1/sql/mysqld |
-| port | 3309 |
-| socket | /tmp/mysql\&.sock3 |
-| pid\-file | hostname\&.pid3 |
-| datadir | /home/cps/mysql_data/data_dir1/ |
-| language | /home/cps/mysql/trees/mysql\-4\&.1/sql/share/english |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-SHOW \fIinstance_name\fR LOG FILES
-.sp
-The command lists all log files used by the instance\&. The result set contains the path to the log file and the log file size\&. If no log file path is specified in the instance section of the configuration file (for example,
-log=/var/mysql\&.log), the Instance Manager tries to guess its placement\&. If Instance Manager is unable to guess the log file placement you should specify the log file location explicitly by using a log option in the appropriate instance section of the configuration file\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSHOW mysqld LOG FILES;\fR
-+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+
-| Logfile | Path | Filesize |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+
-| ERROR LOG | /home/cps/var/mysql/owlet\&.err | 9186 |
-| GENERAL LOG | /home/cps/var/mysql/owlet\&.log | 471503 |
-| SLOW LOG | /home/cps/var/mysql/owlet\-slow\&.log | 4463 |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-SHOW \&.\&.\&. LOG FILES
-displays information only about log files\&. If a server instance uses log tables (see
-Section\ \&5.2.1, \(lqSelecting General Query and Slow Query Log Output Destinations\(rq), no information about those tables is shown\&.
-.sp
-Log options are described in
-Section\ \&5.1.2, \(lqServer Command Options\(rq\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-SHOW \fIinstance_name\fR LOG {ERROR | SLOW | GENERAL} \fIsize\fR[,\fIoffset_from_end\fR]
-.sp
-This command retrieves a portion of the specified log file\&. Because most users are interested in the latest log messages, the
-\fIsize\fR
-parameter defines the number of bytes to retrieve from the end of the log\&. To retrieve data from the middle of the log file, specify the optional
-\fIoffset_from_end\fR
-parameter\&. The following example retrieves 21 bytes of data, starting 23 bytes before the end of the log file and ending 2 bytes before the end:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSHOW mysqld LOG GENERAL 21, 2;\fR
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
-| Log |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
-| using password: YES |
-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-SET \fIinstance_name\fR\&.\fIoption_name\fR[=\fIoption_value\fR]
-.sp
-This command edits the specified instance\'s configuration section to change or add instance options\&. The option is added to the section is it is not already present\&. Otherwise, the new setting replaces the existing one\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSET mysqld2\&.port=3322;\fR
-Query OK, 0 rows affected (0\&.00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-As of MySQL 5\&.1\&.12, you can specify multiple options (separated by commas), and
-SET
-can be used only for offline instances\&. Each option must indicate the instance name:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBSET mysqld2\&.port=3322, mysqld3\&.nonguarded;\fR
-Query OK, 0 rows affected (0\&.00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-Before MySQL 5\&.1\&.12, only a single option can be specified\&. Also, changes made to the configuration file do not take effect until the MySQL server is restarted\&. In addition, these changes are not stored in the instance manager\'s local cache of instance settings until a
-FLUSH INSTANCES
-command is executed\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-UNSET \fIinstance_name\fR\&.\fIoption_name\fR
-.sp
-This command removes an option from an instance\'s configuration section\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBUNSET mysqld2\&.port;\fR
-Query OK, 0 rows affected (0\&.00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-As of MySQL 5\&.1\&.12, you can specify multiple options (separated by commas), and
-UNSET
-can be used only for offline instances\&. Each option must indicate the instance name:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBUNSET mysqld2\&.port, mysqld4\&.nonguarded;\fR
-Query OK, 0 rows affected (0\&.00 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-Before MySQL 5\&.1\&.12, only a single option can be specified\&. Also, changes made to the configuration file do not take effect until the MySQL server is restarted\&. In addition, these changes are not stored in the instance manager\'s local cache of instance settings until a
-FLUSH INSTANCES
-command is executed\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-FLUSH INSTANCES
-.sp
-As of MySQL 5\&.1\&.12,
-FLUSH INSTANCES
-cannot be used unless all instances are offline\&. The command causes Instance Manager to reread the configuration file, update its in\-memory configuration cache, and start any guarded instances\&.
-.sp
-Before MySQL 5\&.1\&.12, this command forces Instance Manager reread the configuration file and to refresh internal structures\&. This command should be performed after editing the configuration file\&. The command does not restart instances\&.
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-mysql> \fBFLUSH INSTANCES;\fR
-Query OK, 0 rows affected (0\&.04 sec)
-.fi
-.if n \{\
-.RE
-.\}
-.RE
-.SH "COPYRIGHT"
-.br
-.PP
-Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.
-.PP
-This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
-.PP
-This documentation is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-.PP
-You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see http://www.gnu.org/licenses/.
-.sp
-.SH "SEE ALSO"
-For more information, please refer to the MySQL Reference Manual,
-which may already be installed locally and which is also available
-online at http://dev.mysql.com/doc/.
-.SH AUTHOR
-Sun Microsystems, Inc. (http://www.mysql.com/).
diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental
index ff4bc960acb..18cd4748687 100644
--- a/mysql-test/collections/default.experimental
+++ b/mysql-test/collections/default.experimental
@@ -13,7 +13,6 @@ main.signal_demo3 @solaris # Bug#11753919 2010-01-20 alik Several
main.sp @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
main.wait_timeout @solaris # Bug#11758972 2010-04-26 alik wait_timeout fails on OpenSolaris
-rpl.rpl_innodb_bug28430 # Bug#11754425
rpl.rpl_row_sp011 @solaris # Bug#11753919 2011-07-25 sven Several test cases fail on Solaris with error Thread stack overrun
rpl.rpl_spec_variables @solaris # Bug #17337114 2013-08-20 Luis Soares failing on pb2 with timeout for 'CHECK WARNINGS'
diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly
index a03e2593cfe..a03e2593cfe 100755..100644
--- a/mysql-test/collections/default.weekly
+++ b/mysql-test/collections/default.weekly
diff --git a/mysql-test/extra/rpl_tests/rpl_ddl.test b/mysql-test/extra/rpl_tests/rpl_ddl.test
index 32fc10479b8..8c35ff974d8 100644
--- a/mysql-test/extra/rpl_tests/rpl_ddl.test
+++ b/mysql-test/extra/rpl_tests/rpl_ddl.test
@@ -98,8 +98,8 @@
# --> less switching of AUTOCOMMIT mode on master side.
#
# 4. Never use a test object, which was direct or indirect affected by a
-# preceeding test sequence again.
-# If one preceeding test sequence hits a (sometimes not visible,
+# preceding test sequence again.
+# If one preceding test sequence hits a (sometimes not visible,
# because the sql error code of the statement might be 0) bug
# and these rules are ignored, a following test sequence might earn ugly
# effects like failing 'sync_slave_with_master', crashes of the slave or
diff --git a/mysql-test/extra/rpl_tests/rpl_row_basic.test b/mysql-test/extra/rpl_tests/rpl_row_basic.test
index f2ef0eda4f5..8ce45505c46 100644
--- a/mysql-test/extra/rpl_tests/rpl_row_basic.test
+++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test
@@ -221,7 +221,7 @@ INSERT INTO t7 VALUES (1,3), (2,6), (3,9);
SELECT * FROM t7 ORDER BY C1;
# since bug#31552/31609 idempotency is not default any longer. In order
-# the preceeding test INSERT INTO t7 to pass the mode is switched
+# the preceding test INSERT INTO t7 to pass the mode is switched
# temprorarily
set @@global.slave_exec_mode= 'IDEMPOTENT';
@@ -260,7 +260,7 @@ INSERT INTO t8 VALUES (1,2,3), (2,4,6), (3,6,9);
SELECT * FROM t8 ORDER BY a;
# since bug#31552/31609 idempotency is not default any longer. In order
-# the preceeding test INSERT INTO t8 to pass the mode is switched
+# the preceding test INSERT INTO t8 to pass the mode is switched
# temprorarily
set @@global.slave_exec_mode= 'IDEMPOTENT';
diff --git a/mysql-test/include/wait_until_count_sessions.inc b/mysql-test/include/wait_until_count_sessions.inc
index 26b0d8f2633..245fb68b5c3 100644
--- a/mysql-test/include/wait_until_count_sessions.inc
+++ b/mysql-test/include/wait_until_count_sessions.inc
@@ -10,7 +10,7 @@
# 1. We wait for $current_sessions <= $count_sessions because in the use case
# with count_sessions.inc before and wait_until_count_sessions.inc after
# the core of the test it could happen that the disconnects of sessions
-# belonging to the preceeding test are not finished.
+# belonging to the preceding test are not finished.
# sessions at test begin($count_sessions) = m + n
# sessions of the previous test which will be soon disconnected = n (n >= 0)
# sessions at test end ($current sessions, assuming the test disconnects
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index c795683c771..29bfa6df034 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -321,7 +321,7 @@ sub parse_disabled {
chomp;
next if /^\s*#/ or /^\s*$/;
mtr_error("Syntax error in $filename line $.")
- unless /^\s*(?:([-0-9A-Za-z_]+)\.)?([-0-9A-Za-z_]+)\s*:\s*(.*?)\s*$/;
+ unless /^\s*(?:([-0-9A-Za-z_\/]+)\.)?([-0-9A-Za-z_]+)\s*:\s*(.*?)\s*$/;
mtr_error("Wrong suite name in $filename line $.")
if defined $1 and defined $suitename and $1 ne $suitename;
$disabled{($1 || $suitename || '') . ".$2"} = $3;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 7667aec2375..e936073edd8 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -3654,6 +3654,9 @@ sub mysql_install_db {
mtr_appendfile_to_file("$sql_dir/fill_help_tables.sql",
$bootstrap_sql_file);
+ # mysql.gtid_slave_pos was created in InnoDB, but many tests
+ # run without InnoDB. Alter it to MyISAM now
+ mtr_tofile($bootstrap_sql_file, "ALTER TABLE gtid_slave_pos ENGINE=MyISAM;\n");
}
else
{
@@ -6582,7 +6585,7 @@ Misc options
start-dirty Only start the servers (without initialization) for
the first specified test case
user-args In combination with start* and no test name, drops
- arguments to mysqld except those speficied with
+ arguments to mysqld except those specified with
--mysqld (if any)
wait-all If --start or --start-dirty option is used, wait for all
servers to exit before finishing the process
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 622023d0e7d..ed6fd8b90bb 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -1460,6 +1460,33 @@ t2 CREATE TABLE `t2` (
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2;
+CREATE TABLE t2 (
+id INT(11) NOT NULL);
+ALTER TABLE t2 ADD COLUMN a INT, ADD COLUMN IF NOT EXISTS a INT;
+Warnings:
+Note 1060 Duplicate column name 'a'
+ALTER TABLE t2 ADD KEY k_id(id), ADD KEY IF NOT EXISTS k_id(id);
+Warnings:
+Note 1061 Duplicate key name 'k_id'
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `a` int(11) DEFAULT NULL,
+ KEY `k_id` (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t2 DROP KEY k_id, DROP KEY IF EXISTS k_id;
+Warnings:
+Note 1091 Can't DROP 'k_id'; check that column/key exists
+ALTER TABLE t2 DROP COLUMN a, DROP COLUMN IF EXISTS a;
+Warnings:
+Note 1091 Can't DROP 'a'; check that column/key exists
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
DROP TABLE t1;
# Bug#11748057 (formerly known as 34972): ALTER TABLE statement doesn't
# identify correct column name.
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 8ae61881c07..c81af134add 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -78,7 +78,7 @@ cast(cast(20010203101112.121314 as double) as datetime)
2001-02-03 10:11:12
select cast(cast(010203101112.12 as double) as datetime);
cast(cast(010203101112.12 as double) as datetime)
-0001-02-03 10:11:12
+2001-02-03 10:11:12
select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime);
cast(cast(20010203101112.121314 as decimal(32,6)) as datetime)
2001-02-03 10:11:12
@@ -87,10 +87,10 @@ cast(20010203101112.121314 as datetime)
2001-02-03 10:11:12
select cast(110203101112.121314 as datetime);
cast(110203101112.121314 as datetime)
-0011-02-03 10:11:12
+2011-02-03 10:11:12
select cast(cast(010203101112.12 as double) as datetime);
cast(cast(010203101112.12 as double) as datetime)
-0001-02-03 10:11:12
+2001-02-03 10:11:12
select cast("2011-02-03 10:11:12.123456" as datetime);
cast("2011-02-03 10:11:12.123456" as datetime)
2011-02-03 10:11:12
@@ -111,7 +111,7 @@ cast(cast(20010203101112.5 as double) as datetime(1))
2001-02-03 10:11:12.5
select cast(cast(010203101112.12 as double) as datetime(2));
cast(cast(010203101112.12 as double) as datetime(2))
-0001-02-03 10:11:12.12
+2001-02-03 10:11:12.12
select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6));
cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6))
2001-02-03 10:11:12.121314
@@ -120,10 +120,10 @@ cast(20010203101112.121314 as datetime(6))
2001-02-03 10:11:12.121314
select cast(110203101112.121314 as datetime(6));
cast(110203101112.121314 as datetime(6))
-0011-02-03 10:11:12.121314
+2011-02-03 10:11:12.121314
select cast(cast(010203101112.12 as double) as datetime(6));
cast(cast(010203101112.12 as double) as datetime(6))
-0001-02-03 10:11:12.120000
+2001-02-03 10:11:12.120000
select cast("2011-02-03 10:11:12.123456" as time);
cast("2011-02-03 10:11:12.123456" as time)
10:11:12
@@ -266,7 +266,7 @@ Warnings:
Warning 1264 Out of range value for column 'cast(-1000 as double(5,2))' at row 1
select cast(010203101112.121314 as datetime);
cast(010203101112.121314 as datetime)
-0001-02-03 10:11:12
+2001-02-03 10:11:12
select cast(120010203101112.121314 as datetime);
cast(120010203101112.121314 as datetime)
NULL
@@ -327,7 +327,7 @@ cast(cast(120010203101112.121314 as double) as datetime)
NULL
select cast(cast(1.1 as double) as datetime);
cast(cast(1.1 as double) as datetime)
-0000-00-00 00:00:01
+NULL
select cast(cast(-1.1 as double) as datetime);
cast(cast(-1.1 as double) as datetime)
NULL
diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result
index a2aae923cf7..32c7bdfcf12 100644
--- a/mysql-test/r/connect.result
+++ b/mysql-test/r/connect.result
@@ -273,6 +273,20 @@ connect(localhost,mysqltest_nouser,newpw,test,MASTER_PORT,MASTER_SOCKET);
ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: YES)
connect(localhost,mysqltest_nouser,,test,MASTER_PORT,MASTER_SOCKET);
ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: NO)
+update mysql.user set password=authentication_string, authentication_string=''
+ where user like 'mysqltest_up_';
+select user, password, plugin, authentication_string from mysql.user
+where user like 'mysqltest_up_';
+user password plugin authentication_string
+mysqltest_up1 *E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB mysql_native_password
+mysqltest_up2 09301740536db389 mysql_old_password
+flush privileges;
+select user(), current_user();
+user() current_user()
+mysqltest_up1@localhost mysqltest_up1@%
+select user(), current_user();
+user() current_user()
+mysqltest_up2@localhost mysqltest_up2@%
DROP USER mysqltest_up1@'%';
DROP USER mysqltest_up2@'%';
#
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 3a3b69f1fc7..d0f42c3d3ec 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -539,6 +539,7 @@ n d1 d2 result
2085 2012-01-01 00:00:00 2013-01-01 00:00:00 0
2084 2012-02-01 00:00:00 2013-01-01 00:00:00 0
drop table t1;
+set @save_derived_optimizer_switch_bug=@@optimizer_switch;
SET optimizer_switch = 'derived_merge=on,derived_with_keys=on,in_to_exists=on';
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (8);
@@ -553,4 +554,17 @@ id select_type table type possible_keys key key_len ref rows Extra
Warnings:
Note 1249 Select 4 was reduced during optimization
DROP TABLE t1, t2;
+set optimizer_switch=@save_derived_optimizer_switch_bug;
+#
+# MDEV-6163: Error while executing an update query that has the
+# same table in a sub-query
+#
+set @save_derived_optimizer_switch_bug=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+create table t1 (balance float, accountId varchar(64), primary key (accountId));
+insert into t1 (accountId,balance) values
+('dealer-1',199354.0),('dealer-2',0),('dealer-3',0),('dealer-5',0),('FINANCE',-200000),('OPERATOR',0);
+update t1 set balance=(select sum(balance) from (SELECT balance FROM t1 where accountId like 'dealer%') AS copied) where accountId = 'OPERATOR';
+set optimizer_switch=@save_derived_optimizer_switch_bug;
+drop table t1;
set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 64501ab5b76..87267124ff0 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -1288,7 +1288,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 't.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 28 from `test`.`t3` where ('j' < `test`.`t1`.`a`)))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(1,<expr_cache><`test`.`t1`.`a`>(exists(select 28 from `test`.`t3` where ('j' < `test`.`t1`.`a`))))
SELECT * FROM (SELECT * FROM t1) AS t
WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
WHERE t2.b < t.a);
diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result
index 5646de88d26..4753728793a 100644
--- a/mysql-test/r/dyncol.result
+++ b/mysql-test/r/dyncol.result
@@ -1001,29 +1001,29 @@ Warnings:
Warning 1292 Truncated incorrect time value: '1223.5aa'
select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time);
column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time)
-NULL
+838:59:59
Warnings:
-Warning 1292 Incorrect datetime value: '1.8446744073709552e19'
+Warning 1292 Truncated incorrect time value: '1.8446744073709552e19'
select column_get(column_create(1, 9223372036854775807 AS int), 1 as time);
column_get(column_create(1, 9223372036854775807 AS int), 1 as time)
-NULL
+838:59:59
Warnings:
-Warning 1292 Incorrect datetime value: '9223372036854775807'
+Warning 1292 Truncated incorrect time value: '9223372036854775807'
select column_get(column_create(1, -9223372036854775808 AS int), 1 as time);
column_get(column_create(1, -9223372036854775808 AS int), 1 as time)
-NULL
+-838:59:59
Warnings:
-Warning 1292 Incorrect datetime value: '-9223372036854775808'
+Warning 1292 Truncated incorrect time value: '-9223372036854775808'
select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time);
column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time)
-NULL
+838:59:59
Warnings:
-Warning 1292 Incorrect datetime value: '99999999999999999999999999999'
+Warning 1292 Truncated incorrect time value: '99999999999999999999999999999'
select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time);
column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time)
-NULL
+838:59:59
Warnings:
-Warning 1292 Incorrect datetime value: '1e29'
+Warning 1292 Truncated incorrect time value: '1e29'
select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time);
column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time)
NULL
@@ -1435,6 +1435,17 @@ Warning 1265 Data truncated for column 'dyncol' at row 1
SELECT COLUMN_ADD( dyncol, 'a', '22:22:22', 'c', REPEAT('x',270) AS CHAR ) FROM t1;
DROP table t1;
#
+# MDEV-4858 Wrong results for a huge unsigned value inserted into a TIME column
+#
+SELECT
+column_get(column_create(1, -999999999999999 AS int), 1 AS TIME) AS t1,
+column_get(column_create(1, -9223372036854775808 AS int), 1 AS TIME) AS t2;
+t1 t2
+-838:59:59 -838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '-999999999999999'
+Warning 1292 Truncated incorrect time value: '-9223372036854775808'
+#
# end of 5.3 tests
#
select column_get(column_create(1, "18446744073709552001" as char), 1 as int);
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 43f77629014..0cac910886b 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -602,8 +602,8 @@ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2 fulltext b2 b2 0 1 Using where
-2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 fulltext b2 b2 0 1 Using where
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where
# should return 0
SELECT count(*) FROM t1 WHERE
not exists(
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 0c4d22f89b7..5ae9ae1f0e8 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -584,3 +584,591 @@ ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#
# End of 5.5 tests
#
+
+# --
+# -- WL#5787: IPv6-capable INET_ATON and INET_NTOA functions.
+# --
+
+# -- INET6_ATON: checking NULL, invalid types, out-of range values...
+
+SELECT INET6_ATON(NULL) IS NULL;
+INET6_ATON(NULL) IS NULL
+1
+SELECT INET6_ATON(123) IS NULL;
+INET6_ATON(123) IS NULL
+1
+SELECT INET6_ATON(123.45) IS NULL;
+INET6_ATON(123.45) IS NULL
+1
+SELECT INET6_ATON(NOW()) IS NULL;
+INET6_ATON(NOW()) IS NULL
+1
+SELECT INET6_ATON('1.2.3') IS NULL;
+INET6_ATON('1.2.3') IS NULL
+1
+SELECT INET6_ATON('1.2.3.') IS NULL;
+INET6_ATON('1.2.3.') IS NULL
+1
+SELECT INET6_ATON('1..3.4') IS NULL;
+INET6_ATON('1..3.4') IS NULL
+1
+SELECT INET6_ATON('-1.2.3.4') IS NULL;
+INET6_ATON('-1.2.3.4') IS NULL
+1
+SELECT INET6_ATON('1.2.3.256') IS NULL;
+INET6_ATON('1.2.3.256') IS NULL
+1
+SELECT INET6_ATON('1.2.3.4.5') IS NULL;
+INET6_ATON('1.2.3.4.5') IS NULL
+1
+SELECT INET6_ATON('0001.2.3.4') IS NULL;
+INET6_ATON('0001.2.3.4') IS NULL
+1
+SELECT INET6_ATON('0x1.2.3.4') IS NULL;
+INET6_ATON('0x1.2.3.4') IS NULL
+1
+SELECT INET6_ATON('a.2.3.4') IS NULL;
+INET6_ATON('a.2.3.4') IS NULL
+1
+SELECT INET6_ATON('1.2.3.4:80') IS NULL;
+INET6_ATON('1.2.3.4:80') IS NULL
+1
+SELECT INET6_ATON('1.2.3.4/32') IS NULL;
+INET6_ATON('1.2.3.4/32') IS NULL
+1
+SELECT INET6_ATON('mysql.com') IS NULL;
+INET6_ATON('mysql.com') IS NULL
+1
+SELECT INET6_ATON(':::') IS NULL;
+INET6_ATON(':::') IS NULL
+1
+SELECT INET6_ATON(':1:2:3') IS NULL;
+INET6_ATON(':1:2:3') IS NULL
+1
+SELECT INET6_ATON('1:2:3:') IS NULL;
+INET6_ATON('1:2:3:') IS NULL
+1
+SELECT INET6_ATON(':1::2:3') IS NULL;
+INET6_ATON(':1::2:3') IS NULL
+1
+SELECT INET6_ATON('1::2:3:') IS NULL;
+INET6_ATON('1::2:3:') IS NULL
+1
+SELECT INET6_ATON('::00001') IS NULL;
+INET6_ATON('::00001') IS NULL
+1
+SELECT INET6_ATON('::00001:2') IS NULL;
+INET6_ATON('::00001:2') IS NULL
+1
+SELECT INET6_ATON('::12345') IS NULL;
+INET6_ATON('::12345') IS NULL
+1
+SELECT INET6_ATON('1020::3040::5060') IS NULL;
+INET6_ATON('1020::3040::5060') IS NULL
+1
+SELECT INET6_ATON('::ABCZ') IS NULL;
+INET6_ATON('::ABCZ') IS NULL
+1
+SELECT INET6_ATON('::0x1.2.3.4') IS NULL;
+INET6_ATON('::0x1.2.3.4') IS NULL
+1
+SELECT INET6_ATON('::1.0x2.3.4') IS NULL;
+INET6_ATON('::1.0x2.3.4') IS NULL
+1
+SELECT INET6_ATON('::a.b.c.d') IS NULL;
+INET6_ATON('::a.b.c.d') IS NULL
+1
+SELECT INET6_ATON('::FFFF:0x1.2.3.4') IS NULL;
+INET6_ATON('::FFFF:0x1.2.3.4') IS NULL
+1
+SELECT INET6_ATON('::FFFF:1.0x2.3.4') IS NULL;
+INET6_ATON('::FFFF:1.0x2.3.4') IS NULL
+1
+SELECT INET6_ATON('::FFFF:a.b.c.d') IS NULL;
+INET6_ATON('::FFFF:a.b.c.d') IS NULL
+1
+SELECT INET6_ATON('::1.2.3.4:ABCD') IS NULL;
+INET6_ATON('::1.2.3.4:ABCD') IS NULL
+1
+# NOTE: such addresses are supported because getaddrinfo() supports them.
+# This is just to record the current behaviour.
+SELECT HEX(INET6_ATON('::ABCD:1.2.3.4'));
+HEX(INET6_ATON('::ABCD:1.2.3.4'))
+00000000000000000000ABCD01020304
+
+# -- INET6_ATON: checking binary representation...
+
+SELECT HEX(INET6_ATON('0.0.0.0'));
+HEX(INET6_ATON('0.0.0.0'))
+00000000
+SELECT HEX(INET6_ATON('00.00.00.00'));
+HEX(INET6_ATON('00.00.00.00'))
+00000000
+SELECT HEX(INET6_ATON('000.000.000.000'));
+HEX(INET6_ATON('000.000.000.000'))
+00000000
+SELECT HEX(INET6_ATON('1.2.3.4'));
+HEX(INET6_ATON('1.2.3.4'))
+01020304
+SELECT HEX(INET6_ATON('01.02.03.04'));
+HEX(INET6_ATON('01.02.03.04'))
+01020304
+SELECT HEX(INET6_ATON('001.002.003.004'));
+HEX(INET6_ATON('001.002.003.004'))
+01020304
+SELECT HEX(INET6_ATON('255.255.255.255'));
+HEX(INET6_ATON('255.255.255.255'))
+FFFFFFFF
+SELECT HEX(INET6_ATON('::'));
+HEX(INET6_ATON('::'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('0::0'));
+HEX(INET6_ATON('0::0'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('1::2'));
+HEX(INET6_ATON('1::2'))
+00010000000000000000000000000002
+SELECT HEX(INET6_ATON('0::'));
+HEX(INET6_ATON('0::'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('1::'));
+HEX(INET6_ATON('1::'))
+00010000000000000000000000000000
+SELECT HEX(INET6_ATON('::0'));
+HEX(INET6_ATON('::0'))
+00000000000000000000000000000000
+SELECT HEX(INET6_ATON('::1'));
+HEX(INET6_ATON('::1'))
+00000000000000000000000000000001
+SELECT HEX(INET6_ATON('1:2:3:4:5:6:7:8'));
+HEX(INET6_ATON('1:2:3:4:5:6:7:8'))
+00010002000300040005000600070008
+SELECT HEX(INET6_ATON('::2:3:4:5:6:7:8'));
+HEX(INET6_ATON('::2:3:4:5:6:7:8'))
+00000002000300040005000600070008
+SELECT HEX(INET6_ATON('1::3:4:5:6:7:8'));
+HEX(INET6_ATON('1::3:4:5:6:7:8'))
+00010000000300040005000600070008
+SELECT HEX(INET6_ATON('1:2::4:5:6:7:8'));
+HEX(INET6_ATON('1:2::4:5:6:7:8'))
+00010002000000040005000600070008
+SELECT HEX(INET6_ATON('1:2:3::5:6:7:8'));
+HEX(INET6_ATON('1:2:3::5:6:7:8'))
+00010002000300000005000600070008
+SELECT HEX(INET6_ATON('1:2:3:4::6:7:8'));
+HEX(INET6_ATON('1:2:3:4::6:7:8'))
+00010002000300040000000600070008
+SELECT HEX(INET6_ATON('1:2:3:4:5::7:8'));
+HEX(INET6_ATON('1:2:3:4:5::7:8'))
+00010002000300040005000000070008
+SELECT HEX(INET6_ATON('1:2:3:4:5:6::8'));
+HEX(INET6_ATON('1:2:3:4:5:6::8'))
+00010002000300040005000600000008
+SELECT HEX(INET6_ATON('1:2:3:4:5:6:7::'));
+HEX(INET6_ATON('1:2:3:4:5:6:7::'))
+00010002000300040005000600070000
+SELECT HEX(INET6_ATON('0000:0000::0000:0001'));
+HEX(INET6_ATON('0000:0000::0000:0001'))
+00000000000000000000000000000001
+SELECT HEX(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed'));
+HEX(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed'))
+123456789ABCDEF043218765CBA90FED
+SELECT HEX(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+HEX(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'))
+00000000000000000000000000000001
+SELECT HEX(INET6_ATON('::C0A8:0102'));
+HEX(INET6_ATON('::C0A8:0102'))
+000000000000000000000000C0A80102
+SELECT HEX(INET6_ATON('::c0a8:0102'));
+HEX(INET6_ATON('::c0a8:0102'))
+000000000000000000000000C0A80102
+SELECT HEX(INET6_ATON('::192.168.1.2'));
+HEX(INET6_ATON('::192.168.1.2'))
+000000000000000000000000C0A80102
+SELECT HEX(INET6_ATON('::FfFf:C0a8:0102'));
+HEX(INET6_ATON('::FfFf:C0a8:0102'))
+00000000000000000000FFFFC0A80102
+SELECT HEX(INET6_ATON('::ffff:c0a8:0102'));
+HEX(INET6_ATON('::ffff:c0a8:0102'))
+00000000000000000000FFFFC0A80102
+SELECT HEX(INET6_ATON('::ffff:192.168.1.2'));
+HEX(INET6_ATON('::ffff:192.168.1.2'))
+00000000000000000000FFFFC0A80102
+SELECT HEX(INET6_ATON('::01.2.3.4'));
+HEX(INET6_ATON('::01.2.3.4'))
+00000000000000000000000001020304
+SELECT HEX(INET6_ATON('::1.02.3.4'));
+HEX(INET6_ATON('::1.02.3.4'))
+00000000000000000000000001020304
+SELECT HEX(INET6_ATON('::1.2.03.4'));
+HEX(INET6_ATON('::1.2.03.4'))
+00000000000000000000000001020304
+SELECT HEX(INET6_ATON('::1.2.3.04'));
+HEX(INET6_ATON('::1.2.3.04'))
+00000000000000000000000001020304
+SELECT HEX(INET6_ATON('::1.2.3.00'));
+HEX(INET6_ATON('::1.2.3.00'))
+00000000000000000000000001020300
+SELECT HEX(INET6_ATON('::FFFF:01.2.3.4'));
+HEX(INET6_ATON('::FFFF:01.2.3.4'))
+00000000000000000000FFFF01020304
+SELECT HEX(INET6_ATON('::FFFF:1.02.3.4'));
+HEX(INET6_ATON('::FFFF:1.02.3.4'))
+00000000000000000000FFFF01020304
+SELECT HEX(INET6_ATON('::FFFF:1.2.03.4'));
+HEX(INET6_ATON('::FFFF:1.2.03.4'))
+00000000000000000000FFFF01020304
+SELECT HEX(INET6_ATON('::FFFF:1.2.3.04'));
+HEX(INET6_ATON('::FFFF:1.2.3.04'))
+00000000000000000000FFFF01020304
+SELECT HEX(INET6_ATON('::FFFF:1.2.3.00'));
+HEX(INET6_ATON('::FFFF:1.2.3.00'))
+00000000000000000000FFFF01020300
+
+# -- INET6_ATON: checking the length is either 4 or 16...
+
+SELECT LENGTH(INET6_ATON('0.0.0.0'));
+LENGTH(INET6_ATON('0.0.0.0'))
+4
+SELECT LENGTH(INET6_ATON('255.255.255.255'));
+LENGTH(INET6_ATON('255.255.255.255'))
+4
+SELECT LENGTH(INET6_ATON('::'));
+LENGTH(INET6_ATON('::'))
+16
+SELECT LENGTH(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+LENGTH(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'))
+16
+
+# -- INET6_NTOA: checking NULL, invalid types, out-of range values...
+
+SELECT INET6_NTOA(NULL);
+INET6_NTOA(NULL)
+NULL
+SELECT INET6_NTOA(123);
+INET6_NTOA(123)
+NULL
+SELECT INET6_NTOA(123.456);
+INET6_NTOA(123.456)
+NULL
+SELECT INET6_NTOA(NOW());
+INET6_NTOA(NOW())
+NULL
+SELECT INET6_NTOA(UNHEX('C0A801'));
+INET6_NTOA(UNHEX('C0A801'))
+NULL
+SELECT INET6_NTOA(UNHEX('C0A80102'));
+INET6_NTOA(UNHEX('C0A80102'))
+192.168.1.2
+SELECT INET6_NTOA(UNHEX('C0A8010203'));
+INET6_NTOA(UNHEX('C0A8010203'))
+NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F'));
+INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F'))
+NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F10'));
+INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F10'))
+102:304:506:708:90a:b0c:d0e:f10
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F1011'));
+INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F1011'))
+NULL
+SELECT INET6_NTOA('1234'), INET6_NTOA(BINARY('1234'));
+INET6_NTOA('1234') INET6_NTOA(BINARY('1234'))
+NULL 49.50.51.52
+SELECT INET6_NTOA('0123456789abcdef'), INET6_NTOA(BINARY('0123456789abcdef'));
+INET6_NTOA('0123456789abcdef') INET6_NTOA(BINARY('0123456789abcdef'))
+NULL 3031:3233:3435:3637:3839:6162:6364:6566
+
+# -- Checking double-conversion...
+
+SELECT INET6_NTOA(INET6_ATON('::'));
+INET6_NTOA(INET6_ATON('::'))
+::
+SELECT INET6_NTOA(INET6_ATON('0::0'));
+INET6_NTOA(INET6_ATON('0::0'))
+::
+SELECT INET6_NTOA(INET6_ATON('1::2'));
+INET6_NTOA(INET6_ATON('1::2'))
+1::2
+SELECT INET6_NTOA(INET6_ATON('0::'));
+INET6_NTOA(INET6_ATON('0::'))
+::
+SELECT INET6_NTOA(INET6_ATON('1::'));
+INET6_NTOA(INET6_ATON('1::'))
+1::
+SELECT INET6_NTOA(INET6_ATON('::0'));
+INET6_NTOA(INET6_ATON('::0'))
+::
+SELECT INET6_NTOA(INET6_ATON('::1'));
+INET6_NTOA(INET6_ATON('::1'))
+::1
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7:8'));
+INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7:8'))
+1:2:3:4:5:6:7:8
+SELECT INET6_NTOA(INET6_ATON('::2:3:4:5:6:7:8'));
+INET6_NTOA(INET6_ATON('::2:3:4:5:6:7:8'))
+::2:3:4:5:6:7:8
+SELECT INET6_NTOA(INET6_ATON('1::3:4:5:6:7:8'));
+INET6_NTOA(INET6_ATON('1::3:4:5:6:7:8'))
+1::3:4:5:6:7:8
+SELECT INET6_NTOA(INET6_ATON('1:2::4:5:6:7:8'));
+INET6_NTOA(INET6_ATON('1:2::4:5:6:7:8'))
+1:2::4:5:6:7:8
+SELECT INET6_NTOA(INET6_ATON('1:2:3::5:6:7:8'));
+INET6_NTOA(INET6_ATON('1:2:3::5:6:7:8'))
+1:2:3::5:6:7:8
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4::6:7:8'));
+INET6_NTOA(INET6_ATON('1:2:3:4::6:7:8'))
+1:2:3:4::6:7:8
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5::7:8'));
+INET6_NTOA(INET6_ATON('1:2:3:4:5::7:8'))
+1:2:3:4:5::7:8
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6::8'));
+INET6_NTOA(INET6_ATON('1:2:3:4:5:6::8'))
+1:2:3:4:5:6::8
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7::'));
+INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7::'))
+1:2:3:4:5:6:7::
+SELECT INET6_NTOA(INET6_ATON('0000:0000::0000:0001'));
+INET6_NTOA(INET6_ATON('0000:0000::0000:0001'))
+::1
+SELECT INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed'));
+INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed'))
+1234:5678:9abc:def0:4321:8765:cba9:fed
+SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'))
+::1
+SELECT INET6_NTOA(INET6_ATON('::C0A8:0102'));
+INET6_NTOA(INET6_ATON('::C0A8:0102'))
+::192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::c0a8:0102'));
+INET6_NTOA(INET6_ATON('::c0a8:0102'))
+::192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::192.168.1.2'));
+INET6_NTOA(INET6_ATON('::192.168.1.2'))
+::192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::FfFf:C0a8:0102'));
+INET6_NTOA(INET6_ATON('::FfFf:C0a8:0102'))
+::ffff:192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::ffff:c0a8:0102'));
+INET6_NTOA(INET6_ATON('::ffff:c0a8:0102'))
+::ffff:192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::ffff:192.168.1.2'));
+INET6_NTOA(INET6_ATON('::ffff:192.168.1.2'))
+::ffff:192.168.1.2
+SELECT INET6_NTOA(INET6_ATON('::01.2.3.4'));
+INET6_NTOA(INET6_ATON('::01.2.3.4'))
+::1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::1.02.3.4'));
+INET6_NTOA(INET6_ATON('::1.02.3.4'))
+::1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::1.2.03.4'));
+INET6_NTOA(INET6_ATON('::1.2.03.4'))
+::1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::1.2.3.04'));
+INET6_NTOA(INET6_ATON('::1.2.3.04'))
+::1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::1.2.3.00'));
+INET6_NTOA(INET6_ATON('::1.2.3.00'))
+::1.2.3.0
+SELECT INET6_NTOA(INET6_ATON('::FFFF:01.2.3.4'));
+INET6_NTOA(INET6_ATON('::FFFF:01.2.3.4'))
+::ffff:1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.02.3.4'));
+INET6_NTOA(INET6_ATON('::FFFF:1.02.3.4'))
+::ffff:1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.2.03.4'));
+INET6_NTOA(INET6_ATON('::FFFF:1.2.03.4'))
+::ffff:1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.2.3.04'));
+INET6_NTOA(INET6_ATON('::FFFF:1.2.3.04'))
+::ffff:1.2.3.4
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.2.3.00'));
+INET6_NTOA(INET6_ATON('::FFFF:1.2.3.00'))
+::ffff:1.2.3.0
+
+# -- Comparing INET_ATON() and INET6_ATON()...
+
+SELECT HEX(INET_ATON('192.168.1.2'));
+HEX(INET_ATON('192.168.1.2'))
+C0A80102
+SELECT HEX(INET6_ATON('192.168.1.2'));
+HEX(INET6_ATON('192.168.1.2'))
+C0A80102
+SELECT HEX(INET_ATON('255.255.255.255'));
+HEX(INET_ATON('255.255.255.255'))
+FFFFFFFF
+SELECT HEX(INET6_ATON('255.255.255.255'));
+HEX(INET6_ATON('255.255.255.255'))
+FFFFFFFF
+SELECT HEX(INET_ATON('192.168.08.2'));
+HEX(INET_ATON('192.168.08.2'))
+C0A80802
+SELECT HEX(INET6_ATON('192.168.08.2'));
+HEX(INET6_ATON('192.168.08.2'))
+C0A80802
+SELECT HEX(INET_ATON('192.168.0x8.2'));
+HEX(INET_ATON('192.168.0x8.2'))
+NULL
+SELECT HEX(INET6_ATON('192.168.0x8.2'));
+HEX(INET6_ATON('192.168.0x8.2'))
+NULL
+SELECT HEX(INET_ATON('1.2.255'));
+HEX(INET_ATON('1.2.255'))
+10200FF
+SELECT HEX(INET6_ATON('1.2.255'));
+HEX(INET6_ATON('1.2.255'))
+NULL
+SELECT HEX(INET_ATON('1.2.256'));
+HEX(INET_ATON('1.2.256'))
+NULL
+SELECT HEX(INET6_ATON('1.2.256'));
+HEX(INET6_ATON('1.2.256'))
+NULL
+SELECT HEX(INET_ATON('1.0002.3.4'));
+HEX(INET_ATON('1.0002.3.4'))
+1020304
+SELECT HEX(INET6_ATON('1.0002.3.4'));
+HEX(INET6_ATON('1.0002.3.4'))
+NULL
+SELECT HEX(INET_ATON('1.2.3.4.5'));
+HEX(INET_ATON('1.2.3.4.5'))
+102030405
+SELECT HEX(INET6_ATON('1.2.3.4.5'));
+HEX(INET6_ATON('1.2.3.4.5'))
+NULL
+
+# -- Checking mix of INET- and INET6- functions...
+
+SELECT HEX(INET6_ATON(INET_NTOA(INET_ATON('1.2.3.4')))) AS x;
+x
+01020304
+
+# -- Checking IS_IPV4() / IS_IPV6()...
+
+SELECT IS_IPV4(NULL);
+IS_IPV4(NULL)
+0
+SELECT IS_IPV4(1);
+IS_IPV4(1)
+0
+SELECT IS_IPV4(1.0);
+IS_IPV4(1.0)
+0
+SELECT IS_IPV4('1.2.3.4');
+IS_IPV4('1.2.3.4')
+1
+SELECT IS_IPV4('001.02.000.255');
+IS_IPV4('001.02.000.255')
+1
+SELECT IS_IPV4('::1.2.0.255');
+IS_IPV4('::1.2.0.255')
+0
+SELECT IS_IPV4('::1');
+IS_IPV4('::1')
+0
+SELECT IS_IPV4(BINARY('1.2.3.4'));
+IS_IPV4(BINARY('1.2.3.4'))
+1
+SELECT IS_IPV6(NULL);
+IS_IPV6(NULL)
+0
+SELECT IS_IPV6(1);
+IS_IPV6(1)
+0
+SELECT IS_IPV6(1.0);
+IS_IPV6(1.0)
+0
+SELECT IS_IPV6('1.2.3.4');
+IS_IPV6('1.2.3.4')
+0
+SELECT IS_IPV6('001.02.000.255');
+IS_IPV6('001.02.000.255')
+0
+SELECT IS_IPV6('::001.02.000.255');
+IS_IPV6('::001.02.000.255')
+1
+SELECT IS_IPV6('::1.2.0.255');
+IS_IPV6('::1.2.0.255')
+1
+SELECT IS_IPV6('::1');
+IS_IPV6('::1')
+1
+SELECT IS_IPV6('0000:0000:0000:0000:0000:0000:0000:0001');
+IS_IPV6('0000:0000:0000:0000:0000:0000:0000:0001')
+1
+SELECT IS_IPV6(BINARY('0000:0000:0000:0000:0000:0000:0000:0001'));
+IS_IPV6(BINARY('0000:0000:0000:0000:0000:0000:0000:0001'))
+1
+
+# -- Checking IS_IPV4_MAPPED() and IS_IPV4_COMPAT()...
+
+SELECT IS_IPV4_MAPPED(INET6_ATON('1.2.3.4')),
+IS_IPV4_COMPAT(INET6_ATON('1.2.3.4'));
+IS_IPV4_MAPPED(INET6_ATON('1.2.3.4')) IS_IPV4_COMPAT(INET6_ATON('1.2.3.4'))
+0 0
+SELECT IS_IPV4_MAPPED(INET6_ATON('::1.2.3.4')),
+IS_IPV4_COMPAT(INET6_ATON('::1.2.3.4'));
+IS_IPV4_MAPPED(INET6_ATON('::1.2.3.4')) IS_IPV4_COMPAT(INET6_ATON('::1.2.3.4'))
+0 1
+SELECT IS_IPV4_MAPPED(INET6_ATON('::FFFF:1.2.3.4')),
+IS_IPV4_COMPAT(INET6_ATON('::FFFF:1.2.3.4'));
+IS_IPV4_MAPPED(INET6_ATON('::FFFF:1.2.3.4')) IS_IPV4_COMPAT(INET6_ATON('::FFFF:1.2.3.4'))
+1 0
+SELECT IS_IPV4_MAPPED(INET6_ATON('::ABCD:1.2.3.4')),
+IS_IPV4_COMPAT(INET6_ATON('::ABCD:1.2.3.4'));
+IS_IPV4_MAPPED(INET6_ATON('::ABCD:1.2.3.4')) IS_IPV4_COMPAT(INET6_ATON('::ABCD:1.2.3.4'))
+0 0
+SELECT IS_IPV4_MAPPED(INET6_ATON('::1')),
+IS_IPV4_COMPAT(INET6_ATON('::1'));
+IS_IPV4_MAPPED(INET6_ATON('::1')) IS_IPV4_COMPAT(INET6_ATON('::1'))
+0 0
+SELECT IS_IPV4_MAPPED(INET6_ATON('::')),
+IS_IPV4_COMPAT(INET6_ATON('::'));
+IS_IPV4_MAPPED(INET6_ATON('::')) IS_IPV4_COMPAT(INET6_ATON('::'))
+0 0
+
+# -- Checking IS_IPV4_COMPAT()...
+
+
+# -- Working with a table...
+
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1(ip INT UNSIGNED);
+CREATE TABLE t2(ip VARBINARY(16));
+
+INSERT INTO t1 VALUES
+(INET_ATON('1.2.3.4')), (INET_ATON('255.255.255.255'));
+SELECT INET_NTOA(ip) FROM t1;
+INET_NTOA(ip)
+1.2.3.4
+255.255.255.255
+
+INSERT INTO t2 SELECT INET6_ATON(INET_NTOA(ip)) FROM t1;
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+INET6_NTOA(ip) HEX(ip) LENGTH(ip)
+1.2.3.4 01020304 4
+255.255.255.255 FFFFFFFF 4
+DELETE FROM t2;
+
+INSERT INTO t2 VALUES
+(INET6_ATON('1.2.3.4')), (INET6_ATON('255.255.255.255')),
+(INET6_ATON('::1.2.3.4')), (INET6_ATON('::ffff:255.255.255.255')),
+(INET6_ATON('::')), (INET6_ATON('::1')),
+(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+INET6_NTOA(ip) HEX(ip) LENGTH(ip)
+1.2.3.4 01020304 4
+255.255.255.255 FFFFFFFF 4
+::1.2.3.4 00000000000000000000000001020304 16
+::ffff:255.255.255.255 00000000000000000000FFFFFFFFFFFF 16
+:: 00000000000000000000000000000000 16
+::1 00000000000000000000000000000001 16
+1020:3040:5060:7080:90a0:b0c0:d0e0:f010 102030405060708090A0B0C0D0E0F010 16
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+# -- Done.
+
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 2f820dfc0a9..e5edabb0130 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2658,6 +2658,17 @@ group_concat( i ) field
NULL NULL
8
drop table t1;
+#
+# Bug#11766684 59851: UNINITIALISED VALUE IN ITEM_FUNC_LIKE::SELECT_OPTIMIZE WITH SUBQUERY AND
+#
+CREATE TABLE t2(a INT, KEY(a));
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t1(b INT, PRIMARY KEY(b));
+INSERT INTO t1 VALUES (0),(254);
+SELECT 1 FROM t2 WHERE a LIKE
+(SELECT EXPORT_SET(1, b, b, b, b) FROM t1 LIMIT 1);
+1
+DROP TABLE t1, t2;
End of 5.1 tests
#
# Start of 5.3 tests
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index cebba082ea4..db68f08cbba 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1091,9 +1091,9 @@ NULL
select isnull(week(now() + 0)), isnull(week(now() + 0.2)),
week(20061108), week(20061108.01), week(20061108085411.000002);
isnull(week(now() + 0)) isnull(week(now() + 0.2)) week(20061108) week(20061108.01) week(20061108085411.000002)
-0 0 45 NULL 45
+0 0 45 45 45
Warnings:
-Warning 1292 Incorrect datetime value: '20061108.01'
+Warning 1292 Truncated incorrect datetime value: '20061108.01'
End of 4.1 tests
select time_format('100:00:00', '%H %k %h %I %l');
time_format('100:00:00', '%H %k %h %I %l')
@@ -1878,9 +1878,15 @@ least(1, f1)
Warnings:
Warning 1292 Incorrect datetime value: '1'
drop table t1;
+SET timestamp=UNIX_TIMESTAMP('2014-04-14 10:10:10');
+select now() > coalesce(time('21:43:24'), date('2010-05-03'));
+now() > coalesce(time('21:43:24'), date('2010-05-03'))
+0
+SET timestamp=UNIX_TIMESTAMP('2014-04-14 22:22:22');
select now() > coalesce(time('21:43:24'), date('2010-05-03'));
now() > coalesce(time('21:43:24'), date('2010-05-03'))
1
+SET timestamp=DEFAULT;
create table t1 (f1 timestamp);
select * from t1 where f1 > f1 and f1 <=> timestampadd(hour, 9 , '2010-01-01 16:55:35');
f1
@@ -1918,15 +1924,20 @@ select cast(f1 AS time) from t1;
cast(f1 AS time)
00:00:00
drop table t1;
+SET timestamp=UNIX_TIMESTAMP('2014-06-01 10:20:30');
select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
greatest(cast("0-0-0" as date), cast("10:20:05" as time))
-0000-00-00
+2014-06-01
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'
+0
+select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01';
+greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01'
1
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6))
-0000-00-00 00:00:00.000000
+2014-06-01 00:00:00.000000
+SET timestamp=DEFAULT;
select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010');
microsecond('12:00:00.123456') microsecond('2009-12-31 23:59:59.000010')
123456 10
@@ -2134,15 +2145,16 @@ DROP TABLE t1;
#
# MDEV-4870 Wrong values of CASE, COALESCE, IFNULL on a combination of different temporal types
#
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
CREATE TABLE t1 (dt2 DATETIME(2), t3 TIME(3), d DATE);
INSERT INTO t1 VALUES ('2001-01-01 00:00:00.12', '00:00:00.567', '2002-01-01');
SELECT CASE WHEN 0 THEN dt2 ELSE t3 END FROM t1;
CASE WHEN 0 THEN dt2 ELSE t3 END
-0000-00-00 00:00:00.567
+2001-01-01 00:00:00.567
CREATE TABLE t2 AS SELECT CASE WHEN 0 THEN dt2 ELSE t3 END FROM t1;
SELECT * FROM t2;
CASE WHEN 0 THEN dt2 ELSE t3 END
-0000-00-00 00:00:00.567
+2001-01-01 00:00:00.567
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
CASE WHEN 0 THEN dt2 ELSE t3 END datetime(3) YES NULL
@@ -2161,7 +2173,7 @@ CONCAT(CASE WHEN 1 THEN d ELSE t3 END)
2002-01-01 00:00:00.000
SELECT CASE WHEN 1 THEN t3 ELSE d END FROM t1;
CASE WHEN 1 THEN t3 ELSE d END
-0000-00-00 00:00:00.567
+2001-01-01 00:00:00.567
SELECT COALESCE(d, t3) FROM t1;
COALESCE(d, t3)
2002-01-01 00:00:00.000
@@ -2181,6 +2193,7 @@ SELECT IFNULL(d, t3), CONCAT(IFNULL(d, t3)) FROM t1;
IFNULL(d, t3) CONCAT(IFNULL(d, t3))
2002-01-01 00:00:00.000 2002-01-01 00:00:00.000
DROP TABLE t1;
+SET timestamp=DEFAULT;
#
# MDEV-4724 Some temporal functions do not preserve microseconds
#
@@ -2483,6 +2496,14 @@ SELECT 1 FROM t1 GROUP BY MONTHNAME(0) WITH ROLLUP;
1
DROP TABLE t1;
#
+# MDEV-6099 Bad results for DATE_ADD(.., INTERVAL 2000000000000000000.0 SECOND)
+#
+SELECT DATE_ADD('2001-01-01 10:20:30',INTERVAL 250000000000.0 SECOND) AS c1, DATE_ADD('2001-01-01 10:20:30',INTERVAL 2000000000000000000.0 SECOND) AS c2;
+c1 c2
+9923-03-10 22:47:10.0 NULL
+Warnings:
+Warning 1292 Truncated incorrect DECIMAL value: '2000000000000000000.0'
+#
# MDEV-4838 Wrong metadata for DATE_ADD('string', INVERVAL)
#
SELECT DATE_ADD('2011-01-02 12:13:14', INTERVAL 1 MINUTE);
@@ -2562,3 +2583,20 @@ Warnings:
Warning 1441 Datetime function: datetime field overflow
Warning 1441 Datetime function: datetime field overflow
DROP TABLE t1;
+#
+# MDEV-6101 Hybrid functions do not add CURRENT_DATE when converting TIME to DATETIME
+#
+SET timestamp=UNIX_TIMESTAMP('2014-04-15 01:02:03');
+SELECT IF(1,TIME'10:20:30',DATE'2001-01-01');
+IF(1,TIME'10:20:30',DATE'2001-01-01')
+2014-04-15 10:20:30
+SELECT IFNULL(TIME'10:20:30',DATE'2001-01-01');
+IFNULL(TIME'10:20:30',DATE'2001-01-01')
+2014-04-15 10:20:30
+SELECT CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END;
+CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END
+2014-04-15 10:20:30
+SELECT COALESCE(TIME'10:20:30',DATE'2001-01-01');
+COALESCE(TIME'10:20:30',DATE'2001-01-01')
+2014-04-15 10:20:30
+SET timestamp=DEFAULT;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 17ff46d2269..0acf6f69323 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -2525,3 +2525,29 @@ DROP USER mysqltest_u1@localhost;
# End of Bug#38347.
+#
+# Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS
+# DATABASE SECURITY
+#
+DROP DATABASE IF EXISTS secret;
+DROP DATABASE IF EXISTS no_such_db;
+CREATE DATABASE secret;
+GRANT USAGE ON *.* TO untrusted@localhost;
+# Connection con1
+SHOW GRANTS;
+Grants for untrusted@localhost
+GRANT USAGE ON *.* TO 'untrusted'@'localhost'
+SHOW DATABASES;
+Database
+information_schema
+test
+# Both statements below should fail with the same error.
+# They used to give different errors, thereby
+# hinting that the secret database exists.
+CREATE PROCEDURE no_such_db.foo() BEGIN END;
+ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'no_such_db'
+CREATE PROCEDURE secret.peek_at_secret() BEGIN END;
+ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'secret'
+# Connection default
+DROP USER untrusted@localhost;
+DROP DATABASE secret;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index d43135359b9..81cdad8c523 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -1358,8 +1358,9 @@ explain select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c = t1.c )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func 1
+2 MATERIALIZED t2 index NULL idx_t2_1 163 NULL 164 Using index
select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c = t1.c )
group by a1,a2,b;
@@ -1384,7 +1385,7 @@ explain select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using index
2 SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
select a1,a2,b,min(c),max(c) from t1
where exists ( select * from t2 where t2.c > 'b1' )
@@ -1410,20 +1411,20 @@ explain select a1,a2,b,c,min(c), max(c) from t1
where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
select a1,a2,b,c,min(c), max(c) from t1
where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' )
group by a1,a2,b;
a1 a2 b c min(c) max(c)
-a a b h112 e112 h112
-a b b p122 m122 p122
-b a b h212 e212 h212
-b b b p222 m222 p222
-c a b h312 e312 h312
-c b b p322 m322 p322
-d a b h412 e412 h412
-d b b p422 m422 p422
+a a b e112 e112 h112
+a b b m122 m122 p122
+b a b e212 e212 h212
+b b b m222 m222 p222
+c a b e312 e312 h312
+c b b m322 m322 p322
+d a b e412 e412 h412
+d b b m422 m422 p422
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='semijoin_with_cache=off';
explain select a1,a2,b,c,min(c), max(c) from t1
@@ -1432,7 +1433,7 @@ where t2.c in (select c from t3 where t3.c > t1.b) and
t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2)
select a1,a2,b,c,min(c), max(c) from t1
@@ -1441,22 +1442,22 @@ where t2.c in (select c from t3 where t3.c > t1.b) and
t2.c > 'b1' )
group by a1,a2,b;
a1 a2 b c min(c) max(c)
-a a a d111 a111 d111
-a a b h112 e112 h112
-a b a l121 i121 l121
-a b b p122 m122 p122
-b a a d211 a211 d211
-b a b h212 e212 h212
-b b a l221 i221 l221
-b b b p222 m222 p222
-c a a d311 a311 d311
-c a b h312 e312 h312
-c b a l321 i321 l321
-c b b p322 m322 p322
-d a a d411 a411 d411
-d a b h412 e412 h412
-d b a l421 i421 l421
-d b b p422 m422 p422
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 p322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 p422
SET optimizer_switch=@save_optimizer_switch;
explain select a1,a2,b,c,min(c), max(c) from t1
where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' )
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index 2c0dc77399f..c907997573a 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -552,9 +552,9 @@ explain select * from t1
where exists (select 1 from t2, t3
where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t3 ALL a,b NULL NULL NULL 1002 Range checked for each record (index map: 0x3)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t3 ALL a,b NULL NULL NULL 1002 Range checked for each record (index map: 0x3); FirstMatch(t1)
select * from t1
where exists (select 1 from t2, t3
where t2.a=t1.a and (t3.a=t2.b or t3.b=t2.b or t3.b=t2.b+1));
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index b0e2898780d..11ef1acc18f 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1130,7 +1130,7 @@ CREATE PROCEDURE p1 ()
BEGIN
SELECT 'foo' FROM DUAL;
END |
-ERROR 42000: Unknown database 'information_schema'
+ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
select ROUTINE_NAME from routines where ROUTINE_SCHEMA='information_schema';
ROUTINE_NAME
grant all on information_schema.* to 'user1'@'localhost';
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index 7ca28c28b1e..53812bfa227 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -5577,8 +5577,8 @@ EXPLAIN
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a;
a a b b c
3 3 30 30 300
@@ -5703,4 +5703,27 @@ select @counter;
2
drop table t1,t2,t3;
set expensive_subquery_limit=default;
+#
+# mdev-6071: EXPLAIN chooses to use join buffer while execution turns it down
+#
+create table t1 (a int);
+insert into t1 values
+(7), (9), (1), (4), (2), (3), (5), (8), (11), (6), (10);
+explain select count(*) from t1, t1 t2 where t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join)
+set join_buffer_space_limit=1024*8;
+select @@join_buffer_space_limit;
+@@join_buffer_space_limit
+8192
+select @@join_buffer_size;
+@@join_buffer_size
+131072
+explain select count(*) from t1, t1 t2 where t1.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 11
+1 SIMPLE t2 ALL NULL NULL NULL NULL 11 Using where
+set join_buffer_space_limit=default;
+drop table t1;
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index 932c1c76027..2d67d24bedd 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -520,3 +520,15 @@ LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug11735141.txt' INTO TABLE t1;
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1;
End of 5.1 tests
+#
+# Bug#11759519 INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS
+#
+SET @old_mode= @@sql_mode;
+CREATE TABLE t1 (fld1 INT);
+SET sql_mode='strict_all_tables';
+# Without fix, load data hangs forever.
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/mysql' REPLACE INTO TABLE t1
+FIELDS TERMINATED BY 't' LINES TERMINATED BY '';
+Got one of the listed errors
+SET @@sql_mode= @old_mode;
+DROP TABLE t1;
diff --git a/mysql-test/r/myisam_explain_non_select_all.result b/mysql-test/r/myisam_explain_non_select_all.result
index 86e3ffbff6c..285a1ca6786 100644
--- a/mysql-test/r/myisam_explain_non_select_all.result
+++ b/mysql-test/r/myisam_explain_non_select_all.result
@@ -1172,12 +1172,12 @@ INSERT INTO t1 (i) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
#
EXPLAIN DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 8 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 5 Using where
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED DELETE FROM t1 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 5 100.00 Using where
# Status of EXPLAIN EXTENDED query
Variable_name Value
FLUSH STATUS;
@@ -1479,12 +1479,12 @@ INSERT INTO t2 (i) SELECT i FROM t1;
#
EXPLAIN DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 Using where
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 Using where
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 100.00 Using where
# Status of EXPLAIN EXTENDED query
Variable_name Value
FLUSH STATUS;
@@ -1606,12 +1606,12 @@ INSERT INTO t2 (i) SELECT i FROM t1;
#
EXPLAIN UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 Using where; Using buffer
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 Using where; Using buffer
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where; Using buffer
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 100.00 Using where; Using buffer
# Status of EXPLAIN EXTENDED query
Variable_name Value
FLUSH STATUS;
@@ -1915,12 +1915,12 @@ INSERT INTO t2 (i) SELECT i FROM t1;
#
EXPLAIN UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 Using where; Using buffer
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 Using where; Using buffer
FLUSH STATUS;
FLUSH TABLES;
EXPLAIN EXTENDED UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 8 100.00 Using where; Using buffer
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 5 100.00 Using where; Using buffer
# Status of EXPLAIN EXTENDED query
Variable_name Value
FLUSH STATUS;
diff --git a/mysql-test/r/myisampack.result b/mysql-test/r/myisampack.result
index a2ce12bffc1..13321695360 100644
--- a/mysql-test/r/myisampack.result
+++ b/mysql-test/r/myisampack.result
@@ -150,6 +150,60 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
+create table `t1` (`id` varchar(15) DEFAULT NULL) ENGINE=MyISAM ROW_FORMAT=FIXED;
+insert into t1 values ('aaa'),('bbb'),('ccc'),('ddd'),('eee');
+insert into t1 (select * from t1);
+insert into t1 (select * from t1);
+insert into t1 (select * from t1);
+insert into t1 (select * from t1);
+checksum table t1;
+Table Checksum
+test.t1 2696656816
+insert into t1 values(NULL);
+checksum table t1;
+Table Checksum
+test.t1 2679879600
+flush table t1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+checksum table t1;
+Table Checksum
+test.t1 2679879600
+alter table t1 checksum=1 row_format=fixed;
+checksum table t1;
+Table Checksum
+test.t1 2679879600
+flush table t1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+checksum table t1;
+Table Checksum
+test.t1 2679879600
+alter table t1 row_format=dynamic checksum=0;
+checksum table t1;
+Table Checksum
+test.t1 2330021136
+flush table t1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+checksum table t1;
+Table Checksum
+test.t1 2330021136
+alter table t1 checksum=1 row_format=dynamic;
+checksum table t1;
+Table Checksum
+test.t1 2330021136
+flush table t1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+checksum table t1;
+Table Checksum
+test.t1 2330021136
+drop table t1;
#
# BUG#11751736: DROP DATABASE STATEMENT SHOULD REMOVE .OLD SUFFIX FROM
# DATABASE DIRECTORY
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index 82f8931e394..eabfa44b24c 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -553,7 +553,6 @@ The following options may be given as the first argument:
record samples
--performance-schema
Enable the performance schema.
- (Defaults to on; use --skip-performance-schema to disable.)
--performance-schema-accounts-size=#
Maximum number of instrumented user@host accounts. Use 0
to disable, -1 for automated sizing.
@@ -683,7 +682,7 @@ The following options may be given as the first argument:
plugins from a given library_file will be loaded.
--plugin-load-add=name
Optional semicolon-separated list of plugins to load.
- This option adds to the list speficied by --plugin-load
+ This option adds to the list specified by --plugin-load
in an incremental way. It can be specified many times,
adding more plugins every time.
--plugin-maturity=name
@@ -756,7 +755,7 @@ The following options may be given as the first argument:
--relay-log-space-limit=#
Maximum space to use for all relay logs
--replicate-annotate-row-events
- Tells the slave to write annotate rows events recieved
+ Tells the slave to write annotate rows events received
from the master to its own binary log. Ignored if
log_slave_updates is not set
--replicate-do-db=name
@@ -1284,10 +1283,10 @@ old-style-user-limits FALSE
optimizer-prune-level 1
optimizer-search-depth 62
optimizer-selectivity-sampling-limit 100
-optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on
+optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
optimizer-use-condition-selectivity 1
-performance-schema TRUE
-performance-schema-accounts-size 10
+performance-schema FALSE
+performance-schema-accounts-size -1
performance-schema-consumer-events-stages-current FALSE
performance-schema-consumer-events-stages-history FALSE
performance-schema-consumer-events-stages-history-long FALSE
@@ -1300,36 +1299,36 @@ performance-schema-consumer-events-waits-history-long FALSE
performance-schema-consumer-global-instrumentation TRUE
performance-schema-consumer-statements-digest TRUE
performance-schema-consumer-thread-instrumentation TRUE
-performance-schema-digests-size 1000
-performance-schema-events-stages-history-long-size 100
-performance-schema-events-stages-history-size 5
-performance-schema-events-statements-history-long-size 100
-performance-schema-events-statements-history-size 5
-performance-schema-events-waits-history-long-size 100
-performance-schema-events-waits-history-size 5
-performance-schema-hosts-size 20
+performance-schema-digests-size -1
+performance-schema-events-stages-history-long-size -1
+performance-schema-events-stages-history-size -1
+performance-schema-events-statements-history-long-size -1
+performance-schema-events-statements-history-size -1
+performance-schema-events-waits-history-long-size -1
+performance-schema-events-waits-history-size -1
+performance-schema-hosts-size -1
performance-schema-instrument
performance-schema-max-cond-classes 80
-performance-schema-max-cond-instances 836
+performance-schema-max-cond-instances -1
performance-schema-max-file-classes 50
performance-schema-max-file-handles 32768
-performance-schema-max-file-instances 1556
+performance-schema-max-file-instances -1
performance-schema-max-mutex-classes 200
-performance-schema-max-mutex-instances 3282
+performance-schema-max-mutex-instances -1
performance-schema-max-rwlock-classes 40
-performance-schema-max-rwlock-instances 1724
+performance-schema-max-rwlock-instances -1
performance-schema-max-socket-classes 10
-performance-schema-max-socket-instances 179
+performance-schema-max-socket-instances -1
performance-schema-max-stage-classes 150
performance-schema-max-statement-classes 180
-performance-schema-max-table-handles 445
-performance-schema-max-table-instances 445
+performance-schema-max-table-handles -1
+performance-schema-max-table-instances -1
performance-schema-max-thread-classes 50
-performance-schema-max-thread-instances 224
-performance-schema-session-connect-attrs-size 512
+performance-schema-max-thread-instances -1
+performance-schema-session-connect-attrs-size -1
performance-schema-setup-actors-size 100
performance-schema-setup-objects-size 100
-performance-schema-users-size 5
+performance-schema-users-size -1
plugin-maturity unknown
port 3306
port-open-timeout 0
diff --git a/mysql-test/r/old-mode.result b/mysql-test/r/old-mode.result
index b7e1ee26391..7f3339e7ce4 100644
--- a/mysql-test/r/old-mode.result
+++ b/mysql-test/r/old-mode.result
@@ -95,8 +95,9 @@ INSERT INTO t1 VALUES (NULL, '00:20:12');
INSERT INTO t1 VALUES (NULL, '-00:20:12');
SELECT IF(1,ADDDATE(IFNULL(a,b),0),1) FROM t1;
IF(1,ADDDATE(IFNULL(a,b),0),1)
-0000-00-00 00:20:12
+NULL
NULL
Warnings:
+Warning 1292 Incorrect datetime value: '0000-00-00 00:20:12'
Warning 1292 Truncated incorrect datetime value: '-00:20:12'
DROP TABLE t1;
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index a8e5cbb295c..294142737d9 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -2936,3 +2936,16 @@ where A.b = B.b
order by A.col2, B.col2 limit 10, 1000000;
drop table t1,t2,t3;
End of 5.5 tests
+#
+# MDEV-5884: EXPLAIN UPDATE ... ORDER BY LIMIT shows wrong #rows
+#
+create table t2(a int);
+insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (key1 int, col1 int, key(key1));
+insert into t1
+select A.a + 10 * B.a + 100 * C.a, 1234 from t2 A, t2 B, t2 C;
+# Should show rows=2, not rows=100
+explain update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range key1 key1 5 NULL 2 Using where; Using buffer
+drop table t1,t2;
diff --git a/mysql-test/r/outfile_loaddata.result b/mysql-test/r/outfile_loaddata.result
index e91855b8dcd..ca3a42c087c 100644
--- a/mysql-test/r/outfile_loaddata.result
+++ b/mysql-test/r/outfile_loaddata.result
@@ -147,6 +147,14 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
a b c
1 ABC-ÐБВ DEF-ÂÃÄ
2 NULL NULL
+SELECT * FROM t1;
+a b c
+1 ABC-ÐБВ DEF-ÂÃÄ
+2 NULL NULL
+SELECT * FROM t2;
+a b c
+1 ABC-ÐБВ DEF-ÂÃÄ
+2 NULL NULL
SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ÑŠ';
Warnings:
Warning 1638 Non-ASCII separator arguments are not fully supported
@@ -175,6 +183,14 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
a b c
1 ABC-ÐБВ DEF-ÂÃÄ
2 NULL NULL
+SELECT * FROM t1;
+a b c
+1 ABC-ÐБВ DEF-ÂÃÄ
+2 NULL NULL
+SELECT * FROM t2;
+a b c
+1 ABC-ÐБВ DEF-ÂÃÄ
+2 NULL NULL
# Default (binary) charset:
SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FROM t1;
##################################################
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index ec7fd798d4c..0a4cf9932c0 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -3301,3 +3301,55 @@ explain partitions select * from t1 where a between 10 and 10+33;
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p0,p1,p2 ALL NULL NULL NULL NULL 100 Using where
drop table t0, t1;
+#
+# MDEV-6239: Partition pruning is not working as expected in an inner query
+#
+create table t1
+(
+company_id bigint(5),
+dept_id bigint(5),
+emp_id bigint(5),
+emp_name varchar(100),
+primary key (company_id, emp_id)
+) partition by list (company_id) (
+partition p_1000 values in (1000),
+partition p_2000 values in (2000),
+partition p_3000 values in (3000)
+);
+create table t2
+(
+company_id bigint(5),
+dept_id bigint(5),
+dept_name varchar(100),
+primary key (company_id, dept_id)
+) partition by list (company_id) (
+partition p_1000 values in (1000),
+partition p_2000 values in (2000),
+partition p_3000 values in (3000)
+);
+insert into t2 values
+(1000, 10, 'Engineering'),
+(1000, 20, 'Product Management'),
+(1000, 30, 'QA'),
+(2000, 40, 'Support'),
+(2000, 50, 'Professional Services');
+insert into t1 values
+(1000, 10, 1, 'John'),
+(1000, 10, 2, 'Smith'),
+(1000, 20, 3, 'Jacob'),
+(1000, 20, 4, 'Brian'),
+(1000, 30, 5, 'Chris'),
+(1000, 30, 6, 'Ryan'),
+(2000, 40, 7, 'Karin'),
+(2000, 40, 8, 'Jay'),
+(2000, 50, 9, 'Ana'),
+(2000, 50, 10, 'Jessica');
+# Table t2 should have only partition p_1000.
+explain partitions
+select * from t1
+where company_id = 1000
+and dept_id in (select dept_id from t2 where COMPANY_ID = 1000);
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 p_1000 ref PRIMARY PRIMARY 8 const 2 Using index
+1 PRIMARY t1 p_1000 ALL PRIMARY NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
+drop table t1,t2;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index ec680b112a3..31fcea528aa 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -613,8 +613,8 @@ insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
("4", "1", "sup", "0");
create table t3 (
id int(11) not null default '0',
-preceeding_id int(11) not null default '0',
-primary key (id,preceeding_id)
+preceding_id int(11) not null default '0',
+primary key (id,preceding_id)
);
create table t4 (
user_id varchar(50) not null,
@@ -625,7 +625,7 @@ insert into t4 values("nicke", "imp");
prepare stmt from
'select distinct t1.partner_id
from t1 left join t3 on t1.id = t3.id
- left join t1 pp on pp.id = t3.preceeding_id
+ left join t1 pp on pp.id = t3.preceding_id
where
exists (
select *
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 1c3c2de764b..6ca76191db5 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -3256,7 +3256,7 @@ values
( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3264,7 +3264,7 @@ values
( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt1 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3273,7 +3273,7 @@ values
execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt2 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3282,7 +3282,7 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
set @arg00= 'abc' ;
set @arg00= NULL ;
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 8b4b6daa108..47237790ae5 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -3239,7 +3239,7 @@ values
( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3247,7 +3247,7 @@ values
( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt1 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3256,7 +3256,7 @@ values
execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt2 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3265,7 +3265,7 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
set @arg00= 'abc' ;
set @arg00= NULL ;
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index 0ea54a45afa..57532797dd7 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -3240,7 +3240,7 @@ values
( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3248,7 +3248,7 @@ values
( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt1 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3257,7 +3257,7 @@ values
execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt2 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3266,7 +3266,7 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
set @arg00= 'abc' ;
set @arg00= NULL ;
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 2fc9475e926..9a9f457a212 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -3176,7 +3176,7 @@ values
( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3184,7 +3184,7 @@ values
( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt1 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3193,7 +3193,7 @@ values
execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt2 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3202,7 +3202,7 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
set @arg00= 'abc' ;
set @arg00= NULL ;
@@ -6530,7 +6530,7 @@ values
( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -6538,7 +6538,7 @@ values
( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt1 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -6547,7 +6547,7 @@ values
execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt2 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -6556,7 +6556,7 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
set @arg00= 'abc' ;
set @arg00= NULL ;
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 01be3cbfe2c..f2ad42ebc8d 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -2047,6 +2047,60 @@ f1 f2 f3 f4
DROP TABLE t1;
DROP VIEW v3;
#
+# MDEV-6105: Emoji unicode character string search query makes mariadb performance down
+#
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 'test.t1'
+CREATE TABLE t1(
+id int AUTO_INCREMENT,
+fd varchar(20),
+primary key(id),
+index ix_fd(fd)
+)engine=innodb default charset=UTF8;
+INSERT INTO t1(id, fd) VALUES (null, ''),(null, 'matt'),(null, 'pitt'),(null, 'lee'),(null, 'kim');
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+# The following should show "Impossible WHERE" :
+explain
+SELECT * FROM t1 WHERE fd='ðŸ˜';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+SELECT * FROM t1 WHERE fd='ðŸ˜';
+id fd
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+# The following must not use range access:
+explain select count(*) from t1 where fd <'ðŸ˜';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index ix_fd ix_fd 63 NULL # Using where; Using index
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+select count(*) from t1 where fd <'ðŸ˜';
+count(*)
+40960
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+select count(*) from t1 ignore index (ix_fd) where fd <'ðŸ˜';
+count(*)
+40960
+drop table t1;
+set names default;
+#
# BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
#
CREATE TABLE t1 (pk INT PRIMARY KEY);
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
index dc6bed5fd98..16b35448c50 100644
--- a/mysql-test/r/range_mrr_icp.result
+++ b/mysql-test/r/range_mrr_icp.result
@@ -2049,6 +2049,60 @@ f1 f2 f3 f4
DROP TABLE t1;
DROP VIEW v3;
#
+# MDEV-6105: Emoji unicode character string search query makes mariadb performance down
+#
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 'test.t1'
+CREATE TABLE t1(
+id int AUTO_INCREMENT,
+fd varchar(20),
+primary key(id),
+index ix_fd(fd)
+)engine=innodb default charset=UTF8;
+INSERT INTO t1(id, fd) VALUES (null, ''),(null, 'matt'),(null, 'pitt'),(null, 'lee'),(null, 'kim');
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+# The following should show "Impossible WHERE" :
+explain
+SELECT * FROM t1 WHERE fd='ðŸ˜';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+SELECT * FROM t1 WHERE fd='ðŸ˜';
+id fd
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+# The following must not use range access:
+explain select count(*) from t1 where fd <'ðŸ˜';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index ix_fd ix_fd 63 NULL # Using where; Using index
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+select count(*) from t1 where fd <'ðŸ˜';
+count(*)
+40960
+Warnings:
+Warning 1366 Incorrect string value: '\xF0\x9F\x98\x81' for column 'fd' at row 1
+select count(*) from t1 ignore index (ix_fd) where fd <'ðŸ˜';
+count(*)
+40960
+drop table t1;
+set names default;
+#
# BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
#
CREATE TABLE t1 (pk INT PRIMARY KEY);
diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result
index 07c7b7939af..04eb2c90d31 100644
--- a/mysql-test/r/select_found.result
+++ b/mysql-test/r/select_found.result
@@ -291,11 +291,7 @@ select found_rows();
found_rows()
1
drop table t1, t2;
-create table t1 (
-a1 int auto_increment primary key,
-b1 datetime,
-c1 int
-);
+create table t1 (a1 int auto_increment primary key, c1 int);
insert t1 (a1) values (null);
insert t1 (a1) select null from t1;
insert t1 (a1) select null from t1;
@@ -307,20 +303,32 @@ insert t1 (a1) select null from t1;
insert t1 (a1) select null from t1;
insert t1 (a1) select null from t1;
update t1 set c1=a1 % 2;
-create table t2 (
-a2 int,
-b2 int,
-c2 char(16) default '',
-primary key (a2, b2)
-);
+create table t2 (a2 int, b2 int, c2 char(16) default '', primary key (a2, b2));
insert t2 select a1, 1, 'ok' from t1;
insert t2 select a1, 2, 'ko' from t1;
insert t2 select a1, 3, 'ko' from t1;
insert t2 select a1, 4, 'ok' from t1;
insert t2 select a1, 5, 'ok' from t1;
-select sql_calc_found_rows distinct a1,b1,c2 from t1 join t2 on a2=a1
-where a1 <= 256 and c1=0 and c2='ok' order by b1 desc, a1 desc limit 46;
+select sql_calc_found_rows distinct a1,c2 from t1 join t2 on a2=a1
+where a1 <= 256 and c1=0 and c2='ok' order by a1 desc limit 46;
select found_rows();
found_rows()
128
drop table t1, t2;
+create table t1 (i1 int, v1 int, primary key(i1,v1));
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 (i2 int primary key, v2 int);
+insert into t2 values (1,5),(2,5),(3,10);
+select 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 or v1 = 5 or v1 = 10 order by v1;
+res
+1
+1
+select sql_calc_found_rows 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 or v1 = 5 or v1 = 10 order by v1 limit 1;
+select found_rows() as count;
+count
+2
+select sql_calc_found_rows 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 order by v1 limit 1;
+select found_rows() as count;
+count
+2
+drop table t1, t2;
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result
index b276ebb709c..9899b894ff6 100644
--- a/mysql-test/r/selectivity.result
+++ b/mysql-test/r/selectivity.result
@@ -400,7 +400,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 SUBQUERY customer ALL NULL NULL NULL NULL 150 100.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2
-Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
+Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(<in_optimizer>(1,exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`)))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal
from (
select substr(c_phone, 1, 2) as cntrycode, c_acctbal
@@ -441,7 +441,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 SUBQUERY customer ALL NULL NULL NULL NULL 150 91.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2
-Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
+Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(<in_optimizer>(1,exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`)))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal
from (
select substr(c_phone, 1, 2) as cntrycode, c_acctbal
@@ -985,7 +985,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 14 100.00 Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((exists(select 1 from `test`.`t1` join `test`.`t2`) and (`test`.`t1`.`a` <> `test`.`t2`.`b`)) or (`test`.`t1`.`a` <= 4))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((<cache>(<in_optimizer>(1,exists(select 1 from `test`.`t1` join `test`.`t2`))) and (`test`.`t1`.`a` <> `test`.`t2`.`b`)) or (`test`.`t1`.`a` <= 4))
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result
index 399e12560ac..90f6dba83f1 100644
--- a/mysql-test/r/selectivity_innodb.result
+++ b/mysql-test/r/selectivity_innodb.result
@@ -403,7 +403,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 SUBQUERY customer ALL NULL NULL NULL NULL 150 100.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2
-Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
+Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(<in_optimizer>(1,exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`)))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal
from (
select substr(c_phone, 1, 2) as cntrycode, c_acctbal
@@ -444,7 +444,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 SUBQUERY customer ALL NULL NULL NULL NULL 150 91.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2
-Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
+Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(<in_optimizer>(1,exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`)))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2)
select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal
from (
select substr(c_phone, 1, 2) as cntrycode, c_acctbal
@@ -995,7 +995,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00
2 SUBQUERY t1 ALL NULL NULL NULL NULL 14 100.00 Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((exists(select 1 from `test`.`t1` join `test`.`t2`) and (`test`.`t1`.`a` <> `test`.`t2`.`b`)) or (`test`.`t1`.`a` <= 4))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where ((<cache>(<in_optimizer>(1,exists(select 1 from `test`.`t1` join `test`.`t2`))) and (`test`.`t1`.`a` <> `test`.`t2`.`b`)) or (`test`.`t1`.`a` <= 4))
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables;
diff --git a/mysql-test/r/selectivity_no_engine.result b/mysql-test/r/selectivity_no_engine.result
index da39ec1b3b4..a14832f9c0a 100644
--- a/mysql-test/r/selectivity_no_engine.result
+++ b/mysql-test/r/selectivity_no_engine.result
@@ -23,9 +23,9 @@ create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (col1 int);
# one value in 1..100 range
-insert into t2 select A.a + B.a*10 from t1 A, t1 B;
+insert into t2 select ta.a + tb.a*10 from t1 ta, t1 tb;
# ten values in 100...200 range
-insert into t2 select 100 + A.a + B.a*10 from t1 A, t1 B, t1 C;
+insert into t2 select 100 + ta.a + tb.a*10 from t1 ta, t1 tb, t1 tc;
set histogram_type='SINGLE_PREC_HB';
set histogram_size=100;
set optimizer_use_condition_selectivity=4;
@@ -51,7 +51,7 @@ drop table t1, t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(a int);
-insert into t1 select A.a from t0 A, t0 B, t0 C;
+insert into t1 select ta.a from t0 ta, t0 tb, t0 tc;
set histogram_size=20;
set histogram_type='single_prec_hb';
analyze table t1 persistent for all;
@@ -90,8 +90,8 @@ drop table t0, t1;
#
create table t1 (col1 int);
set @a=-1;
-create table t2 (a int) select (@a:=@a+1) as a from information_schema.session_variables A limit 100;
-insert into t1 select A.a from t2 A, t2 B where A.a < 100 and B.a < 100;
+create table t2 (a int) select (@a:=@a+1) as a from information_schema.session_variables ta limit 100;
+insert into t1 select ta.a from t2 ta, t2 tb where ta.a < 100 and tb.a < 100;
select min(col1), max(col1), count(*) from t1;
min(col1) max(col1) count(*)
0 99 10000
@@ -123,7 +123,7 @@ drop table t1, t2;
create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, b int, col1 varchar(64), col2 varchar(64), key(a,b));
-insert into t2 select A.a+10*B.a, C.a+10*D.a, 'filler-data1', 'filler-data2' from t1 A, t1 B, t1 C, t1 D;
+insert into t2 select ta.a+10*tb.a, tc.a+10*td.a, 'filler-data1', 'filler-data2' from t1 ta, t1 tb, t1 tc, t1 td;
set histogram_size=100;
set optimizer_use_condition_selectivity=4;
set use_stat_tables='preferably';
@@ -144,7 +144,7 @@ drop table t2, t1;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(key1 int, col1 int, key(key1));
-insert into t1 select A.a, A.a from t0 A, t0 B, t0 C;
+insert into t1 select ta.a, ta.a from t0 ta, t0 tb, t0 tc;
set histogram_size=100;
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=4;
@@ -177,11 +177,11 @@ key(kp1, kp2)
);
insert into t1
select
-A.a,
-B.a,
+ta.a,
+tb.a,
'filler-data-1',
'filler-data-2'
-from t0 A, t0 B, t0 C;
+from t0 ta, t0 tb, t0 tc;
set histogram_size=100;
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=4;
@@ -215,6 +215,68 @@ SELECT * FROM t1 AS t1_1, t1 AS t1_2 WHERE NOT ( t1_1.a <> 'baz');
a b a b
DROP TABLE t1;
#
+# MDEV-6308: Server crashes in table_multi_eq_cond_selectivity with ...
+#
+CREATE TABLE t1 (
+id varchar(40) COLLATE utf8_bin,
+dt datetime,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES ('foo','2011-04-12 05:18:08'),
+('bar','2013-09-19 11:37:03');
+CREATE TABLE t2 (
+t1_id varchar(40) COLLATE utf8_bin,
+f1 varchar(64),
+f2 varchar(1024),
+KEY (f1,f2(255))
+);
+INSERT INTO t2 VALUES ('foo','baz','qux'),('bar','baz','qux');
+set optimizer_use_condition_selectivity=2;
+explain
+select * from t1,t2 where t1.id = t2.t1_id and t2.f2='qux' and t2.f1='baz';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref f1 f1 325 const,const 1 Using index condition; Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 122 test.t2.t1_id 1
+select * from t1,t2 where t1.id = t2.t1_id and t2.f2='qux' and t2.f1='baz';
+id dt t1_id f1 f2
+foo 2011-04-12 05:18:08 foo baz qux
+bar 2013-09-19 11:37:03 bar baz qux
+drop table t1,t2;
+#
+# MDEV-5985: EITS: selectivity estimates look illogical for join and non-key equalities
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select ta.a + tb.a* 10 + tc.a * 100 from t0 ta, t0 tb, t0 tc;
+create table t2 as select * from t1;
+set histogram_size=100;
+set use_stat_tables='preferably';
+set optimizer_use_condition_selectivity=4;
+analyze table t1 persistent for all;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+analyze table t2 persistent for all;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+# Filtered will be 4.95, 9.90
+explain extended select * from t1 ta, t2 tb where ta.a < 40 and tb.a < 100;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE ta ALL NULL NULL NULL NULL 1000 4.95 Using where
+1 SIMPLE tb ALL NULL NULL NULL NULL 1000 9.90 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`ta`.`a` AS `a`,`test`.`tb`.`a` AS `a` from `test`.`t1` `ta` join `test`.`t2` `tb` where ((`test`.`ta`.`a` < 40) and (`test`.`tb`.`a` < 100))
+# Here, tb.filtered should not become 100%:
+explain extended select * from t1 ta, t2 tb where ta.a < 40 and tb.a < 100 and tb.a=ta.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE ta ALL NULL NULL NULL NULL 1000 4.95 Using where
+1 SIMPLE tb ALL NULL NULL NULL NULL 1000 4.95 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`ta`.`a` AS `a`,`test`.`tb`.`a` AS `a` from `test`.`t1` `ta` join `test`.`t2` `tb` where ((`test`.`tb`.`a` = `test`.`ta`.`a`) and (`test`.`ta`.`a` < 40) and (`test`.`ta`.`a` < 100))
+drop table t0,t1,t2;
+#
# End of the test file
#
set use_stat_tables= @save_use_stat_tables;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index c1c35e0e3ec..5678a455234 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -337,11 +337,11 @@ patient_uq clinic_uq
2 2
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
-2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index
+1 PRIMARY t6 ALL i1 NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where (`test`.`t6`.`clinic_uq` = `test`.`t7`.`uq`)
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -1887,7 +1887,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<in_optimizer>(1,<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2419,11 +2419,12 @@ a b
3 4
explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <expr_cache><`test`.`up`.`a`>(exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`)))
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where 1
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -4428,11 +4429,12 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where 1
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -5670,8 +5672,9 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
a
@@ -5680,8 +5683,9 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index
DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result
index 47cb8bca734..7616dd429b7 100644
--- a/mysql-test/r/subselect_extra.result
+++ b/mysql-test/r/subselect_extra.result
@@ -227,7 +227,7 @@ where t2.c in (select c from t3 where t3.c > t1.b) and
t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2); Using join buffer (flat, BNL join)
select a1,a2,b,c,min(c), max(c) from t1
@@ -236,22 +236,22 @@ where t2.c in (select c from t3 where t3.c > t1.b) and
t2.c > 'b1' )
group by a1,a2,b;
a1 a2 b c min(c) max(c)
-a a a d111 a111 d111
-a a b h112 e112 h112
-a b a l121 i121 l121
-a b b p122 m122 p122
-b a a d211 a211 d211
-b a b h212 e212 h212
-b b a l221 i221 l221
-b b b p222 m222 p222
-c a a d311 a311 d311
-c a b h312 e312 h312
-c b a l321 i321 l321
-c b b p322 m322 p322
-d a a d411 a411 d411
-d a b h412 e412 h412
-d b a l421 i421 l421
-d b b p422 m422 p422
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 p322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 p422
explain select a1,a2,b,c,min(c), max(c) from t1
where exists ( select * from t2
where t2.c in (select c from t3 where t3.c > t1.c) and
diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result
index ba001c71e3f..d178e45d07e 100644
--- a/mysql-test/r/subselect_extra_no_semijoin.result
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -231,7 +231,7 @@ where t2.c in (select c from t3 where t3.c > t1.b) and
t2.c > 'b1' )
group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
3 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index
select a1,a2,b,c,min(c), max(c) from t1
@@ -240,22 +240,22 @@ where t2.c in (select c from t3 where t3.c > t1.b) and
t2.c > 'b1' )
group by a1,a2,b;
a1 a2 b c min(c) max(c)
-a a a d111 a111 d111
-a a b h112 e112 h112
-a b a l121 i121 l121
-a b b p122 m122 p122
-b a a d211 a211 d211
-b a b h212 e212 h212
-b b a l221 i221 l221
-b b b p222 m222 p222
-c a a d311 a311 d311
-c a b h312 e312 h312
-c b a l321 i321 l321
-c b b p322 m322 p322
-d a a d411 a411 d411
-d a b h412 e412 h412
-d b a l421 i421 l421
-d b b p422 m422 p422
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 p322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 p422
explain select a1,a2,b,c,min(c), max(c) from t1
where exists ( select * from t2
where t2.c in (select c from t3 where t3.c > t1.c) and
diff --git a/mysql-test/r/subselect_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index 641cfc29e84..5434bb920e3 100644
--- a/mysql-test/r/subselect_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -1,7 +1,7 @@
-select @@optimizer_switch like '%exists_to_in=on%';
-@@optimizer_switch like '%exists_to_in=on%'
+select @@optimizer_switch like '%exists_to_in=off%';
+@@optimizer_switch like '%exists_to_in=off%'
0
-set optimizer_switch='exists_to_in=on';
+set optimizer_switch='exists_to_in=off';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
drop view if exists v2;
set @subselect_tmp=@@optimizer_switch;
@@ -341,11 +341,11 @@ patient_uq clinic_uq
2 2
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index
-1 PRIMARY t6 ALL i1 NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where (`test`.`t6`.`clinic_uq` = `test`.`t7`.`uq`)
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)))
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -1891,7 +1891,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<in_optimizer>(1,<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2423,12 +2423,11 @@ a b
3 4
explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
-2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where 1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <expr_cache><`test`.`up`.`a`>(exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`)))
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -4433,12 +4432,11 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
-2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where 1
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -5676,9 +5674,8 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
-2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
a
@@ -5687,9 +5684,8 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
-2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
@@ -7024,6 +7020,6 @@ exists(select 1 from t1 group by `c` in (select `c` from t1))
0
drop table t1;
set optimizer_switch=default;
-select @@optimizer_switch like '%exists_to_in=on%';
-@@optimizer_switch like '%exists_to_in=on%'
+select @@optimizer_switch like '%exists_to_in=off%';
+@@optimizer_switch like '%exists_to_in=off%'
0
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index d59f6f3524d..3325889e1e0 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -344,11 +344,11 @@ patient_uq clinic_uq
2 2
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
-2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index
+1 PRIMARY t6 ALL i1 NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where (`test`.`t6`.`clinic_uq` = `test`.`t7`.`uq`)
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -1894,7 +1894,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<in_optimizer>(1,<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2426,11 +2426,11 @@ a b
3 4
explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(up); Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <expr_cache><`test`.`up`.`a`>(exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`)))
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`up`.`a`)
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -4432,11 +4432,11 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where (`test`.`t2`.`a` = `test`.`t1`.`a`)
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -5671,8 +5671,8 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
a
@@ -5681,8 +5681,8 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+1 PRIMARY t2 index idx idx 5 NULL 3 Using index; LooseScan
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index df18343c6d6..01af3ea4b16 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -341,10 +341,10 @@ patient_uq clinic_uq
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
-2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+2 DEPENDENT SUBQUERY t7 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <in_optimizer>(`test`.`t6`.`clinic_uq`,<exists>(<primary_index_lookup>(<cache>(`test`.`t6`.`clinic_uq`) in t7 on PRIMARY)))
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -1890,7 +1890,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<in_optimizer>(1,exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2426,7 +2426,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <in_optimizer>(`test`.`up`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` where (<cache>(`test`.`up`.`a`) = `test`.`t1`.`a`)))
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -4432,7 +4432,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+Note 1003 select 2 AS `2` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` where (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`)))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -5678,7 +5678,7 @@ SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery idx idx 5 func 2 Using index
DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index e36994e0534..16ebf7a4199 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -343,11 +343,11 @@ patient_uq clinic_uq
2 2
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
-2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+1 PRIMARY t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index
+1 PRIMARY t6 ALL i1 NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t7` join `test`.`t6` where (`test`.`t6`.`clinic_uq` = `test`.`t7`.`uq`)
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -1893,7 +1893,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<in_optimizer>(1,exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2425,11 +2425,12 @@ a b
3 4
explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` semi join (`test`.`t1`) where 1
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -4434,11 +4435,12 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+Note 1003 select 2 AS `2` from `test`.`t1` semi join (`test`.`t2`) where 1
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -5676,8 +5678,9 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
a
@@ -5686,8 +5689,9 @@ EXPLAIN
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index
DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 69922a5fe5f..d98f7ad67de 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -341,10 +341,10 @@ patient_uq clinic_uq
explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
-2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+2 MATERIALIZED t7 index PRIMARY PRIMARY 4 NULL 2 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(<in_optimizer>(`test`.`t6`.`clinic_uq`,`test`.`t6`.`clinic_uq` in ( <materialize> (select `test`.`t7`.`uq` from `test`.`t7` where 1 ), <primary_index_lookup>(`test`.`t6`.`clinic_uq` in <temporary table> on distinct_key where ((`test`.`t6`.`clinic_uq` = `<subquery2>`.`uq`))))))
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -1890,7 +1890,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<in_optimizer>(1,<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2423,10 +2423,10 @@ a b
explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <expr_cache><`test`.`up`.`a`>(exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`)))
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <expr_cache><`test`.`up`.`a`>(<in_optimizer>(`test`.`up`.`a`,`test`.`up`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where 1 ), <primary_index_lookup>(`test`.`up`.`a` in <temporary table> on distinct_key where ((`test`.`up`.`a` = `<subquery2>`.`a`))))))
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -4429,10 +4429,10 @@ EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`a` from `test`.`t2` where 1 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`a`))))))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -5668,7 +5668,7 @@ SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3
SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
a
@@ -5678,7 +5678,7 @@ SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
-2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+2 MATERIALIZED t2 index idx idx 5 NULL 3 Using index
DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index c76d40d1a5f..2bb00835a75 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -94,6 +94,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t1`.`A`,`test`.`t1`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t1`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t1`.`A` = `<suBquery2>`.`pk`))))))) where 1
+set join_buffer_size=8*1024;
we shouldn't flatten if we're going to get a join of > MAX_TABLES.
explain select * from
t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -185,6 +186,7 @@ a b a b
0 0 0 0
1 1 1 1
2 2 2 2
+set join_buffer_size=default;
prepare s1 from
' select * from
t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
@@ -1007,8 +1009,8 @@ insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
("4", "1", "sup", "0");
create table t3 (
id int(11) not null default '0',
-preceeding_id int(11) not null default '0',
-primary key (id,preceeding_id)
+preceding_id int(11) not null default '0',
+primary key (id,preceding_id)
);
create table t4 (
user_id varchar(50) not null,
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
index 2975176c64a..43ba6ead575 100644
--- a/mysql-test/r/subselect_sj2.result
+++ b/mysql-test/r/subselect_sj2.result
@@ -1148,5 +1148,35 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t4 index NULL PRIMARY 59 NULL 2 Using where; Using index; End temporary
DROP TABLE t1,t2,t3,t4;
+#
+# MDEV-6263: Wrong result when using IN subquery with order by
+#
+CREATE TABLE t1 (
+id int(11) NOT NULL,
+nombre varchar(255) NOT NULL,
+PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 (id, nombre) VALUES
+(1, 'row 1'),(2, 'row 2'),(3, 'row 3'),
+(4, 'row 4'),(5, 'row 5'),(6, 'row 6');
+CREATE TABLE t2 (
+id_algo int(11) NOT NULL,
+id_agente int(11) NOT NULL,
+PRIMARY KEY (id_algo,id_agente),
+KEY another_data (id_agente)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 (id_algo, id_agente) VALUES
+(1, 1),(1, 2),(2, 1),(2, 2),(2, 3),(3, 1);
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2) ORDER BY nombre ASC;
+id nombre
+1 row 1
+2 row 2
+3 row 3
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2);
+id nombre
+1 row 1
+2 row 2
+3 row 3
+DROP TABLE t1, t2;
# This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
index ff97882c469..c45ab02a646 100644
--- a/mysql-test/r/subselect_sj2_jcl6.result
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -1163,6 +1163,36 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY t4 hash_index NULL #hash#$hj:PRIMARY 55:59 test.t3.t3_c 2 Using where; End temporary; Using join buffer (incremental, BNLH join)
DROP TABLE t1,t2,t3,t4;
+#
+# MDEV-6263: Wrong result when using IN subquery with order by
+#
+CREATE TABLE t1 (
+id int(11) NOT NULL,
+nombre varchar(255) NOT NULL,
+PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 (id, nombre) VALUES
+(1, 'row 1'),(2, 'row 2'),(3, 'row 3'),
+(4, 'row 4'),(5, 'row 5'),(6, 'row 6');
+CREATE TABLE t2 (
+id_algo int(11) NOT NULL,
+id_agente int(11) NOT NULL,
+PRIMARY KEY (id_algo,id_agente),
+KEY another_data (id_agente)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 (id_algo, id_agente) VALUES
+(1, 1),(1, 2),(2, 1),(2, 2),(2, 3),(3, 1);
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2) ORDER BY nombre ASC;
+id nombre
+1 row 1
+2 row 2
+3 row 3
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2);
+id nombre
+1 row 1
+2 row 2
+3 row 3
+DROP TABLE t1, t2;
# This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;
#
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index f4d7d986a9d..0ff366b0d7a 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -1150,6 +1150,36 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t4 index NULL PRIMARY 59 NULL 2 Using where; Using index; End temporary
DROP TABLE t1,t2,t3,t4;
+#
+# MDEV-6263: Wrong result when using IN subquery with order by
+#
+CREATE TABLE t1 (
+id int(11) NOT NULL,
+nombre varchar(255) NOT NULL,
+PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 (id, nombre) VALUES
+(1, 'row 1'),(2, 'row 2'),(3, 'row 3'),
+(4, 'row 4'),(5, 'row 5'),(6, 'row 6');
+CREATE TABLE t2 (
+id_algo int(11) NOT NULL,
+id_agente int(11) NOT NULL,
+PRIMARY KEY (id_algo,id_agente),
+KEY another_data (id_agente)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 (id_algo, id_agente) VALUES
+(1, 1),(1, 2),(2, 1),(2, 2),(2, 3),(3, 1);
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2) ORDER BY nombre ASC;
+id nombre
+1 row 1
+2 row 2
+3 row 3
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2);
+id nombre
+1 row 1
+2 row 2
+3 row 3
+DROP TABLE t1, t2;
# This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;
set optimizer_switch=default;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 92ad951325b..f388fd41ce8 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -107,6 +107,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t1`.`A`,`test`.`t1`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t1`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t1`.`A` = `<suBquery2>`.`pk`))))))) where 1
+set join_buffer_size=8*1024;
we shouldn't flatten if we're going to get a join of > MAX_TABLES.
explain select * from
t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -198,6 +199,7 @@ a b a b
0 0 0 0
1 1 1 1
2 2 2 2
+set join_buffer_size=default;
prepare s1 from
' select * from
t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
@@ -1020,8 +1022,8 @@ insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
("4", "1", "sup", "0");
create table t3 (
id int(11) not null default '0',
-preceeding_id int(11) not null default '0',
-primary key (id,preceeding_id)
+preceding_id int(11) not null default '0',
+primary key (id,preceding_id)
);
create table t4 (
user_id varchar(50) not null,
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 5e5b37f480a..82b64d30d96 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -653,13 +653,15 @@ SELECT * FROM t1;
dt1
DROP TABLE t1;
End of 5.1 tests
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
create table t1 (d date, t time) engine=myisam;
insert into t1 values ('2000-12-03','22:55:23'),('2008-05-03','10:19:31');
select case when d = '2012-12-12' then d else t end as cond, group_concat( d ) from t1 group by cond;
cond group_concat( d )
-0000-00-00 10:19:31 2008-05-03
-0000-00-00 22:55:23 2000-12-03
+2001-01-01 10:19:31 2008-05-03
+2001-01-01 22:55:23 2000-12-03
drop table t1;
+SET timestamp=DEFAULT;
#
# Semantics of the condition <non-nullable datetime field> IS NULL
# when the field belongs to an inner table of an outer join
@@ -722,6 +724,15 @@ dt
2013-09-21 08:20:30
drop procedure test5041;
SET @@timestamp=DEFAULT;
+#
+# MDEV-6097 Inconsistent results for CAST(int,decimal,double AS DATETIME)
+#
+SELECT
+CAST(010203101112 AS DATETIME(1)) AS c1,
+CAST(010203101112.2 AS DATETIME(1)) AS c2,
+CAST(010203101112.2+0e0 AS DATETIME(1)) AS c3;
+c1 c2 c3
+2001-02-03 10:11:12.0 2001-02-03 10:11:12.2 2001-02-03 10:11:12.2
End of 5.3 tests
#
# Start of 5.5 tests
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 00a7a9b783e..55b3ca1a1f4 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -163,12 +163,26 @@ create table t1 (f1 time , f2 varchar(5), key(f1));
insert into t1 values ('00:20:01','a'),('00:20:03','b');
select * from t1 force key (f1) where f1 < curdate();
f1 f2
+select * from t1 ignore key (f1) where f1 < curdate();
+f1 f2
+select * from t1 force key (f1) where f1 > curdate();
+f1 f2
00:20:01 a
00:20:03 b
-select * from t1 ignore key (f1) where f1 < curdate();
+select * from t1 ignore key (f1) where f1 > curdate();
f1 f2
00:20:01 a
00:20:03 b
+delete from t1;
+insert into t1 values ('-00:20:01','a'),('-00:20:03','b');
+select * from t1 force key (f1) where f1 < curdate();
+f1 f2
+-00:20:01 a
+-00:20:03 b
+select * from t1 ignore key (f1) where f1 < curdate();
+f1 f2
+-00:20:01 a
+-00:20:03 b
drop table t1;
create table t1(f1 time);
insert into t1 values ('23:38:57');
@@ -301,6 +315,34 @@ Field Type Null Key Default Extra
MAX(t1)+1 decimal(22,1) YES NULL
DROP TABLE t2,t1;
#
+# MDEV-4858 Wrong results for a huge unsigned value inserted into a TIME column
+#
+SET sql_mode=traditional;
+CREATE TABLE t1 (a TIME(6));
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFF00000000 AS UNSIGNED));
+ERROR 22007: Incorrect time value: '18446744069414584320' for column 'a' at row 1
+SET sql_mode=DEFAULT;
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFF00000000 AS UNSIGNED));
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 1
+SELECT * FROM t1;
+a
+838:59:59.999999
+DROP TABLE t1;
+SELECT TIME'00:00:00'> CAST(0xFFFFFFFF00000000 AS UNSIGNED);
+TIME'00:00:00'> CAST(0xFFFFFFFF00000000 AS UNSIGNED)
+0
+Warnings:
+Warning 1292 Truncated incorrect time value: '18446744069414584320'
+#
+# MDEV-6100 No warning on CAST(9000000 AS TIME)
+#
+SELECT CAST(9000000 AS TIME);
+CAST(9000000 AS TIME)
+838:59:59
+Warnings:
+Warning 1292 Truncated incorrect time value: '9000000'
+#
# End of 5.3 tests
#
CREATE TABLE t1 (f1 TIME);
@@ -326,3 +368,17 @@ SELECT '-24:00:00' = (SELECT f1 FROM t1);
'-24:00:00' = (SELECT f1 FROM t1)
1
DROP TABLE t1;
+#
+# Start of 10.0 tests
+#
+#
+# MDEV-6102 Comparison between TIME and DATETIME does not use CURRENT_DATE
+#
+SET timestamp=UNIX_TIMESTAMP('2014-04-14 01:02:03');
+SELECT CAST(TIME'10:20:30' AS DATETIME), TIME'10:20:30'=TIMESTAMP'2014-04-14 10:20:30' AS cmp;
+CAST(TIME'10:20:30' AS DATETIME) cmp
+2014-04-14 10:20:30 1
+SET timestamp=DEFAULT;
+#
+# End of 10.0 tests
+#
diff --git a/mysql-test/r/type_time_6065.result b/mysql-test/r/type_time_6065.result
new file mode 100644
index 00000000000..db3efc3bcbb
--- /dev/null
+++ b/mysql-test/r/type_time_6065.result
@@ -0,0 +1,2310 @@
+SET TIMESTAMP=UNIX_TIMESTAMP('2012-01-31 10:14:35');
+CREATE TABLE t1 (col_time_key TIME, KEY(col_time_key));
+INSERT INTO t1 VALUES ('00:00:00'),('-24:00:00'),('-48:00:00'),('24:00:00'),('48:00:00');
+CREATE TABLE t2 (col_datetime_key DATETIME, KEY(col_datetime_key));
+INSERT INTO t2 SELECT * FROM t1;
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 SIMPLE t2 ref col_datetime_key col_datetime_key 9 test.t1.col_time_key 1 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 SIMPLE t2 ref col_datetime_key col_datetime_key 9 test.t1.col_time_key 1 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using where; Using index
+1 SIMPLE t2 ref col_datetime_key col_datetime_key 9 test.t1.col_time_key 1 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key = col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using where; Using index
+1 SIMPLE t2 ref col_datetime_key col_datetime_key 9 test.t1.col_time_key 1 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key = col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using where; Using index
+1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` = `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key = col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using where; Using index
+1 SIMPLE t1 ref col_time_key col_time_key 4 test.t2.col_datetime_key 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` = `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key = col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key >= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key >= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` >= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key >= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` >= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key >= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key > col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key > col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` > `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key > col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` > `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key > col_time_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key <= col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-30 00:00:00
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-29 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-01-31 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-01 00:00:00
+24:00:00 2012-02-02 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key <= col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+-24:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+00:00:00 2012-01-31 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+24:00:00 2012-02-01 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+48:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` <= `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key <= col_datetime_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` <= `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key <= col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 -48:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 -24:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 00:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 24:00:00
+2012-02-01 00:00:00 48:00:00
+2012-02-02 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` IGNORE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 ignore INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` IGNORE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 ignore INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_time_key < col_datetime_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-31 00:00:00
+-24:00:00 2012-02-01 00:00:00
+-24:00:00 2012-02-02 00:00:00
+-48:00:00 2012-01-30 00:00:00
+-48:00:00 2012-01-31 00:00:00
+-48:00:00 2012-02-01 00:00:00
+-48:00:00 2012-02-02 00:00:00
+00:00:00 2012-02-01 00:00:00
+00:00:00 2012-02-02 00:00:00
+24:00:00 2012-02-02 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index col_time_key col_time_key 4 NULL 5 100.00 Using index
+1 SIMPLE t2 ALL col_datetime_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t1`.`col_time_key` AS `col_time_key`,`test`.`t2`.`col_datetime_key` AS `col_datetime_key` from `test`.`t1` FORCE INDEX (`col_time_key`) straight_join `test`.`t2` FORCE INDEX (`col_datetime_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t1 force INDEX (col_time_key)
+STRAIGHT_JOIN
+t2 force INDEX (col_datetime_key)
+WHERE col_datetime_key < col_time_key;
+col_time_key col_datetime_key
+-24:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-29 00:00:00
+00:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-29 00:00:00
+24:00:00 2012-01-30 00:00:00
+24:00:00 2012-01-31 00:00:00
+48:00:00 2012-01-29 00:00:00
+48:00:00 2012-01-30 00:00:00
+48:00:00 2012-01-31 00:00:00
+48:00:00 2012-02-01 00:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` IGNORE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 ignore INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` IGNORE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 ignore INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t1`.`col_time_key` < `test`.`t2`.`col_datetime_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_time_key < col_datetime_key;
+col_datetime_key col_time_key
+2012-01-30 00:00:00 -48:00:00
+2012-01-31 00:00:00 -24:00:00
+2012-01-31 00:00:00 -48:00:00
+2012-02-01 00:00:00 -24:00:00
+2012-02-01 00:00:00 -48:00:00
+2012-02-01 00:00:00 00:00:00
+2012-02-02 00:00:00 -24:00:00
+2012-02-02 00:00:00 -48:00:00
+2012-02-02 00:00:00 00:00:00
+2012-02-02 00:00:00 24:00:00
+EXPLAIN EXTENDED SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 index col_datetime_key col_datetime_key 9 NULL 5 100.00 Using index
+1 SIMPLE t1 ALL col_time_key NULL NULL NULL 5 100.00 Range checked for each record (index map: 0x1)
+Warnings:
+Note 1003 select `test`.`t2`.`col_datetime_key` AS `col_datetime_key`,`test`.`t1`.`col_time_key` AS `col_time_key` from `test`.`t2` FORCE INDEX (`col_datetime_key`) straight_join `test`.`t1` FORCE INDEX (`col_time_key`) where (`test`.`t2`.`col_datetime_key` < `test`.`t1`.`col_time_key`)
+SELECT * FROM
+t2 force INDEX (col_datetime_key)
+STRAIGHT_JOIN
+t1 force INDEX (col_time_key)
+WHERE col_datetime_key < col_time_key;
+col_datetime_key col_time_key
+2012-01-29 00:00:00 -24:00:00
+2012-01-29 00:00:00 00:00:00
+2012-01-29 00:00:00 24:00:00
+2012-01-29 00:00:00 48:00:00
+2012-01-30 00:00:00 00:00:00
+2012-01-30 00:00:00 24:00:00
+2012-01-30 00:00:00 48:00:00
+2012-01-31 00:00:00 24:00:00
+2012-01-31 00:00:00 48:00:00
+2012-02-01 00:00:00 48:00:00
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+pk INT NOT NULL AUTO_INCREMENT,
+col_int_nokey INT,
+col_int_key INT NOT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key)
+);
+INSERT INTO t1 VALUES (10,1,7), (11,7,0), (12,4,9), (13,7,3),
+(14,0,4), (15,2,2), (16,9,5), (17,4,3), (18,0,1), (19,9,3), (20,1,6),
+(21,3,7), (22,8,5), (23,8,1), (24,18,204), (25,84,224), (26,6,9),
+(27,3,5), (28,6,0), (29,6,3);
+CREATE TABLE t2 (
+col_int_nokey INT NOT NULL,
+col_datetime_key DATETIME NOT NULL,
+col_varchar_key VARCHAR(1) NOT NULL,
+KEY col_datetime_key (col_datetime_key),
+KEY col_varchar_key (col_varchar_key)
+);
+INSERT INTO t2 VALUES (1,'2001-11-04 19:07:55','k');
+CREATE TABLE t3 (
+col_time_key TIME,
+KEY col_time_key (col_time_key)
+);
+INSERT INTO t3 VALUES ('21:22:34'), ('10:50:38'), ('00:21:38'),
+('04:08:02'), ('16:25:11'), ('10:14:58'), ('19:47:59'), ('11:14:24'),
+('00:00:00'), ('00:00:00'), ('15:57:25'), ('07:05:51'), ('19:22:21'),
+('03:53:16'), ('09:16:38'), ('15:37:26'), ('00:00:00'), ('05:03:03'),
+('02:59:24'), ('00:01:58');
+EXPLAIN EXTENDED SELECT * FROM t2 STRAIGHT_JOIN t3 FORCE INDEX (col_time_key)
+ON t3.col_time_key > t2.col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 system col_datetime_key NULL NULL NULL 1 100.00
+1 SIMPLE t3 index col_time_key col_time_key 4 NULL 20 100.00 Using where; Using index
+Warnings:
+Note 1003 select 1 AS `col_int_nokey`,'2001-11-04 19:07:55' AS `col_datetime_key`,'k' AS `col_varchar_key`,`test`.`t3`.`col_time_key` AS `col_time_key` from `test`.`t3` FORCE INDEX (`col_time_key`) where (`test`.`t3`.`col_time_key` > '2001-11-04 19:07:55')
+SELECT * FROM t2 STRAIGHT_JOIN t3 FORCE INDEX (col_time_key)
+ON t3.col_time_key > t2.col_datetime_key;
+col_int_nokey col_datetime_key col_varchar_key col_time_key
+1 2001-11-04 19:07:55 k 00:00:00
+1 2001-11-04 19:07:55 k 00:00:00
+1 2001-11-04 19:07:55 k 00:00:00
+1 2001-11-04 19:07:55 k 00:01:58
+1 2001-11-04 19:07:55 k 00:21:38
+1 2001-11-04 19:07:55 k 02:59:24
+1 2001-11-04 19:07:55 k 03:53:16
+1 2001-11-04 19:07:55 k 04:08:02
+1 2001-11-04 19:07:55 k 05:03:03
+1 2001-11-04 19:07:55 k 07:05:51
+1 2001-11-04 19:07:55 k 09:16:38
+1 2001-11-04 19:07:55 k 10:14:58
+1 2001-11-04 19:07:55 k 10:50:38
+1 2001-11-04 19:07:55 k 11:14:24
+1 2001-11-04 19:07:55 k 15:37:26
+1 2001-11-04 19:07:55 k 15:57:25
+1 2001-11-04 19:07:55 k 16:25:11
+1 2001-11-04 19:07:55 k 19:22:21
+1 2001-11-04 19:07:55 k 19:47:59
+1 2001-11-04 19:07:55 k 21:22:34
+EXPLAIN EXTENDED SELECT * FROM t2 STRAIGHT_JOIN t3 IGNORE INDEX (col_time_key)
+ON t3.col_time_key > t2.col_datetime_key;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 system col_datetime_key NULL NULL NULL 1 100.00
+1 SIMPLE t3 ALL NULL NULL NULL NULL 20 100.00 Using where
+Warnings:
+Note 1003 select 1 AS `col_int_nokey`,'2001-11-04 19:07:55' AS `col_datetime_key`,'k' AS `col_varchar_key`,`test`.`t3`.`col_time_key` AS `col_time_key` from `test`.`t3` IGNORE INDEX (`col_time_key`) where (`test`.`t3`.`col_time_key` > '2001-11-04 19:07:55')
+SELECT * FROM t2 STRAIGHT_JOIN t3 IGNORE INDEX (col_time_key)
+ON t3.col_time_key > t2.col_datetime_key;
+col_int_nokey col_datetime_key col_varchar_key col_time_key
+1 2001-11-04 19:07:55 k 00:00:00
+1 2001-11-04 19:07:55 k 00:00:00
+1 2001-11-04 19:07:55 k 00:00:00
+1 2001-11-04 19:07:55 k 00:01:58
+1 2001-11-04 19:07:55 k 00:21:38
+1 2001-11-04 19:07:55 k 02:59:24
+1 2001-11-04 19:07:55 k 03:53:16
+1 2001-11-04 19:07:55 k 04:08:02
+1 2001-11-04 19:07:55 k 05:03:03
+1 2001-11-04 19:07:55 k 07:05:51
+1 2001-11-04 19:07:55 k 09:16:38
+1 2001-11-04 19:07:55 k 10:14:58
+1 2001-11-04 19:07:55 k 10:50:38
+1 2001-11-04 19:07:55 k 11:14:24
+1 2001-11-04 19:07:55 k 15:37:26
+1 2001-11-04 19:07:55 k 15:57:25
+1 2001-11-04 19:07:55 k 16:25:11
+1 2001-11-04 19:07:55 k 19:22:21
+1 2001-11-04 19:07:55 k 19:47:59
+1 2001-11-04 19:07:55 k 21:22:34
+EXPLAIN EXTENDED SELECT outr.col_int_nokey
+FROM t2 as outr
+STRAIGHT_JOIN t3 AS outr2
+ON outr2.col_time_key > outr.col_datetime_key
+WHERE outr.col_int_nokey IN (
+SELECT col_int_key
+FROM t1 AS innr
+WHERE innr.pk >= innr.col_int_nokey
+) AND (
+outr.col_int_nokey <= 6
+OR
+outr.col_varchar_key IS NULL
+);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY outr system col_datetime_key NULL NULL NULL 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+1 PRIMARY outr2 index col_time_key col_time_key 4 NULL 20 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED innr ref col_int_key col_int_key 4 const 2 100.00 Using where
+Warnings:
+Note 1003 select 1 AS `col_int_nokey` from `test`.`t3` `outr2` semi join (`test`.`t1` `innr`) where ((`test`.`innr`.`col_int_key` = 1) and (`test`.`innr`.`pk` >= `test`.`innr`.`col_int_nokey`) and (`test`.`outr2`.`col_time_key` > '2001-11-04 19:07:55'))
+SELECT outr.col_int_nokey
+FROM t2 as outr
+STRAIGHT_JOIN t3 AS outr2
+ON outr2.col_time_key > outr.col_datetime_key
+WHERE outr.col_int_nokey IN (
+SELECT col_int_key
+FROM t1 AS innr
+WHERE innr.pk >= innr.col_int_nokey
+) AND (
+outr.col_int_nokey <= 6
+OR
+outr.col_varchar_key IS NULL
+);
+col_int_nokey
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+DROP TABLE t1,t2,t3;
+SET TIMESTAMP=0;
diff --git a/mysql-test/r/type_time_hires.result b/mysql-test/r/type_time_hires.result
index 2239ecfcaaa..8096785dcc1 100644
--- a/mysql-test/r/type_time_hires.result
+++ b/mysql-test/r/type_time_hires.result
@@ -11,52 +11,52 @@ Warnings:
Note 1265 Data truncated for column 'a' at row 1
insert t1 values (20101211010203.45678);
Warnings:
-Warning 1265 Data truncated for column 'a' at row 1
+Note 1265 Data truncated for column 'a' at row 1
insert t1 values (20101211030405.789e0);
Warnings:
-Warning 1265 Data truncated for column 'a' at row 1
+Note 1265 Data truncated for column 'a' at row 1
insert t1 values (99991231235959e1);
Warnings:
-Warning 1265 Data truncated for column 'a' at row 1
+Warning 1264 Out of range value for column 'a' at row 1
select * from t1;
a
-00:00:00.000
00:20:03.123
01:02:03.456
03:04:05.789
15:47:11.123
+838:59:59.999
select truncate(a, 6) from t1;
truncate(a, 6)
-0.000000
2003.123000
10203.456000
30405.789062
154711.123000
+8385959.999000
select a DIV 1 from t1;
a DIV 1
-0
2003
10203
30405
154711
+8385959
select group_concat(distinct a) from t1;
group_concat(distinct a)
-00:00:00.000,00:20:03.123,01:02:03.456,03:04:05.789,15:47:11.123
+00:20:03.123,01:02:03.456,03:04:05.789,15:47:11.123,838:59:59.999
alter table t1 engine=innodb;
select * from t1 order by a;
a
-00:00:00.000
00:20:03.123
01:02:03.456
03:04:05.789
15:47:11.123
+838:59:59.999
select * from t1 order by a+0;
a
-00:00:00.000
00:20:03.123
01:02:03.456
03:04:05.789
15:47:11.123
+838:59:59.999
drop table t1;
create table t1 (a time(4)) engine=innodb;
insert t1 values ('2010-12-11 01:02:03.456789');
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index a3ad63c035a..6d99cad30f0 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -1876,8 +1876,8 @@ SELECT(SELECT 1 AS a FROM dual ORDER BY a DESC LIMIT 1) AS dev;
dev
1
#
-# LP bug#1010729: Unexpected syntax error from UNION
-# (bug #54382) with single-table join nest
+# lp:1010729: Unexpected syntax error from UNION
+# (bug #54382) with single-table join nest
#
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int);
@@ -1892,3 +1892,12 @@ UNION
SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk);
pk
DROP TABLE t1,t2;
+create table t1 (a int);
+insert t1 values (1),(2),(3),(1);
+explain select 1 from dual where exists (select max(a) from t1 group by a union select a+2 from t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+3 UNION t1 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+drop table t1;
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index bc0f9411d15..9eaf1a46d89 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -615,7 +615,7 @@ select A.a + 10 * B.a + 100 * C.a, 1234 from t2 A, t2 B, t2 C;
explain
update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range key1 key1 5 NULL 100 Using where; Using buffer
+1 SIMPLE t1 range key1 key1 5 NULL 2 Using where; Using buffer
flush status;
update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2;
show status like 'Handler_read%';
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 1ea30658561..64b329e9e01 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1,5 +1,5 @@
-drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
-drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
+drop table if exists t1,t2,t3,t4,t5,t6,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
+drop view if exists t1,t2,t3,t4,t5,t6,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop database if exists mysqltest;
use test;
SET @save_optimizer_switch=@@optimizer_switch;
@@ -4114,6 +4114,114 @@ a
20
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
+#
+# MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
+# with MERGE view)
+#
+CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE OR REPLACE view v1 AS
+SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+;
+SELECT 1
+FROM (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t1)
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t2) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t3) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t4) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t5) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t6) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t7) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t8) ON 1=1
+;
+1
+SELECT 1
+FROM (v1 t1)
+LEFT OUTER JOIN (v1 t2) ON 1=1
+LEFT OUTER JOIN (v1 t3) ON 1=1
+LEFT OUTER JOIN (v1 t4) ON 1=1
+LEFT OUTER JOIN (v1 t5) ON 1=1
+LEFT OUTER JOIN (v1 t6) ON 1=1
+LEFT OUTER JOIN (v1 t7) ON 1=1
+LEFT OUTER JOIN (v1 t8) ON 1=1
+;
+1
+drop view v1;
+drop table t1,t2,t3,t4,t5,t6;
# -----------------------------------------------------------------
# -- End of 5.2 tests.
# -----------------------------------------------------------------
@@ -5052,6 +5160,114 @@ execute stmt1;
deallocate prepare stmt1;
drop view v1,v2;
drop table t1,t2;
+#
+# MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
+# with MERGE view)
+#
+CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE OR REPLACE view v1 AS
+SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+;
+SELECT 1
+FROM (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t1)
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t2) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t3) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t4) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t5) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t6) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t7) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+FROM t1 a_alias_1
+LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t8) ON 1=1
+;
+1
+SELECT 1
+FROM (v1 t1)
+LEFT OUTER JOIN (v1 t2) ON 1=1
+LEFT OUTER JOIN (v1 t3) ON 1=1
+LEFT OUTER JOIN (v1 t4) ON 1=1
+LEFT OUTER JOIN (v1 t5) ON 1=1
+LEFT OUTER JOIN (v1 t6) ON 1=1
+LEFT OUTER JOIN (v1 t7) ON 1=1
+LEFT OUTER JOIN (v1 t8) ON 1=1
+;
+1
+drop view v1;
+drop table t1,t2,t3,t4,t5,t6;
# -----------------------------------------------------------------
# -- End of 5.3 tests.
# -----------------------------------------------------------------
diff --git a/mysql-test/suite/binlog/r/binlog_truncate_kill.result b/mysql-test/suite/binlog/r/binlog_truncate_kill.result
new file mode 100644
index 00000000000..9161f3dc10d
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_truncate_kill.result
@@ -0,0 +1,38 @@
+RESET MASTER;
+connection default;
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB;
+INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10);
+SET DEBUG_SYNC = "open_and_process_table signal truncate_before_lock wait_for forever";
+TRUNCATE t1;
+connect con1,localhost,root,,;
+SET DEBUG_SYNC = "now wait_for truncate_before_lock";
+SELECT ((@id := id) - id) FROM information_schema.processlist WHERE processlist.info LIKE '%TRUNCATE t1%' AND state LIKE '%open_and_process_table%';
+((@id := id) - id)
+0
+KILL QUERY @id;
+connection default;
+ERROR 70100: Query execution was interrupted
+connection con1;
+include/show_binlog_events.inc
+connection con1;
+connection con1;
+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(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Intvar # # INSERT_ID=1
+master-bin.000001 # Query # # use `test`; INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10)
+master-bin.000001 # Xid # # COMMIT /* XID */
+connection con1;
+connection con1;
+disconnect con1;
+connection default;
+SELECT * FROM t1;
+id a b
+1 1 2
+2 2 4
+3 3 6
+4 4 8
+5 5 10
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/suite/binlog/t/binlog_truncate_kill.test b/mysql-test/suite/binlog/t/binlog_truncate_kill.test
new file mode 100644
index 00000000000..92c23f18cb4
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_truncate_kill.test
@@ -0,0 +1,57 @@
+###############################################################################
+# Bug#17942050:KILL OF TRUNCATE TABLE WILL LEAD TO BINARY LOG WRITTEN WHILE
+# ROWS REMAINS
+#
+# Problem:
+# ========
+# When truncate table fails while using transactional based engines even
+# though the operation errors out we still continue and log it to binlog.
+# Because of this master has data but the truncate will be written to binary
+# log which will cause inconsistency.
+#
+# Test:
+# =====
+# Make master to wait in "open_table" call during the execution of truncate
+# table command and kill the truncate table from other connection. This causes
+# open table to return an error saying truncate failed during open table. This
+# statement should not be binlogged.
+###############################################################################
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source include/have_binlog_format_statement.inc
+RESET MASTER;
+--enable_connect_log
+--connection default
+CREATE TABLE t1(id INT AUTO_INCREMENT PRIMARY KEY, a INT, b INT) ENGINE=INNODB;
+INSERT INTO t1(a, b) VALUES(1,2),(2,4),(3,6),(4,8),(5,10);
+SET DEBUG_SYNC = "open_and_process_table signal truncate_before_lock wait_for forever";
+--send TRUNCATE t1
+
+connect(con1,localhost,root,,);
+SET DEBUG_SYNC = "now wait_for truncate_before_lock";
+# Wait for one connection to reach open_and_process_table.
+--let $show_statement= SHOW PROCESSLIST
+--let $field= State
+--let $condition= 'debug sync point: open_and_process_table';
+--source include/wait_show_condition.inc
+
+SELECT ((@id := id) - id) FROM information_schema.processlist WHERE processlist.info LIKE '%TRUNCATE t1%' AND state LIKE '%open_and_process_table%';
+# Test killing from mysql server
+KILL QUERY @id;
+
+connection default;
+--ERROR ER_QUERY_INTERRUPTED
+--reap
+
+connection con1;
+--source include/show_binlog_events.inc
+
+disconnect con1;
+--source include/wait_until_disconnected.inc
+connection default;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
+--disable_connect_log
diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result
index 2b98bc704d5..ae9440859df 100644
--- a/mysql-test/suite/funcs_1/r/innodb_func_view.result
+++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result
@@ -3695,14 +3695,14 @@ my_double, id FROM t1_values
WHERE select_id = 53 OR select_id IS NULL order by id;
CAST(my_double AS TIME) my_double id
NULL NULL 1
-NULL -1.7976931348623e308 2
-NULL 1.7976931348623e308 3
+-838:59:59 -1.7976931348623e308 2
+838:59:59 1.7976931348623e308 3
00:00:00 0 4
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
+Warning 1292 Incorrect time value: '-1.7976931348623e308' for column 'my_double' at row 2
+Warning 1292 Incorrect time value: '1.7976931348623e308' for column 'my_double' at row 3
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as time) AS `CAST(my_double AS TIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3711,14 +3711,14 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 53 OR select_id IS NULL) order by id;
CAST(my_double AS TIME) my_double id
NULL NULL 1
-NULL -1.7976931348623e308 2
-NULL 1.7976931348623e308 3
+-838:59:59 -1.7976931348623e308 2
+838:59:59 1.7976931348623e308 3
00:00:00 0 4
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect time value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect time value: '1.7976931348623e308' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result
index 43516edc70a..81f7a0584d3 100644
--- a/mysql-test/suite/funcs_1/r/memory_func_view.result
+++ b/mysql-test/suite/funcs_1/r/memory_func_view.result
@@ -3696,14 +3696,14 @@ my_double, id FROM t1_values
WHERE select_id = 53 OR select_id IS NULL order by id;
CAST(my_double AS TIME) my_double id
NULL NULL 1
-NULL -1.7976931348623e308 2
-NULL 1.7976931348623e308 3
+-838:59:59 -1.7976931348623e308 2
+838:59:59 1.7976931348623e308 3
00:00:00 0 4
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
+Warning 1292 Incorrect time value: '-1.7976931348623e308' for column 'my_double' at row 2
+Warning 1292 Incorrect time value: '1.7976931348623e308' for column 'my_double' at row 3
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as time) AS `CAST(my_double AS TIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3712,14 +3712,14 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 53 OR select_id IS NULL) order by id;
CAST(my_double AS TIME) my_double id
NULL NULL 1
-NULL -1.7976931348623e308 2
-NULL 1.7976931348623e308 3
+-838:59:59 -1.7976931348623e308 2
+838:59:59 1.7976931348623e308 3
00:00:00 0 4
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect time value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect time value: '1.7976931348623e308' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result
index 43516edc70a..81f7a0584d3 100644
--- a/mysql-test/suite/funcs_1/r/myisam_func_view.result
+++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result
@@ -3696,14 +3696,14 @@ my_double, id FROM t1_values
WHERE select_id = 53 OR select_id IS NULL order by id;
CAST(my_double AS TIME) my_double id
NULL NULL 1
-NULL -1.7976931348623e308 2
-NULL 1.7976931348623e308 3
+-838:59:59 -1.7976931348623e308 2
+838:59:59 1.7976931348623e308 3
00:00:00 0 4
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
+Warning 1292 Incorrect time value: '-1.7976931348623e308' for column 'my_double' at row 2
+Warning 1292 Incorrect time value: '1.7976931348623e308' for column 'my_double' at row 3
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_double` as time) AS `CAST(my_double AS TIME)`,`t1_values`.`my_double` AS `my_double`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
@@ -3712,14 +3712,14 @@ WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 53 OR select_id IS NULL) order by id;
CAST(my_double AS TIME) my_double id
NULL NULL 1
-NULL -1.7976931348623e308 2
-NULL 1.7976931348623e308 3
+-838:59:59 -1.7976931348623e308 2
+838:59:59 1.7976931348623e308 3
00:00:00 0 4
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect time value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect time value: '1.7976931348623e308' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/views/func_view.inc b/mysql-test/suite/funcs_1/views/func_view.inc
index c26f21945c3..1f0b0ac52a7 100644
--- a/mysql-test/suite/funcs_1/views/func_view.inc
+++ b/mysql-test/suite/funcs_1/views/func_view.inc
@@ -284,7 +284,7 @@ INSERT INTO t1_values SET
# other interesting value
# numbers -> 0
# strings, blobs, binaries -> not full length of used data type, "exotic"
-# characters and preceeding and trailing spaces
+# characters and preceding and trailing spaces
# FIXME enum, set ??
INSERT INTO t1_values SET
my_char_30 = ' ---äÖüß@µ*$-- ',
diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc
index 48996a6c1a3..1743bace705 100644
--- a/mysql-test/suite/funcs_1/views/views_master.inc
+++ b/mysql-test/suite/funcs_1/views/views_master.inc
@@ -545,7 +545,7 @@ let $message= Testcase 3.3.1.7 ;
# view names are accepted, at creation time, alteration time,
# and drop time.
###############################################################################
-# Note(mleich): non-qualified view name means a view name without preceeding
+# Note(mleich): non-qualified view name means a view name without preceding
# database name
--disable_warnings
DROP VIEW IF EXISTS v1 ;
diff --git a/mysql-test/suite/innodb/r/count_distinct.result b/mysql-test/suite/innodb/r/count_distinct.result
new file mode 100644
index 00000000000..201767b8f42
--- /dev/null
+++ b/mysql-test/suite/innodb/r/count_distinct.result
@@ -0,0 +1,12 @@
+CREATE TABLE t1 (
+id int NOT NULL AUTO_INCREMENT,
+a int NOT NULL,
+b int NOT NULL,
+PRIMARY KEY (id),
+UNIQUE KEY ba (b, a)
+) ENGINE=InnoDB;
+INSERT INTO t1 (a, b) VALUES(1,101),(1,102),(1,103),(1,104),(1,105),(1,106),(1,107),(1,108),(1,109),(1,110);
+SELECT COUNT(DISTINCT b) FROM t1 WHERE a = 1;
+COUNT(DISTINCT b)
+10
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/count_distinct.test b/mysql-test/suite/innodb/t/count_distinct.test
new file mode 100644
index 00000000000..94a70260e23
--- /dev/null
+++ b/mysql-test/suite/innodb/t/count_distinct.test
@@ -0,0 +1,15 @@
+--source include/have_innodb.inc
+
+#
+# MDEV-4925 Wrong result - count(distinct), Using index for group-by (scanning)
+#
+CREATE TABLE t1 (
+ id int NOT NULL AUTO_INCREMENT,
+ a int NOT NULL,
+ b int NOT NULL,
+ PRIMARY KEY (id),
+ UNIQUE KEY ba (b, a)
+) ENGINE=InnoDB;
+INSERT INTO t1 (a, b) VALUES(1,101),(1,102),(1,103),(1,104),(1,105),(1,106),(1,107),(1,108),(1,109),(1,110);
+SELECT COUNT(DISTINCT b) FROM t1 WHERE a = 1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result
index e665fd1370f..dd8412c6651 100644
--- a/mysql-test/suite/innodb_fts/r/fulltext.result
+++ b/mysql-test/suite/innodb_fts/r/fulltext.result
@@ -549,8 +549,8 @@ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2 fulltext b2 b2 0 1 Using where
-2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 fulltext b2 b2 0 1 Using where
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where
# should return 0
SELECT count(*) FROM t1 WHERE
not exists(
@@ -558,7 +558,7 @@ SELECT 1 FROM t2, t3
WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE)
);
count(*)
-1
+0
SELECT count(*) FROM t1 WHERE
not exists(
SELECT 1 FROM t2 IGNORE INDEX (b2), t3
diff --git a/mysql-test/suite/maria/ps_maria.result b/mysql-test/suite/maria/ps_maria.result
index e2669b568cf..774bf8af54a 100644
--- a/mysql-test/suite/maria/ps_maria.result
+++ b/mysql-test/suite/maria/ps_maria.result
@@ -3256,7 +3256,7 @@ values
( 50, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10, 1.0e+10 ) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3264,7 +3264,7 @@ values
( 51, @arg00, @arg00, @arg00, @arg00, @arg00) ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt1 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3273,7 +3273,7 @@ values
execute stmt1 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
prepare stmt2 from "insert into t9
( c1, c13, c14, c15, c16, c17 )
@@ -3282,7 +3282,7 @@ values
execute stmt2 using @arg00, @arg00, @arg00, @arg00, @arg00 ;
Warnings:
Warning 1265 Data truncated for column 'c15' at row 1
-Warning 1265 Data truncated for column 'c16' at row 1
+Note 1265 Data truncated for column 'c16' at row 1
Warning 1264 Out of range value for column 'c17' at row 1
set @arg00= 'abc' ;
set @arg00= NULL ;
diff --git a/mysql-test/suite/perfschema/r/mks_timer-6258.result b/mysql-test/suite/perfschema/r/mks_timer-6258.result
new file mode 100644
index 00000000000..d0e95a1a8fb
--- /dev/null
+++ b/mysql-test/suite/perfschema/r/mks_timer-6258.result
@@ -0,0 +1,3 @@
+select distinct first_seen < DATE'2000-01-01', last_seen < DATE'2000-01-01' from performance_schema.events_statements_summary_by_digest;
+first_seen < DATE'2000-01-01' last_seen < DATE'2000-01-01'
+0 0
diff --git a/mysql-test/suite/perfschema/t/mks_timer-6258.test b/mysql-test/suite/perfschema/t/mks_timer-6258.test
new file mode 100644
index 00000000000..b4e5791298a
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/mks_timer-6258.test
@@ -0,0 +1,5 @@
+--source include/not_embedded.inc
+#
+# MDEV-6258 MariaDB 10.0 performance schema timestamps relative to epoch
+#
+select distinct first_seen < DATE'2000-01-01', last_seen < DATE'2000-01-01' from performance_schema.events_statements_summary_by_digest;
diff --git a/mysql-test/suite/rpl/r/rpl_row_create_select.result b/mysql-test/suite/rpl/r/rpl_row_create_select.result
new file mode 100644
index 00000000000..ac95d50df9d
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_create_select.result
@@ -0,0 +1,28 @@
+include/master-slave.inc
+[connection master]
+#
+# BUG#17994219: CREATE TABLE .. SELECT PRODUCES INVALID STRUCTURE,
+# BREAKS RBR
+#
+#After the patch, the display width is set to a default
+#value of 21.
+CREATE TABLE t1 AS SELECT REPEAT('A', 1000) DIV 1 AS a;
+Warnings:
+Warning 1918 Encountered illegal value '' when converting to DECIMAL
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(21) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t2 AS SELECT CONVERT(REPEAT('A', 255) USING UCS2) DIV 1 AS a;
+Warnings:
+Warning 1918 Encountered illegal value '' when converting to DECIMAL
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` bigint(21) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+#After the patch, no error is reported.
+DROP TABLE t1;
+DROP TABLE t2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_ddl.test b/mysql-test/suite/rpl/t/rpl_ddl.test
index f9a353f87ac..89ae2c03242 100644
--- a/mysql-test/suite/rpl/t/rpl_ddl.test
+++ b/mysql-test/suite/rpl/t/rpl_ddl.test
@@ -13,10 +13,10 @@
# sequences start.
#
# 2. Never use a test object, which was direct or indirect affected by a
-# preceeding test sequence again.
+# preceding test sequence again.
# Except table d1.t1 where ONLY DML is allowed.
#
-# If one preceeding test sequence hits a (sometimes not good visible,
+# If one preceding test sequence hits a (sometimes not good visible,
# because the sql error code of the statement might be 0) bug
# and these rules are ignored, a following test sequence might earn ugly
# effects like failing 'sync_slave_with_master', crashes of the slave or
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
index 3123a7da2a5..5b55f11da85 100644
--- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
@@ -363,12 +363,11 @@ let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_b
--connection master
DELETE FROM t1;
DROP EVENT e1;
+--sync_slave_with_master
--echo
-
# Check received heartbeat events while logs flushed on slave
---sync_slave_with_master
--echo *** Flush logs on slave ***
STOP SLAVE;
RESET SLAVE;
diff --git a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
index b88001e6a9f..9e99c1eb0b3 100644
--- a/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
+++ b/mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test
@@ -244,7 +244,7 @@ sync_slave_with_master;
UPDATE t1 SET a = 5, b = 'slave' WHERE a = 1;
SELECT * FROM t1 ORDER BY a;
# since bug#31552/31609 idempotency is not default any longer. In
-# order for the preceeding test UPDATE t1 to pass, the mode is switched
+# order for the preceding test UPDATE t1 to pass, the mode is switched
# temprorarily
set @@global.slave_exec_mode= 'IDEMPOTENT';
--echo **** On Master ****
diff --git a/mysql-test/suite/rpl/t/rpl_row_create_select.test b/mysql-test/suite/rpl/t/rpl_row_create_select.test
new file mode 100644
index 00000000000..ca270e92d0c
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_create_select.test
@@ -0,0 +1,28 @@
+# Testing table creations for row-based replication.
+
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+--echo #
+--echo # BUG#17994219: CREATE TABLE .. SELECT PRODUCES INVALID STRUCTURE,
+--echo # BREAKS RBR
+--echo #
+
+connection master;
+--echo #After the patch, the display width is set to a default
+--echo #value of 21.
+CREATE TABLE t1 AS SELECT REPEAT('A', 1000) DIV 1 AS a;
+SHOW CREATE TABLE t1;
+
+CREATE TABLE t2 AS SELECT CONVERT(REPEAT('A', 255) USING UCS2) DIV 1 AS a;
+SHOW CREATE TABLE t2;
+
+--echo #After the patch, no error is reported.
+sync_slave_with_master;
+
+connection master;
+DROP TABLE t1;
+DROP TABLE t2;
+
+--source include/rpl_end.inc
+
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
index 99b1d6296a8..141ab31ea82 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
@@ -1,25 +1,25 @@
SET @start_global_value = @@global.optimizer_switch;
SELECT @start_global_value;
@start_global_value
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
set global optimizer_switch=10;
set session optimizer_switch=5;
select @@global.optimizer_switch;
@@ -67,4 +67,4 @@ ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
SET @@global.optimizer_switch = @start_global_value;
SELECT @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
diff --git a/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc
index c586479618a..8c83586109c 100644
--- a/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc
+++ b/mysql-test/suite/vcol/inc/vcol_non_stored_columns.inc
@@ -160,3 +160,15 @@ select * from t1;
show create table t1;
drop table t1;
+--echo #
+--echo # MDEV-6103 - Adding/removing non-materialized virtual column triggers
+--echo # table recreation
+--echo #
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
+enable_info;
+ALTER TABLE t1 ADD COLUMN b INT AS (a + 1) VIRTUAL;
+ALTER TABLE t1 DROP COLUMN b;
+disable_info;
+CHECK TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result
index 0379a71922d..85e89f57090 100644
--- a/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_innodb.result
@@ -240,3 +240,19 @@ t1 CREATE TABLE `t1` (
`c` int(11) AS (week(b,1)) VIRTUAL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t1;
+#
+# MDEV-6103 - Adding/removing non-materialized virtual column triggers
+# table recreation
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
+ALTER TABLE t1 ADD COLUMN b INT AS (a + 1) VIRTUAL;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+ALTER TABLE t1 DROP COLUMN b;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result
index de9a962ac2c..d73ea923a11 100644
--- a/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_non_stored_columns_myisam.result
@@ -240,3 +240,19 @@ t1 CREATE TABLE `t1` (
`c` int(11) AS (week(b,1)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+#
+# MDEV-6103 - Adding/removing non-materialized virtual column triggers
+# table recreation
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
+ALTER TABLE t1 ADD COLUMN b INT AS (a + 1) VIRTUAL;
+affected rows: 10
+info: Records: 10 Duplicates: 0 Warnings: 0
+ALTER TABLE t1 DROP COLUMN b;
+affected rows: 10
+info: Records: 10 Duplicates: 0 Warnings: 0
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 4aeabf5f349..416c73009e6 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1314,6 +1314,16 @@ ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
+CREATE TABLE t2 (
+ id INT(11) NOT NULL);
+ALTER TABLE t2 ADD COLUMN a INT, ADD COLUMN IF NOT EXISTS a INT;
+ALTER TABLE t2 ADD KEY k_id(id), ADD KEY IF NOT EXISTS k_id(id);
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 DROP KEY k_id, DROP KEY IF EXISTS k_id;
+ALTER TABLE t2 DROP COLUMN a, DROP COLUMN IF EXISTS a;
+SHOW CREATE TABLE t2;
+
+DROP TABLE t2;
DROP TABLE t1;
--echo # Bug#11748057 (formerly known as 34972): ALTER TABLE statement doesn't
diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test
index 916b0150773..fca588de8e8 100644
--- a/mysql-test/t/connect.test
+++ b/mysql-test/t/connect.test
@@ -378,8 +378,8 @@ select user(), current_user();
disconnect pcon4;
#
-# lpbug#683112 Maria 5.2 incorrectly reports "(using password: NO)"
-# even when password is specified
+# lp:683112 Maria 5.2 incorrectly reports "(using password: NO)"
+# even when password is specified
#
# test "access denied" error for nonexisting user with and without a password
#
@@ -391,6 +391,31 @@ connect(pcon5,localhost,mysqltest_nouser,newpw,,$MASTER_MYPORT,);
connect(pcon5,localhost,mysqltest_nouser,,,$MASTER_MYPORT,);
connection default;
+
+#
+# MDEV-6253 MySQL Users Break when Migrating from MySQL 5.1 to MariaDB 10.0.10
+#
+# cannot connect when password is set and plugin=mysql_native_password
+#
+update mysql.user set password=authentication_string, authentication_string=''
+ where user like 'mysqltest_up_';
+select user, password, plugin, authentication_string from mysql.user
+ where user like 'mysqltest_up_';
+flush privileges;
+
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+connect(pcon6,localhost,mysqltest_up1,bar,,$MASTER_MYPORT,);
+connection pcon6;
+select user(), current_user();
+disconnect pcon6;
+
+--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+connect(pcon7,localhost,mysqltest_up2,oldpw,,$MASTER_MYPORT,);
+connection pcon7;
+select user(), current_user();
+disconnect pcon7;
+connection default;
+
DROP USER mysqltest_up1@'%';
DROP USER mysqltest_up2@'%';
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 4b1d7604b9d..61ae3695a1f 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -465,6 +465,7 @@ drop table t1;
#
# MDEV-5012 Server crashes in Item_ref::real_item on EXPLAIN with select subqueries or views, constant table, derived_merge+derived_with_keys
#
+set @save_derived_optimizer_switch_bug=@@optimizer_switch;
SET optimizer_switch = 'derived_merge=on,derived_with_keys=on,in_to_exists=on';
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (8);
@@ -473,5 +474,23 @@ INSERT INTO t2 VALUES (1),(7);
EXPLAIN SELECT * FROM (SELECT * FROM t1) AS table1,
(SELECT DISTINCT * FROM t2) AS table2 WHERE b = a AND a <> ANY (SELECT 9);
DROP TABLE t1, t2;
+set optimizer_switch=@save_derived_optimizer_switch_bug;
+
+--echo #
+--echo # MDEV-6163: Error while executing an update query that has the
+--echo # same table in a sub-query
+--echo #
+
+set @save_derived_optimizer_switch_bug=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+create table t1 (balance float, accountId varchar(64), primary key (accountId));
+
+insert into t1 (accountId,balance) values
+('dealer-1',199354.0),('dealer-2',0),('dealer-3',0),('dealer-5',0),('FINANCE',-200000),('OPERATOR',0);
+
+update t1 set balance=(select sum(balance) from (SELECT balance FROM t1 where accountId like 'dealer%') AS copied) where accountId = 'OPERATOR';
+set optimizer_switch=@save_derived_optimizer_switch_bug;
+drop table t1;
+
set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test
index 626309330b7..c5d442ebe49 100644
--- a/mysql-test/t/dyncol.test
+++ b/mysql-test/t/dyncol.test
@@ -640,6 +640,13 @@ SELECT COLUMN_ADD( dyncol, 'a', '22:22:22', 'c', REPEAT('x',270) AS CHAR ) FROM
DROP table t1;
--echo #
+--echo # MDEV-4858 Wrong results for a huge unsigned value inserted into a TIME column
+--echo #
+SELECT
+ column_get(column_create(1, -999999999999999 AS int), 1 AS TIME) AS t1,
+ column_get(column_create(1, -9223372036854775808 AS int), 1 AS TIME) AS t2;
+
+--echo #
--echo # end of 5.3 tests
--echo #
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index 44fd0b274e8..8b1f0ca108e 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -572,3 +572,297 @@ select release_lock(repeat('a', 193));
--echo #
--echo # End of 5.5 tests
--echo #
+
+
+--echo
+--echo # --
+--echo # -- WL#5787: IPv6-capable INET_ATON and INET_NTOA functions.
+--echo # --
+
+--echo
+--echo # -- INET6_ATON: checking NULL, invalid types, out-of range values...
+--echo
+
+SELECT INET6_ATON(NULL) IS NULL;
+SELECT INET6_ATON(123) IS NULL;
+SELECT INET6_ATON(123.45) IS NULL;
+SELECT INET6_ATON(NOW()) IS NULL;
+
+SELECT INET6_ATON('1.2.3') IS NULL;
+SELECT INET6_ATON('1.2.3.') IS NULL;
+SELECT INET6_ATON('1..3.4') IS NULL;
+SELECT INET6_ATON('-1.2.3.4') IS NULL;
+SELECT INET6_ATON('1.2.3.256') IS NULL;
+SELECT INET6_ATON('1.2.3.4.5') IS NULL;
+SELECT INET6_ATON('0001.2.3.4') IS NULL;
+SELECT INET6_ATON('0x1.2.3.4') IS NULL;
+SELECT INET6_ATON('a.2.3.4') IS NULL;
+
+SELECT INET6_ATON('1.2.3.4:80') IS NULL;
+SELECT INET6_ATON('1.2.3.4/32') IS NULL;
+
+SELECT INET6_ATON('mysql.com') IS NULL;
+
+SELECT INET6_ATON(':::') IS NULL;
+SELECT INET6_ATON(':1:2:3') IS NULL;
+SELECT INET6_ATON('1:2:3:') IS NULL;
+SELECT INET6_ATON(':1::2:3') IS NULL;
+SELECT INET6_ATON('1::2:3:') IS NULL;
+SELECT INET6_ATON('::00001') IS NULL;
+SELECT INET6_ATON('::00001:2') IS NULL;
+SELECT INET6_ATON('::12345') IS NULL;
+SELECT INET6_ATON('1020::3040::5060') IS NULL;
+SELECT INET6_ATON('::ABCZ') IS NULL;
+
+SELECT INET6_ATON('::0x1.2.3.4') IS NULL;
+SELECT INET6_ATON('::1.0x2.3.4') IS NULL;
+SELECT INET6_ATON('::a.b.c.d') IS NULL;
+
+SELECT INET6_ATON('::FFFF:0x1.2.3.4') IS NULL;
+SELECT INET6_ATON('::FFFF:1.0x2.3.4') IS NULL;
+SELECT INET6_ATON('::FFFF:a.b.c.d') IS NULL;
+
+SELECT INET6_ATON('::1.2.3.4:ABCD') IS NULL;
+
+--echo # NOTE: such addresses are supported because getaddrinfo() supports them.
+--echo # This is just to record the current behaviour.
+SELECT HEX(INET6_ATON('::ABCD:1.2.3.4'));
+
+--echo
+--echo # -- INET6_ATON: checking binary representation...
+--echo
+
+SELECT HEX(INET6_ATON('0.0.0.0'));
+SELECT HEX(INET6_ATON('00.00.00.00'));
+SELECT HEX(INET6_ATON('000.000.000.000'));
+SELECT HEX(INET6_ATON('1.2.3.4'));
+SELECT HEX(INET6_ATON('01.02.03.04'));
+SELECT HEX(INET6_ATON('001.002.003.004'));
+SELECT HEX(INET6_ATON('255.255.255.255'));
+SELECT HEX(INET6_ATON('::'));
+SELECT HEX(INET6_ATON('0::0'));
+SELECT HEX(INET6_ATON('1::2'));
+SELECT HEX(INET6_ATON('0::'));
+SELECT HEX(INET6_ATON('1::'));
+SELECT HEX(INET6_ATON('::0'));
+SELECT HEX(INET6_ATON('::1'));
+SELECT HEX(INET6_ATON('1:2:3:4:5:6:7:8'));
+SELECT HEX(INET6_ATON('::2:3:4:5:6:7:8'));
+SELECT HEX(INET6_ATON('1::3:4:5:6:7:8'));
+SELECT HEX(INET6_ATON('1:2::4:5:6:7:8'));
+SELECT HEX(INET6_ATON('1:2:3::5:6:7:8'));
+SELECT HEX(INET6_ATON('1:2:3:4::6:7:8'));
+SELECT HEX(INET6_ATON('1:2:3:4:5::7:8'));
+SELECT HEX(INET6_ATON('1:2:3:4:5:6::8'));
+SELECT HEX(INET6_ATON('1:2:3:4:5:6:7::'));
+SELECT HEX(INET6_ATON('0000:0000::0000:0001'));
+SELECT HEX(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed'));
+SELECT HEX(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+SELECT HEX(INET6_ATON('::C0A8:0102'));
+SELECT HEX(INET6_ATON('::c0a8:0102'));
+SELECT HEX(INET6_ATON('::192.168.1.2'));
+SELECT HEX(INET6_ATON('::FfFf:C0a8:0102'));
+SELECT HEX(INET6_ATON('::ffff:c0a8:0102'));
+SELECT HEX(INET6_ATON('::ffff:192.168.1.2'));
+SELECT HEX(INET6_ATON('::01.2.3.4'));
+SELECT HEX(INET6_ATON('::1.02.3.4'));
+SELECT HEX(INET6_ATON('::1.2.03.4'));
+SELECT HEX(INET6_ATON('::1.2.3.04'));
+SELECT HEX(INET6_ATON('::1.2.3.00'));
+SELECT HEX(INET6_ATON('::FFFF:01.2.3.4'));
+SELECT HEX(INET6_ATON('::FFFF:1.02.3.4'));
+SELECT HEX(INET6_ATON('::FFFF:1.2.03.4'));
+SELECT HEX(INET6_ATON('::FFFF:1.2.3.04'));
+SELECT HEX(INET6_ATON('::FFFF:1.2.3.00'));
+
+--echo
+--echo # -- INET6_ATON: checking the length is either 4 or 16...
+--echo
+
+SELECT LENGTH(INET6_ATON('0.0.0.0'));
+SELECT LENGTH(INET6_ATON('255.255.255.255'));
+SELECT LENGTH(INET6_ATON('::'));
+SELECT LENGTH(INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+
+--echo
+--echo # -- INET6_NTOA: checking NULL, invalid types, out-of range values...
+--echo
+
+SELECT INET6_NTOA(NULL);
+SELECT INET6_NTOA(123);
+SELECT INET6_NTOA(123.456);
+SELECT INET6_NTOA(NOW());
+SELECT INET6_NTOA(UNHEX('C0A801')); # 3 bytes -> NULL
+SELECT INET6_NTOA(UNHEX('C0A80102')); # 4 bytes -> 192.168.1.2
+SELECT INET6_NTOA(UNHEX('C0A8010203')); # 5 bytes -> NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F')); # 15 bytes -> NULL
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F10')); # 16 bytes -> IP
+SELECT INET6_NTOA(UNHEX('0102030405060708090A0B0C0D0E0F1011')); # 17 bytes -> NULL
+
+SELECT INET6_NTOA('1234'), INET6_NTOA(BINARY('1234'));
+SELECT INET6_NTOA('0123456789abcdef'), INET6_NTOA(BINARY('0123456789abcdef'));
+
+--echo
+--echo # -- Checking double-conversion...
+--echo
+
+SELECT INET6_NTOA(INET6_ATON('::'));
+SELECT INET6_NTOA(INET6_ATON('0::0'));
+SELECT INET6_NTOA(INET6_ATON('1::2'));
+SELECT INET6_NTOA(INET6_ATON('0::'));
+SELECT INET6_NTOA(INET6_ATON('1::'));
+SELECT INET6_NTOA(INET6_ATON('::0'));
+SELECT INET6_NTOA(INET6_ATON('::1'));
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7:8'));
+SELECT INET6_NTOA(INET6_ATON('::2:3:4:5:6:7:8'));
+SELECT INET6_NTOA(INET6_ATON('1::3:4:5:6:7:8'));
+SELECT INET6_NTOA(INET6_ATON('1:2::4:5:6:7:8'));
+SELECT INET6_NTOA(INET6_ATON('1:2:3::5:6:7:8'));
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4::6:7:8'));
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5::7:8'));
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6::8'));
+SELECT INET6_NTOA(INET6_ATON('1:2:3:4:5:6:7::'));
+SELECT INET6_NTOA(INET6_ATON('0000:0000::0000:0001'));
+SELECT INET6_NTOA(INET6_ATON('1234:5678:9abc:def0:4321:8765:cba9:0fed'));
+SELECT INET6_NTOA(INET6_ATON('0000:0000:0000:0000:0000:0000:0000:0001'));
+SELECT INET6_NTOA(INET6_ATON('::C0A8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::c0a8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::192.168.1.2'));
+SELECT INET6_NTOA(INET6_ATON('::FfFf:C0a8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::ffff:c0a8:0102'));
+SELECT INET6_NTOA(INET6_ATON('::ffff:192.168.1.2'));
+SELECT INET6_NTOA(INET6_ATON('::01.2.3.4'));
+SELECT INET6_NTOA(INET6_ATON('::1.02.3.4'));
+SELECT INET6_NTOA(INET6_ATON('::1.2.03.4'));
+SELECT INET6_NTOA(INET6_ATON('::1.2.3.04'));
+SELECT INET6_NTOA(INET6_ATON('::1.2.3.00'));
+SELECT INET6_NTOA(INET6_ATON('::FFFF:01.2.3.4'));
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.02.3.4'));
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.2.03.4'));
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.2.3.04'));
+SELECT INET6_NTOA(INET6_ATON('::FFFF:1.2.3.00'));
+
+--echo
+--echo # -- Comparing INET_ATON() and INET6_ATON()...
+--echo
+
+SELECT HEX(INET_ATON('192.168.1.2'));
+SELECT HEX(INET6_ATON('192.168.1.2'));
+
+SELECT HEX(INET_ATON('255.255.255.255'));
+SELECT HEX(INET6_ATON('255.255.255.255'));
+
+SELECT HEX(INET_ATON('192.168.08.2'));
+SELECT HEX(INET6_ATON('192.168.08.2'));
+
+SELECT HEX(INET_ATON('192.168.0x8.2'));
+SELECT HEX(INET6_ATON('192.168.0x8.2'));
+
+SELECT HEX(INET_ATON('1.2.255'));
+SELECT HEX(INET6_ATON('1.2.255'));
+
+SELECT HEX(INET_ATON('1.2.256'));
+SELECT HEX(INET6_ATON('1.2.256'));
+
+SELECT HEX(INET_ATON('1.0002.3.4'));
+SELECT HEX(INET6_ATON('1.0002.3.4'));
+
+SELECT HEX(INET_ATON('1.2.3.4.5'));
+SELECT HEX(INET6_ATON('1.2.3.4.5'));
+
+--echo
+--echo # -- Checking mix of INET- and INET6- functions...
+--echo
+
+SELECT HEX(INET6_ATON(INET_NTOA(INET_ATON('1.2.3.4')))) AS x;
+
+--echo
+--echo # -- Checking IS_IPV4() / IS_IPV6()...
+--echo
+
+SELECT IS_IPV4(NULL);
+SELECT IS_IPV4(1);
+SELECT IS_IPV4(1.0);
+SELECT IS_IPV4('1.2.3.4');
+SELECT IS_IPV4('001.02.000.255');
+SELECT IS_IPV4('::1.2.0.255');
+SELECT IS_IPV4('::1');
+SELECT IS_IPV4(BINARY('1.2.3.4'));
+
+SELECT IS_IPV6(NULL);
+SELECT IS_IPV6(1);
+SELECT IS_IPV6(1.0);
+SELECT IS_IPV6('1.2.3.4');
+SELECT IS_IPV6('001.02.000.255');
+SELECT IS_IPV6('::001.02.000.255');
+SELECT IS_IPV6('::1.2.0.255');
+SELECT IS_IPV6('::1');
+SELECT IS_IPV6('0000:0000:0000:0000:0000:0000:0000:0001');
+SELECT IS_IPV6(BINARY('0000:0000:0000:0000:0000:0000:0000:0001'));
+
+--echo
+--echo # -- Checking IS_IPV4_MAPPED() and IS_IPV4_COMPAT()...
+--echo
+
+SELECT IS_IPV4_MAPPED(INET6_ATON('1.2.3.4')),
+ IS_IPV4_COMPAT(INET6_ATON('1.2.3.4'));
+SELECT IS_IPV4_MAPPED(INET6_ATON('::1.2.3.4')),
+ IS_IPV4_COMPAT(INET6_ATON('::1.2.3.4'));
+SELECT IS_IPV4_MAPPED(INET6_ATON('::FFFF:1.2.3.4')),
+ IS_IPV4_COMPAT(INET6_ATON('::FFFF:1.2.3.4'));
+SELECT IS_IPV4_MAPPED(INET6_ATON('::ABCD:1.2.3.4')),
+ IS_IPV4_COMPAT(INET6_ATON('::ABCD:1.2.3.4'));
+SELECT IS_IPV4_MAPPED(INET6_ATON('::1')),
+ IS_IPV4_COMPAT(INET6_ATON('::1'));
+SELECT IS_IPV4_MAPPED(INET6_ATON('::')),
+ IS_IPV4_COMPAT(INET6_ATON('::'));
+
+# NOTE: IS_IPV4_COMPAT() / IS_IPV4_MAPPED() could work with "regular strings in
+# binary collation" too, but there is no way to create a "regular string"
+# starting with \0.
+
+--echo
+--echo # -- Checking IS_IPV4_COMPAT()...
+--echo
+
+--echo
+--echo # -- Working with a table...
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1(ip INT UNSIGNED);
+CREATE TABLE t2(ip VARBINARY(16));
+
+--echo
+
+INSERT INTO t1 VALUES
+ (INET_ATON('1.2.3.4')), (INET_ATON('255.255.255.255'));
+SELECT INET_NTOA(ip) FROM t1;
+
+--echo
+
+INSERT INTO t2 SELECT INET6_ATON(INET_NTOA(ip)) FROM t1;
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+DELETE FROM t2;
+
+--echo
+
+INSERT INTO t2 VALUES
+ (INET6_ATON('1.2.3.4')), (INET6_ATON('255.255.255.255')),
+ (INET6_ATON('::1.2.3.4')), (INET6_ATON('::ffff:255.255.255.255')),
+ (INET6_ATON('::')), (INET6_ATON('::1')),
+ (INET6_ATON('1020:3040:5060:7080:90A0:B0C0:D0E0:F010'));
+SELECT INET6_NTOA(ip), HEX(ip), LENGTH(ip) FROM t2;
+
+--echo
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+--echo
+--echo # -- Done.
+--echo
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index ed11333dd95..61a237cb447 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1407,6 +1407,18 @@ insert into t1 values (null),(8);
select group_concat( i ), make_set( i, 'a', 'b' ) field from t1 group by field;
drop table t1;
+--echo #
+--echo # Bug#11766684 59851: UNINITIALISED VALUE IN ITEM_FUNC_LIKE::SELECT_OPTIMIZE WITH SUBQUERY AND
+--echo #
+
+CREATE TABLE t2(a INT, KEY(a));
+INSERT INTO t2 VALUES (1),(2);
+CREATE TABLE t1(b INT, PRIMARY KEY(b));
+INSERT INTO t1 VALUES (0),(254);
+SELECT 1 FROM t2 WHERE a LIKE
+(SELECT EXPORT_SET(1, b, b, b, b) FROM t1 LIMIT 1);
+DROP TABLE t1, t2;
+
--echo End of 5.1 tests
--echo #
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index b65e634ea61..6bea1aab392 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1126,7 +1126,11 @@ drop table t1;
#
# lp:737092 Assertion `item->null_value' failed in get_datetime_value in 5.1-micro
#
+SET timestamp=UNIX_TIMESTAMP('2014-04-14 10:10:10');
select now() > coalesce(time('21:43:24'), date('2010-05-03'));
+SET timestamp=UNIX_TIMESTAMP('2014-04-14 22:22:22');
+select now() > coalesce(time('21:43:24'), date('2010-05-03'));
+SET timestamp=DEFAULT;
#
# lp:737104 Crash in DTCollation::set in 5.1-micro
@@ -1170,9 +1174,12 @@ insert into t1 values ('0000-00-00 00:00:00');
select cast(f1 AS time) from t1;
drop table t1;
+SET timestamp=UNIX_TIMESTAMP('2014-06-01 10:20:30');
select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
+select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01';
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
+SET timestamp=DEFAULT;
select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010');
@@ -1340,6 +1347,7 @@ DROP TABLE t1;
--echo #
--echo # MDEV-4870 Wrong values of CASE, COALESCE, IFNULL on a combination of different temporal types
--echo #
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
CREATE TABLE t1 (dt2 DATETIME(2), t3 TIME(3), d DATE);
INSERT INTO t1 VALUES ('2001-01-01 00:00:00.12', '00:00:00.567', '2002-01-01');
SELECT CASE WHEN 0 THEN dt2 ELSE t3 END FROM t1;
@@ -1359,7 +1367,7 @@ SELECT CONCAT(COALESCE(dt2, t3)) FROM t1;
SELECT IFNULL(dt2, t3), CONCAT(IFNULL(dt2, t3)) FROM t1;
SELECT IFNULL(d, t3), CONCAT(IFNULL(d, t3)) FROM t1;
DROP TABLE t1;
-
+SET timestamp=DEFAULT;
--echo #
--echo # MDEV-4724 Some temporal functions do not preserve microseconds
@@ -1522,6 +1530,11 @@ SELECT 1 FROM t1 GROUP BY MONTHNAME(0) WITH ROLLUP;
DROP TABLE t1;
--echo #
+--echo # MDEV-6099 Bad results for DATE_ADD(.., INTERVAL 2000000000000000000.0 SECOND)
+--echo #
+SELECT DATE_ADD('2001-01-01 10:20:30',INTERVAL 250000000000.0 SECOND) AS c1, DATE_ADD('2001-01-01 10:20:30',INTERVAL 2000000000000000000.0 SECOND) AS c2;
+
+--echo #
--echo # MDEV-4838 Wrong metadata for DATE_ADD('string', INVERVAL)
--echo #
--enable_metadata
@@ -1566,3 +1579,13 @@ CREATE TABLE t1 (dt DATETIME);
INSERT INTO t1 VALUES ('2003-05-13 19:36:05'), ('2012-12-12 09:20:06');
SELECT COALESCE(ADDDATE(MAKEDATE(2011,121), dt), '2006-09-12' ) FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-6101 Hybrid functions do not add CURRENT_DATE when converting TIME to DATETIME
+--echo #
+SET timestamp=UNIX_TIMESTAMP('2014-04-15 01:02:03');
+SELECT IF(1,TIME'10:20:30',DATE'2001-01-01');
+SELECT IFNULL(TIME'10:20:30',DATE'2001-01-01');
+SELECT CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END;
+SELECT COALESCE(TIME'10:20:30',DATE'2001-01-01');
+SET timestamp=DEFAULT;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index cb2b1ab5f3d..ed7271521c8 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1852,9 +1852,6 @@ revoke select on Foo.* from myuser@localhost;
delete from mysql.user where User='myuser';
flush privileges;
-# Wait till we reached the initial number of concurrent sessions
---source include/wait_until_count_sessions.inc
-
--echo #########################################################################
--echo #
--echo # Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
@@ -2177,3 +2174,39 @@ DROP USER mysqltest_u1@localhost;
--echo
--echo # End of Bug#38347.
--echo
+
+--echo #
+--echo # Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS
+--echo # DATABASE SECURITY
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS secret;
+DROP DATABASE IF EXISTS no_such_db;
+--enable_warnings
+
+CREATE DATABASE secret;
+GRANT USAGE ON *.* TO untrusted@localhost;
+
+--echo # Connection con1
+connect (con1, localhost, untrusted);
+SHOW GRANTS;
+SHOW DATABASES;
+
+--echo # Both statements below should fail with the same error.
+--echo # They used to give different errors, thereby
+--echo # hinting that the secret database exists.
+--error ER_DBACCESS_DENIED_ERROR
+CREATE PROCEDURE no_such_db.foo() BEGIN END;
+--error ER_DBACCESS_DENIED_ERROR
+CREATE PROCEDURE secret.peek_at_secret() BEGIN END;
+
+--echo # Connection default
+--connection default
+disconnect con1;
+DROP USER untrusted@localhost;
+DROP DATABASE secret;
+
+# Wait till we reached the initial number of concurrent sessions
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index a1ca0bce1d1..09a3f590a1f 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -738,7 +738,7 @@ create temporary table schemata(f1 char(10));
# Bug#10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA
#
delimiter |;
---error ER_BAD_DB_ERROR
+--error ER_DBACCESS_DENIED_ERROR
CREATE PROCEDURE p1 ()
BEGIN
SELECT 'foo' FROM DUAL;
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index b40fee20e11..c60a06f0b0b 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -3700,5 +3700,26 @@ select @counter;
drop table t1,t2,t3;
set expensive_subquery_limit=default;
+--echo #
+--echo # mdev-6071: EXPLAIN chooses to use join buffer while execution turns it down
+--echo #
+
+create table t1 (a int);
+insert into t1 values
+(7), (9), (1), (4), (2), (3), (5), (8), (11), (6), (10);
+
+explain select count(*) from t1, t1 t2 where t1.a=t2.a;
+
+set join_buffer_space_limit=1024*8;
+select @@join_buffer_space_limit;
+select @@join_buffer_size;
+
+explain select count(*) from t1, t1 t2 where t1.a=t2.a;
+
+set join_buffer_space_limit=default;
+
+drop table t1;
+
+# The following command must be the last one the file
# this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index bf84bdf9194..35243864c04 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -637,3 +637,24 @@ create table t1(a point);
drop table t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # Bug#11759519 INFINITE HANG WITH 100% CPU USAGE WITH LOAD DATA LOCAL AND IMPORT ERRORS
+--echo #
+SET @old_mode= @@sql_mode;
+CREATE TABLE t1 (fld1 INT);
+--copy_file $EXE_MYSQL $MYSQLTEST_VARDIR/mysql
+
+SET sql_mode='strict_all_tables';
+
+--echo # Without fix, load data hangs forever.
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,1000
+eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/mysql' REPLACE INTO TABLE t1
+ FIELDS TERMINATED BY 't' LINES TERMINATED BY '';
+
+SET @@sql_mode= @old_mode;
+
+--remove_file $MYSQLTEST_VARDIR/mysql
+DROP TABLE t1;
+
diff --git a/mysql-test/t/myisampack.test b/mysql-test/t/myisampack.test
index ac47d521930..1f97a28e6fd 100644
--- a/mysql-test/t/myisampack.test
+++ b/mysql-test/t/myisampack.test
@@ -268,6 +268,53 @@ FLUSH TABLE t1;
CHECK TABLE t1;
DROP TABLE t1;
+#
+# MDEV-6245 Certain compressed tables with myisampack are corrupted by
+# "CHECK TABLE"
+#
+# Issue was that checksum failed for tables with NULL and VARCHAR fields
+#
+
+create table `t1` (`id` varchar(15) DEFAULT NULL) ENGINE=MyISAM ROW_FORMAT=FIXED;
+insert into t1 values ('aaa'),('bbb'),('ccc'),('ddd'),('eee');
+insert into t1 (select * from t1);
+insert into t1 (select * from t1);
+insert into t1 (select * from t1);
+insert into t1 (select * from t1);
+checksum table t1;
+insert into t1 values(NULL);
+checksum table t1;
+flush table t1;
+--exec $MYISAMPACK -sf $MYSQLD_DATADIR/test/t1
+--exec $MYISAMCHK -srnq $MYSQLD_DATADIR/test/t1
+check table t1;
+checksum table t1;
+alter table t1 checksum=1 row_format=fixed;
+checksum table t1;
+flush table t1;
+--exec $MYISAMPACK -sf $MYSQLD_DATADIR/test/t1
+--exec $MYISAMCHK -srnq $MYSQLD_DATADIR/test/t1
+check table t1;
+checksum table t1;
+
+# Testing with row_format=dynamic
+
+alter table t1 row_format=dynamic checksum=0;
+checksum table t1;
+flush table t1;
+--exec $MYISAMPACK -sf $MYSQLD_DATADIR/test/t1
+--exec $MYISAMCHK -srnq $MYSQLD_DATADIR/test/t1
+check table t1;
+checksum table t1;
+alter table t1 checksum=1 row_format=dynamic;
+checksum table t1;
+flush table t1;
+--exec $MYISAMPACK -sf $MYSQLD_DATADIR/test/t1
+--exec $MYISAMCHK -srnq $MYSQLD_DATADIR/test/t1
+check table t1;
+checksum table t1;
+drop table t1;
+
--echo #
--echo # BUG#11751736: DROP DATABASE STATEMENT SHOULD REMOVE .OLD SUFFIX FROM
--echo # DATABASE DIRECTORY
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index c4a85e4b111..cf6a4d473c3 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1947,4 +1947,14 @@ drop table t1,t2,t3;
--echo End of 5.5 tests
-
+--echo #
+--echo # MDEV-5884: EXPLAIN UPDATE ... ORDER BY LIMIT shows wrong #rows
+--echo #
+create table t2(a int);
+insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (key1 int, col1 int, key(key1));
+insert into t1
+select A.a + 10 * B.a + 100 * C.a, 1234 from t2 A, t2 B, t2 C;
+--echo # Should show rows=2, not rows=100
+explain update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2;
+drop table t1,t2;
diff --git a/mysql-test/t/outfile_loaddata.test b/mysql-test/t/outfile_loaddata.test
index 26760f9a1b2..745c75cb4de 100644
--- a/mysql-test/t/outfile_loaddata.test
+++ b/mysql-test/t/outfile_loaddata.test
@@ -169,6 +169,8 @@ TRUNCATE t2;
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary FIELDS TERMINATED BY 'ÑŠ'
--remove_file $file
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
+SELECT * FROM t1;
+SELECT * FROM t2;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval SELECT * FROM t1 INTO OUTFILE '$file' LINES STARTING BY 'ÑŠ'
@@ -191,6 +193,8 @@ TRUNCATE t2;
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary LINES TERMINATED BY 'ÑŠ'
--remove_file $file
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
+SELECT * FROM t1;
+SELECT * FROM t2;
--echo # Default (binary) charset:
diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test
index e7e764ce138..4c97bab454d 100644
--- a/mysql-test/t/partition_pruning.test
+++ b/mysql-test/t/partition_pruning.test
@@ -1412,3 +1412,60 @@ explain partitions select * from t1 where a between 10 and 13;
explain partitions select * from t1 where a between 10 and 10+33;
drop table t0, t1;
+
+--echo #
+--echo # MDEV-6239: Partition pruning is not working as expected in an inner query
+--echo #
+
+create table t1
+(
+ company_id bigint(5),
+ dept_id bigint(5),
+ emp_id bigint(5),
+ emp_name varchar(100),
+ primary key (company_id, emp_id)
+) partition by list (company_id) (
+ partition p_1000 values in (1000),
+ partition p_2000 values in (2000),
+ partition p_3000 values in (3000)
+);
+
+create table t2
+(
+ company_id bigint(5),
+ dept_id bigint(5),
+ dept_name varchar(100),
+ primary key (company_id, dept_id)
+) partition by list (company_id) (
+ partition p_1000 values in (1000),
+ partition p_2000 values in (2000),
+ partition p_3000 values in (3000)
+);
+
+insert into t2 values
+ (1000, 10, 'Engineering'),
+ (1000, 20, 'Product Management'),
+ (1000, 30, 'QA'),
+ (2000, 40, 'Support'),
+ (2000, 50, 'Professional Services');
+
+insert into t1 values
+(1000, 10, 1, 'John'),
+(1000, 10, 2, 'Smith'),
+(1000, 20, 3, 'Jacob'),
+(1000, 20, 4, 'Brian'),
+(1000, 30, 5, 'Chris'),
+(1000, 30, 6, 'Ryan'),
+(2000, 40, 7, 'Karin'),
+(2000, 40, 8, 'Jay'),
+(2000, 50, 9, 'Ana'),
+(2000, 50, 10, 'Jessica');
+
+--echo # Table t2 should have only partition p_1000.
+explain partitions
+select * from t1
+where company_id = 1000
+and dept_id in (select dept_id from t2 where COMPANY_ID = 1000);
+
+drop table t1,t2;
+
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 9775a8dc28e..0233b2e428b 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -677,8 +677,8 @@ insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
create table t3 (
id int(11) not null default '0',
- preceeding_id int(11) not null default '0',
- primary key (id,preceeding_id)
+ preceding_id int(11) not null default '0',
+ primary key (id,preceding_id)
);
create table t4 (
@@ -692,7 +692,7 @@ insert into t4 values("nicke", "imp");
prepare stmt from
'select distinct t1.partner_id
from t1 left join t3 on t1.id = t3.id
- left join t1 pp on pp.id = t3.preceeding_id
+ left join t1 pp on pp.id = t3.preceding_id
where
exists (
select *
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index f0434f50c98..7b68f42c4cb 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1640,6 +1640,45 @@ DROP TABLE t1;
DROP VIEW v3;
--echo #
+--echo # MDEV-6105: Emoji unicode character string search query makes mariadb performance down
+--echo #
+SET NAMES utf8;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(
+id int AUTO_INCREMENT,
+fd varchar(20),
+primary key(id),
+index ix_fd(fd)
+)engine=innodb default charset=UTF8;
+INSERT INTO t1(id, fd) VALUES (null, ''),(null, 'matt'),(null, 'pitt'),(null, 'lee'),(null, 'kim');
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+INSERT INTO t1 (fd) SELECT fd FROM t1;
+--echo # The following should show "Impossible WHERE" :
+explain
+SELECT * FROM t1 WHERE fd='ðŸ˜';
+SELECT * FROM t1 WHERE fd='ðŸ˜';
+
+--echo # The following must not use range access:
+--replace_column 9 #
+explain select count(*) from t1 where fd <'ðŸ˜';
+select count(*) from t1 where fd <'ðŸ˜';
+select count(*) from t1 ignore index (ix_fd) where fd <'ðŸ˜';
+
+drop table t1;
+set names default;
+
+--echo #
--echo # BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
--echo #
@@ -1706,4 +1745,3 @@ explain select * from t3, t2 where t2.a < t3.b and t3.a=1;
--echo # The second table should use 'range':
explain select * from t3, t2 where t3.b > t2.a and t3.a=1;
drop table t1,t2,t3;
-
diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test
index 684ae54b517..d529dc415e7 100644
--- a/mysql-test/t/select_found.test
+++ b/mysql-test/t/select_found.test
@@ -208,11 +208,10 @@ select f1 from t1,t2 where f1=f3 and f2=3 order by f1;
select found_rows();
drop table t1, t2;
-create table t1 (
- a1 int auto_increment primary key,
- b1 datetime,
- c1 int
-);
+#
+# MDEV-5898 FOUND_ROWS() return incorrect value when using DISTINCT
+#
+create table t1 (a1 int auto_increment primary key, c1 int);
insert t1 (a1) values (null);
insert t1 (a1) select null from t1;
@@ -226,12 +225,7 @@ insert t1 (a1) select null from t1;
insert t1 (a1) select null from t1;
update t1 set c1=a1 % 2;
-create table t2 (
- a2 int,
- b2 int,
- c2 char(16) default '',
- primary key (a2, b2)
-);
+create table t2 (a2 int, b2 int, c2 char(16) default '', primary key (a2, b2));
insert t2 select a1, 1, 'ok' from t1;
insert t2 select a1, 2, 'ko' from t1;
@@ -239,12 +233,27 @@ insert t2 select a1, 3, 'ko' from t1;
insert t2 select a1, 4, 'ok' from t1;
insert t2 select a1, 5, 'ok' from t1;
---disable_result_log
-select sql_calc_found_rows distinct a1,b1,c2 from t1 join t2 on a2=a1
- where a1 <= 256 and c1=0 and c2='ok' order by b1 desc, a1 desc limit 46;
---enable_result_log
+--disable_result_log ONCE
+select sql_calc_found_rows distinct a1,c2 from t1 join t2 on a2=a1
+ where a1 <= 256 and c1=0 and c2='ok' order by a1 desc limit 46;
select found_rows();
drop table t1, t2;
+#
+# MDEV-6221 SQL_CALC_FOUND_ROWS yields wrong result again
+#
+create table t1 (i1 int, v1 int, primary key(i1,v1));
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 (i2 int primary key, v2 int);
+insert into t2 values (1,5),(2,5),(3,10);
+select 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 or v1 = 5 or v1 = 10 order by v1;
+--disable_result_log ONCE
+select sql_calc_found_rows 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 or v1 = 5 or v1 = 10 order by v1 limit 1;
+select found_rows() as count;
+--disable_result_log ONCE
+select sql_calc_found_rows 1 as res from t1 left join t2 on i1 = i2 where v2 = 5 order by v1 limit 1;
+select found_rows() as count;
+drop table t1, t2;
+
diff --git a/mysql-test/t/selectivity_no_engine.test b/mysql-test/t/selectivity_no_engine.test
index 87e6b629762..fc425daff6d 100644
--- a/mysql-test/t/selectivity_no_engine.test
+++ b/mysql-test/t/selectivity_no_engine.test
@@ -30,9 +30,9 @@ insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (col1 int);
--echo # one value in 1..100 range
-insert into t2 select A.a + B.a*10 from t1 A, t1 B;
+insert into t2 select ta.a + tb.a*10 from t1 ta, t1 tb;
--echo # ten values in 100...200 range
-insert into t2 select 100 + A.a + B.a*10 from t1 A, t1 B, t1 C;
+insert into t2 select 100 + ta.a + tb.a*10 from t1 ta, t1 tb, t1 tc;
set histogram_type='SINGLE_PREC_HB';
set histogram_size=100;
@@ -51,7 +51,7 @@ drop table t1, t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(a int);
-insert into t1 select A.a from t0 A, t0 B, t0 C;
+insert into t1 select ta.a from t0 ta, t0 tb, t0 tc;
set histogram_size=20;
set histogram_type='single_prec_hb';
analyze table t1 persistent for all;
@@ -73,8 +73,8 @@ drop table t0, t1;
--echo #
create table t1 (col1 int);
set @a=-1;
-create table t2 (a int) select (@a:=@a+1) as a from information_schema.session_variables A limit 100;
-insert into t1 select A.a from t2 A, t2 B where A.a < 100 and B.a < 100;
+create table t2 (a int) select (@a:=@a+1) as a from information_schema.session_variables ta limit 100;
+insert into t1 select ta.a from t2 ta, t2 tb where ta.a < 100 and tb.a < 100;
select min(col1), max(col1), count(*) from t1;
set histogram_size=100;
analyze table t1 persistent for all;
@@ -91,7 +91,7 @@ create table t1(a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, b int, col1 varchar(64), col2 varchar(64), key(a,b));
-insert into t2 select A.a+10*B.a, C.a+10*D.a, 'filler-data1', 'filler-data2' from t1 A, t1 B, t1 C, t1 D;
+insert into t2 select ta.a+10*tb.a, tc.a+10*td.a, 'filler-data1', 'filler-data2' from t1 ta, t1 tb, t1 tc, t1 td;
set histogram_size=100;
set optimizer_use_condition_selectivity=4;
@@ -108,7 +108,7 @@ drop table t2, t1;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(key1 int, col1 int, key(key1));
-insert into t1 select A.a, A.a from t0 A, t0 B, t0 C;
+insert into t1 select ta.a, ta.a from t0 ta, t0 tb, t0 tc;
set histogram_size=100;
set use_stat_tables='preferably';
@@ -133,11 +133,11 @@ create table t1 (
insert into t1
select
- A.a,
- B.a,
+ ta.a,
+ tb.a,
'filler-data-1',
'filler-data-2'
-from t0 A, t0 B, t0 C;
+from t0 ta, t0 tb, t0 tc;
set histogram_size=100;
set use_stat_tables='preferably';
set optimizer_use_condition_selectivity=4;
@@ -162,6 +162,55 @@ SELECT * FROM t1 AS t1_1, t1 AS t1_2 WHERE NOT ( t1_1.a <> 'baz');
DROP TABLE t1;
--echo #
+--echo # MDEV-6308: Server crashes in table_multi_eq_cond_selectivity with ...
+--echo #
+CREATE TABLE t1 (
+ id varchar(40) COLLATE utf8_bin,
+ dt datetime,
+ PRIMARY KEY (id)
+);
+
+INSERT INTO t1 VALUES ('foo','2011-04-12 05:18:08'),
+ ('bar','2013-09-19 11:37:03');
+
+CREATE TABLE t2 (
+ t1_id varchar(40) COLLATE utf8_bin,
+ f1 varchar(64),
+ f2 varchar(1024),
+ KEY (f1,f2(255))
+);
+
+INSERT INTO t2 VALUES ('foo','baz','qux'),('bar','baz','qux');
+
+set optimizer_use_condition_selectivity=2;
+explain
+select * from t1,t2 where t1.id = t2.t1_id and t2.f2='qux' and t2.f1='baz';
+select * from t1,t2 where t1.id = t2.t1_id and t2.f2='qux' and t2.f1='baz';
+
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-5985: EITS: selectivity estimates look illogical for join and non-key equalities
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select ta.a + tb.a* 10 + tc.a * 100 from t0 ta, t0 tb, t0 tc;
+create table t2 as select * from t1;
+set histogram_size=100;
+set use_stat_tables='preferably';
+set optimizer_use_condition_selectivity=4;
+analyze table t1 persistent for all;
+analyze table t2 persistent for all;
+--echo # Filtered will be 4.95, 9.90
+explain extended select * from t1 ta, t2 tb where ta.a < 40 and tb.a < 100;
+--echo # Here, tb.filtered should not become 100%:
+explain extended select * from t1 ta, t2 tb where ta.a < 40 and tb.a < 100 and tb.a=ta.a;
+
+drop table t0,t1,t2;
+
+--echo #
--echo # End of the test file
--echo #
diff --git a/mysql-test/t/subselect_exists_to_in.test b/mysql-test/t/subselect_exists_to_in.test
deleted file mode 100644
index 1b97aa13955..00000000000
--- a/mysql-test/t/subselect_exists_to_in.test
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Run subselect.test with exists to in transformation
-#
-select @@optimizer_switch like '%exists_to_in=on%';
-set optimizer_switch='exists_to_in=on';
-
---source t/subselect.test
-
-set optimizer_switch=default;
-select @@optimizer_switch like '%exists_to_in=on%';
-
diff --git a/mysql-test/t/subselect_no_exists_to_in.test b/mysql-test/t/subselect_no_exists_to_in.test
new file mode 100644
index 00000000000..7145a4594bc
--- /dev/null
+++ b/mysql-test/t/subselect_no_exists_to_in.test
@@ -0,0 +1,11 @@
+#
+# Run subselect.test with exists to in transformation
+#
+select @@optimizer_switch like '%exists_to_in=off%';
+set optimizer_switch='exists_to_in=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+select @@optimizer_switch like '%exists_to_in=off%';
+
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index 1b0076fd1e6..2c60e5645c3 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -79,6 +79,8 @@ select * from t1 left join (t2 A, t2 B) on ( A.a= t1.a and B.a in (select pk fro
explain extended
select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10));
+set join_buffer_size=8*1024;
+
--echo we shouldn't flatten if we're going to get a join of > MAX_TABLES.
explain select * from
t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -97,6 +99,8 @@ select * from
t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
where t1.a < 5;
+set join_buffer_size=default;
+
#
# Prepared statements
#
@@ -897,8 +901,8 @@ insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"),
("4", "1", "sup", "0");
create table t3 (
id int(11) not null default '0',
- preceeding_id int(11) not null default '0',
- primary key (id,preceeding_id)
+ preceding_id int(11) not null default '0',
+ primary key (id,preceding_id)
);
create table t4 (
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
index 9d9e7848415..a82baf095c1 100644
--- a/mysql-test/t/subselect_sj2.test
+++ b/mysql-test/t/subselect_sj2.test
@@ -1291,5 +1291,34 @@ SELECT * FROM t1, t3 WHERE t3_c IN ( SELECT t1_pk2 FROM t4, t2 WHERE t2_c = t1_p
DROP TABLE t1,t2,t3,t4;
+--echo #
+--echo # MDEV-6263: Wrong result when using IN subquery with order by
+--echo #
+CREATE TABLE t1 (
+ id int(11) NOT NULL,
+ nombre varchar(255) NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO t1 (id, nombre) VALUES
+(1, 'row 1'),(2, 'row 2'),(3, 'row 3'),
+(4, 'row 4'),(5, 'row 5'),(6, 'row 6');
+
+CREATE TABLE t2 (
+ id_algo int(11) NOT NULL,
+ id_agente int(11) NOT NULL,
+ PRIMARY KEY (id_algo,id_agente),
+ KEY another_data (id_agente)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO t2 (id_algo, id_agente) VALUES
+(1, 1),(1, 2),(2, 1),(2, 2),(2, 3),(3, 1);
+
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2) ORDER BY nombre ASC;
+
+SELECT * FROM t1 WHERE id in (select distinct id_agente from t2);
+
+DROP TABLE t1, t2;
+
--echo # This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index b841d8b1def..e44b190def0 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -466,10 +466,12 @@ DROP TABLE t1;
#
# MDEV-4281 Assertion `maybe_null && item->null_value' fails in make_sortkey on CASE with different return types, GROUP_CONCAT, GROUP BY
#
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
create table t1 (d date, t time) engine=myisam;
insert into t1 values ('2000-12-03','22:55:23'),('2008-05-03','10:19:31');
select case when d = '2012-12-12' then d else t end as cond, group_concat( d ) from t1 group by cond;
drop table t1;
+SET timestamp=DEFAULT;
--echo #
--echo # Semantics of the condition <non-nullable datetime field> IS NULL
@@ -519,8 +521,16 @@ END;|
DELIMITER ;|
call test5041();
drop procedure test5041;
-
SET @@timestamp=DEFAULT;
+
+--echo #
+--echo # MDEV-6097 Inconsistent results for CAST(int,decimal,double AS DATETIME)
+--echo #
+SELECT
+ CAST(010203101112 AS DATETIME(1)) AS c1,
+ CAST(010203101112.2 AS DATETIME(1)) AS c2,
+ CAST(010203101112.2+0e0 AS DATETIME(1)) AS c3;
+
--echo End of 5.3 tests
--echo #
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index 1daeec03a08..4f23f7b1bb8 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -115,6 +115,12 @@ create table t1 (f1 time , f2 varchar(5), key(f1));
insert into t1 values ('00:20:01','a'),('00:20:03','b');
select * from t1 force key (f1) where f1 < curdate();
select * from t1 ignore key (f1) where f1 < curdate();
+select * from t1 force key (f1) where f1 > curdate();
+select * from t1 ignore key (f1) where f1 > curdate();
+delete from t1;
+insert into t1 values ('-00:20:01','a'),('-00:20:03','b');
+select * from t1 force key (f1) where f1 < curdate();
+select * from t1 ignore key (f1) where f1 < curdate();
drop table t1;
#
@@ -205,6 +211,23 @@ SELECT * FROM t2;
SHOW COLUMNS FROM t2;
DROP TABLE t2,t1;
+--echo #
+--echo # MDEV-4858 Wrong results for a huge unsigned value inserted into a TIME column
+--echo #
+SET sql_mode=traditional;
+CREATE TABLE t1 (a TIME(6));
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFF00000000 AS UNSIGNED));
+SET sql_mode=DEFAULT;
+INSERT INTO t1 VALUES (CAST(0xFFFFFFFF00000000 AS UNSIGNED));
+SELECT * FROM t1;
+DROP TABLE t1;
+SELECT TIME'00:00:00'> CAST(0xFFFFFFFF00000000 AS UNSIGNED);
+
+--echo #
+--echo # MDEV-6100 No warning on CAST(9000000 AS TIME)
+--echo #
+SELECT CAST(9000000 AS TIME);
--echo #
--echo # End of 5.3 tests
@@ -226,3 +249,19 @@ SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
SELECT '-24:00:00' = (SELECT f1 FROM t1);
DROP TABLE t1;
+--echo #
+--echo # Start of 10.0 tests
+--echo #
+
+
+--echo #
+--echo # MDEV-6102 Comparison between TIME and DATETIME does not use CURRENT_DATE
+--echo #
+SET timestamp=UNIX_TIMESTAMP('2014-04-14 01:02:03');
+SELECT CAST(TIME'10:20:30' AS DATETIME), TIME'10:20:30'=TIMESTAMP'2014-04-14 10:20:30' AS cmp;
+SET timestamp=DEFAULT;
+
+--echo #
+--echo # End of 10.0 tests
+--echo #
+
diff --git a/mysql-test/t/type_time_6065.test b/mysql-test/t/type_time_6065.test
new file mode 100644
index 00000000000..6e29b849be5
--- /dev/null
+++ b/mysql-test/t/type_time_6065.test
@@ -0,0 +1,177 @@
+#
+# MDEV-6065 MySQL Bug#13623473 "MISSING ROWS ON SELECT AND JOIN WITH TIME/DATETIME COMPARE"
+#
+
+# Systematic testing of ref access and range scan
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2012-01-31 10:14:35');
+
+CREATE TABLE t1 (col_time_key TIME, KEY(col_time_key));
+INSERT INTO t1 VALUES ('00:00:00'),('-24:00:00'),('-48:00:00'),('24:00:00'),('48:00:00');
+CREATE TABLE t2 (col_datetime_key DATETIME, KEY(col_datetime_key));
+INSERT INTO t2 SELECT * FROM t1;
+
+let $cnt_0=5;
+let $operator= =;
+# For operator in =, >=, >, <=, <
+while ($cnt_0)
+{
+ let $cnt_1=2;
+ let $first_table=t1;
+ # for table in t1,t2
+ while ($cnt_1)
+ {
+ if ($first_table==t1)
+ {
+ let $first_index=col_time_key;
+ let $second_table=t2;
+ let $second_index=col_datetime_key;
+ }
+ if ($first_table==t2)
+ {
+ let $first_index=col_datetime_key;
+ let $second_table=t1;
+ let $second_index=col_time_key;
+ }
+ let $cnt_2=2;
+ let $first_index_hint=ignore;
+ # for first_index_hint in ignore,force
+ while ($cnt_2)
+ {
+ let $cnt_3=2;
+ let $second_index_hint=ignore;
+ # for second_index_hint in ignore, force
+ while ($cnt_3)
+ {
+ let $cnt_4=2;
+ let $first_operand=col_time_key;
+ # for first_operand in col_time_key, col_datetime_key
+ while ($cnt_4)
+ {
+ if ($first_operand==col_time_key)
+ {
+ let $second_operand=col_datetime_key;
+ }
+ if ($first_operand==col_datetime_key)
+ {
+ let $second_operand=col_time_key;
+ }
+
+ eval EXPLAIN EXTENDED SELECT * FROM
+ $first_table $first_index_hint INDEX ($first_index)
+ STRAIGHT_JOIN
+ $second_table $second_index_hint INDEX ($second_index)
+ WHERE $first_operand $operator $second_operand;
+ --sorted_result
+ eval SELECT * FROM
+ $first_table $first_index_hint INDEX ($first_index)
+ STRAIGHT_JOIN
+ $second_table $second_index_hint INDEX ($second_index)
+ WHERE $first_operand $operator $second_operand;
+
+ let $first_operand=col_datetime_key;
+ dec $cnt_4;
+ }
+ let $second_index_hint=force;
+ dec $cnt_3;
+ }
+ let $first_index_hint=force;
+ dec $cnt_2;
+ }
+ let $first_table=t2;
+ dec $cnt_1;
+ }
+ if ($cnt_0==5)
+ {
+ let $operator= >=;
+ }
+ if ($cnt_0==4)
+ {
+ let $operator= >;
+ }
+ if ($cnt_0==3)
+ {
+ let $operator= <=;
+ }
+ if ($cnt_0==2)
+ {
+ let $operator= <;
+ }
+ dec $cnt_0;
+}
+
+DROP TABLE t1,t2;
+
+#
+# Original test of the bug report
+#
+
+CREATE TABLE t1 (
+ pk INT NOT NULL AUTO_INCREMENT,
+ col_int_nokey INT,
+ col_int_key INT NOT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key)
+);
+
+INSERT INTO t1 VALUES (10,1,7), (11,7,0), (12,4,9), (13,7,3),
+(14,0,4), (15,2,2), (16,9,5), (17,4,3), (18,0,1), (19,9,3), (20,1,6),
+(21,3,7), (22,8,5), (23,8,1), (24,18,204), (25,84,224), (26,6,9),
+(27,3,5), (28,6,0), (29,6,3);
+
+CREATE TABLE t2 (
+ col_int_nokey INT NOT NULL,
+ col_datetime_key DATETIME NOT NULL,
+ col_varchar_key VARCHAR(1) NOT NULL,
+ KEY col_datetime_key (col_datetime_key),
+ KEY col_varchar_key (col_varchar_key)
+);
+
+INSERT INTO t2 VALUES (1,'2001-11-04 19:07:55','k');
+
+CREATE TABLE t3 (
+ col_time_key TIME,
+ KEY col_time_key (col_time_key)
+);
+
+INSERT INTO t3 VALUES ('21:22:34'), ('10:50:38'), ('00:21:38'),
+('04:08:02'), ('16:25:11'), ('10:14:58'), ('19:47:59'), ('11:14:24'),
+('00:00:00'), ('00:00:00'), ('15:57:25'), ('07:05:51'), ('19:22:21'),
+('03:53:16'), ('09:16:38'), ('15:37:26'), ('00:00:00'), ('05:03:03'),
+('02:59:24'), ('00:01:58');
+
+let $query=SELECT * FROM t2 STRAIGHT_JOIN t3 FORCE INDEX (col_time_key)
+ ON t3.col_time_key > t2.col_datetime_key;
+eval EXPLAIN EXTENDED $query;
+--sorted_result
+eval $query;
+
+let $query=SELECT * FROM t2 STRAIGHT_JOIN t3 IGNORE INDEX (col_time_key)
+ ON t3.col_time_key > t2.col_datetime_key;
+eval EXPLAIN EXTENDED $query;
+--sorted_result
+eval $query;
+
+let $query=SELECT outr.col_int_nokey
+FROM t2 as outr
+ STRAIGHT_JOIN t3 AS outr2
+ ON outr2.col_time_key > outr.col_datetime_key
+WHERE outr.col_int_nokey IN (
+ SELECT col_int_key
+ FROM t1 AS innr
+ WHERE innr.pk >= innr.col_int_nokey
+) AND (
+ outr.col_int_nokey <= 6
+ OR
+ outr.col_varchar_key IS NULL
+);
+eval EXPLAIN EXTENDED $query;
+--sorted_result
+eval $query;
+
+DROP TABLE t1,t2,t3;
+SET TIMESTAMP=0; # back to current time
+
+#
+# End of 10.0 tests
+#
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index a53427f7fc6..877509a9fc0 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1274,8 +1274,8 @@ SELECT(SELECT 1 AS a LIMIT 1) AS dev;
SELECT(SELECT 1 AS a FROM dual ORDER BY a DESC LIMIT 1) AS dev;
--echo #
---echo # LP bug#1010729: Unexpected syntax error from UNION
---echo # (bug #54382) with single-table join nest
+--echo # lp:1010729: Unexpected syntax error from UNION
+--echo # (bug #54382) with single-table join nest
--echo #
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int);
@@ -1292,3 +1292,11 @@ SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk);
DROP TABLE t1,t2;
+#
+# Bug #18167356: EXPLAIN W/ EXISTS(SELECT* UNION SELECT*)
+# WHERE ONE OF SELECT* IS DISTINCT FAILS.
+#
+create table t1 (a int);
+insert t1 values (1),(2),(3),(1);
+explain select 1 from dual where exists (select max(a) from t1 group by a union select a+2 from t1);
+drop table t1;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index e36e22bdfac..d1d4b936aba 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1,7 +1,7 @@
--disable_warnings
-drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
-drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
+drop table if exists t1,t2,t3,t4,t5,t6,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
+drop view if exists t1,t2,t3,t4,t5,t6,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
drop database if exists mysqltest;
--enable_warnings
use test;
@@ -4083,6 +4083,118 @@ select * from t2;
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
+--echo #
+--echo # MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
+--echo # with MERGE view)
+--echo #
+
+CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+
+CREATE OR REPLACE view v1 AS
+ SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+;
+
+SELECT 1
+FROM (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t1)
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t2) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t3) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t4) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t5) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t6) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t7) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t8) ON 1=1
+;
+
+SELECT 1
+FROM (v1 t1)
+LEFT OUTER JOIN (v1 t2) ON 1=1
+LEFT OUTER JOIN (v1 t3) ON 1=1
+LEFT OUTER JOIN (v1 t4) ON 1=1
+LEFT OUTER JOIN (v1 t5) ON 1=1
+LEFT OUTER JOIN (v1 t6) ON 1=1
+LEFT OUTER JOIN (v1 t7) ON 1=1
+LEFT OUTER JOIN (v1 t8) ON 1=1
+;
+
+drop view v1;
+drop table t1,t2,t3,t4,t5,t6;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.2 tests.
--echo # -----------------------------------------------------------------
@@ -4971,6 +5083,119 @@ execute stmt1;
deallocate prepare stmt1;
drop view v1,v2;
drop table t1,t2;
+
+--echo #
+--echo # MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized
+--echo # with MERGE view)
+--echo #
+
+CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY);
+
+CREATE OR REPLACE view v1 AS
+ SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+;
+
+SELECT 1
+FROM (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t1)
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t2) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t3) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t4) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t5) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t6) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t7) ON 1=1
+LEFT OUTER JOIN (( SELECT 1
+ FROM t1 a_alias_1
+ LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
+ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
+ LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
+ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
+ LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
+) t8) ON 1=1
+;
+
+SELECT 1
+FROM (v1 t1)
+LEFT OUTER JOIN (v1 t2) ON 1=1
+LEFT OUTER JOIN (v1 t3) ON 1=1
+LEFT OUTER JOIN (v1 t4) ON 1=1
+LEFT OUTER JOIN (v1 t5) ON 1=1
+LEFT OUTER JOIN (v1 t6) ON 1=1
+LEFT OUTER JOIN (v1 t7) ON 1=1
+LEFT OUTER JOIN (v1 t8) ON 1=1
+;
+
+drop view v1;
+drop table t1,t2,t3,t4,t5,t6;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.3 tests.
--echo # -----------------------------------------------------------------
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index bdbf67455e1..5007cb01689 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -304,6 +304,9 @@ my_bool my_thread_init(void)
struct st_my_thread_var *tmp;
my_bool error=0;
+ if (!my_thread_global_init_done)
+ return 1; /* cannot proceed with unintialized library */
+
#ifdef EXTRA_DEBUG_THREADS
fprintf(stderr,"my_thread_init(): pthread_self: %p\n", pthread_self());
#endif
diff --git a/mysys/psi_noop.c b/mysys/psi_noop.c
index 8c9f2773170..2a351b5dd8d 100644
--- a/mysys/psi_noop.c
+++ b/mysys/psi_noop.c
@@ -236,7 +236,7 @@ static void set_thread_state_noop(const char* state NNN)
return;
}
-static void set_thread_info_noop(const char* info NNN, int info_len NNN)
+static void set_thread_info_noop(const char* info NNN, uint info_len NNN)
{
return;
}
diff --git a/packaging/rpm-oel/filter-provides.sh b/packaging/rpm-oel/filter-provides.sh
index bc166bd82d0..bc166bd82d0 100644..100755
--- a/packaging/rpm-oel/filter-provides.sh
+++ b/packaging/rpm-oel/filter-provides.sh
diff --git a/packaging/rpm-oel/filter-requires.sh b/packaging/rpm-oel/filter-requires.sh
index 521eb0ca7d9..521eb0ca7d9 100644..100755
--- a/packaging/rpm-oel/filter-requires.sh
+++ b/packaging/rpm-oel/filter-requires.sh
diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in
index d9e29317ff5..d28e89b4216 100644
--- a/packaging/rpm-oel/mysql.spec.in
+++ b/packaging/rpm-oel/mysql.spec.in
@@ -85,7 +85,7 @@ Name: mysql-%{product_suffix}
Summary: A very fast and reliable SQL database server
Group: Applications/Databases
Version: @VERSION@
-Release: 4%{?dist}
+Release: 2%{?commercial:.1}%{?dist}
License: Copyright (c) 2000, @MYSQL_COPYRIGHT_YEAR@, %{mysql_vendor}. All rights reserved. Under %{?license_type} license as shown in the Description field.
Source0: https://cdn.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/%{src_dir}.tar.gz
URL: http://www.mysql.com/
@@ -153,13 +153,17 @@ Requires: procps
Requires: shadow-utils
Requires: net-tools
%if 0%{?commercial}
+Provides: MySQL-server-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-server-advanced < %{version}-%{release}
Obsoletes: mysql-community-server < %{version}-%{release}
Requires: mysql-enterprise-client%{?_isa} = %{version}-%{release}
Requires: mysql-enterprise-common%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-server%{?_isa} = %{version}-%{release}
Requires: mysql-community-client%{?_isa} = %{version}-%{release}
Requires: mysql-community-common%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-server < %{version}-%{release}
Obsoletes: mysql-server < %{version}-%{release}
Obsoletes: mariadb-server
Provides: mysql-server = %{version}-%{release}
@@ -199,11 +203,15 @@ to run and administer a MySQL server.
Summary: MySQL database client applications and tools
Group: Applications/Databases
%if 0%{?commercial}
+Provides: MySQL-client-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-client-advanced < %{version}-%{release}
Obsoletes: mysql-community-client < %{version}-%{release}
Requires: mysql-enterprise-libs%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-client%{?_isa} = %{version}-%{release}
Requires: mysql-community-libs%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-client < %{version}-%{release}
Obsoletes: mariadb
%if 0%{?rhel} > 5
Obsoletes: mysql < %{version}-%{release}
@@ -234,11 +242,15 @@ MySQL database server, and MySQL embedded server.
Summary: Test suite for the MySQL database server
Group: Applications/Databases
%if 0%{?commercial}
+Provides: MySQL-test-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-test-advanced < %{version}-%{release}
Obsoletes: mysql-community-test < %{version}-%{release}
Requires: mysql-enterprise-server%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-test%{?_isa} = %{version}-%{release}
Requires: mysql-community-server%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-test < %{version}-%{release}
Obsoletes: mysql-test < %{version}-%{release}
Obsoletes: mariadb-test
Provides: mysql-test = %{version}-%{release}
@@ -254,11 +266,15 @@ database server.
Summary: Development header files and libraries for MySQL database client applications
Group: Applications/Databases
%if 0%{?commercial}
+Provides: MySQL-devel-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-devel-advanced < %{version}-%{release}
Obsoletes: mysql-community-devel < %{version}-%{release}
Requires: mysql-enterprise-libs%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-devel%{?_isa} = %{version}-%{release}
Requires: mysql-community-libs%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-devel < %{version}-%{release}
Obsoletes: mysql-devel < %{version}-%{release}
Obsoletes: mariadb-devel
Provides: mysql-devel = %{version}-%{release}
@@ -272,11 +288,15 @@ to develop MySQL client applications.
Summary: Shared libraries for MySQL database client applications
Group: Applications/Databases
%if 0%{?commercial}
+Provides: MySQL-shared-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-shared-advanced < %{version}-%{release}
Obsoletes: mysql-community-libs < %{version}-%{release}
Requires: mysql-enterprise-common%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-shared%{?_isa} = %{version}-%{release}
Requires: mysql-community-common%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-shared < %{version}-%{release}
Obsoletes: mysql-libs < %{version}-%{release}
Obsoletes: mariadb-libs
Provides: mysql-libs = %{version}-%{release}
@@ -294,11 +314,15 @@ Obsoletes: mysql-libs-compat < %{version}-%{release}
Provides: mysql-libs-compat = %{version}-%{release}
Provides: mysql-libs-compat%{?_isa} = %{version}-%{release}
%if 0%{?commercial}
+Provides: MySQL-shared-compat-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-shared-compat-advanced < %{version}-%{release}
Obsoletes: mysql-community-libs-compat < %{version}-%{release}
Requires: mysql-enterprise-libs%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-shared-compat%{?_isa} = %{version}-%{release}
Requires: mysql-community-libs%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-shared-compat < %{version}-%{release}
%if 0%{?rhel} > 5
Obsoletes: mysql-libs < %{version}-%{release}
%endif
@@ -312,11 +336,15 @@ applications.
Summary: MySQL embedded library
Group: Applications/Databases
%if 0%{?commercial}
+Provides: MySQL-embedded-advanced%{?_isa} = %{version}-%{release}
+Obsoletes: MySQL-embedded-advanced < %{version}-%{release}
Obsoletes: mysql-community-embedded < %{version}-%{release}
Requires: mysql-enterprise-common%{?_isa} = %{version}-%{release}
%else
+Provides: MySQL-embedded%{?_isa} = %{version}-%{release}
Requires: mysql-community-common%{?_isa} = %{version}-%{release}
%endif
+Obsoletes: MySQL-embedded < %{version}-%{release}
Obsoletes: mysql-embedded < %{version}-%{release}
Provides: mysql-embedded = %{version}-%{release}
Provides: mysql-emdedded%{?_isa} = %{version}-%{release}
@@ -435,20 +463,18 @@ popd
)
%endif # 0%{?compatlib}
-export CFLAGS="%{optflags} %{?el7:-DTAOCRYPT_DISABLE_X86ASM}"
-export CXXFLAGS="%{optflags} %{?el7:-DTAOCRYPT_DISABLE_X86ASM}"
-
# Build debug versions of mysqld and libmysqld.a
mkdir debug
(
cd debug
# Attempt to remove any optimisation flags from the debug build
- CFLAGS=$(echo "${CFLAGS}" | sed -e 's/-O2 / /' -e 's/-Wp,-D_FORTIFY_SOURCE=2/ /')
- CXXFLAGS=$(echo "${CFLAGS}" | sed -e 's/-O2 / /' -e 's/-Wp,-D_FORTIFY_SOURCE=2/ /')
+ optflags=$(echo "%{optflags}" | sed -e 's/-O2 / /' -e 's/-Wp,-D_FORTIFY_SOURCE=2/ /')
cmake ../%{src_dir} \
-DBUILD_CONFIG=mysql_release \
-DINSTALL_LAYOUT=RPM \
-DCMAKE_BUILD_TYPE=Debug %{?el7:-DENABLE_DTRACE=OFF} \
+ -DCMAKE_C_FLAGS="$optflags" \
+ -DCMAKE_CXX_FLAGS="$optflags" \
-DINSTALL_LIBDIR="%{_lib}/mysql" \
-DINSTALL_PLUGINDIR="%{_lib}/mysql/plugin" \
-DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
@@ -470,6 +496,8 @@ mkdir release
-DBUILD_CONFIG=mysql_release \
-DINSTALL_LAYOUT=RPM \
-DCMAKE_BUILD_TYPE=RelWithDebInfo %{?el7:-DENABLE_DTRACE=OFF} \
+ -DCMAKE_C_FLAGS="%{optflags}" \
+ -DCMAKE_CXX_FLAGS="%{optflags}" \
-DINSTALL_LIBDIR="%{_lib}/mysql" \
-DINSTALL_PLUGINDIR="%{_lib}/mysql/plugin" \
-DMYSQL_UNIX_ADDR="%{mysqldatadir}/mysql.sock" \
@@ -676,7 +704,41 @@ fi
%attr(755, root, root) %{_sbindir}/mysqld
%attr(755, root, root) %{_sbindir}/mysqld-debug
-%{_libdir}/mysql/plugin
+%dir %{_libdir}/mysql/plugin
+%attr(755, root, root) %{_libdir}/mysql/plugin/adt_null.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/auth_socket.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/mypluglib.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so
+%dir %{_libdir}/mysql/plugin/debug
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/adt_null.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth_socket.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/mypluglib.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_master.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/semisync_slave.so
+
+%attr(755, root, root) %{_libdir}/mysql/plugin/auth.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/auth_test_plugin.so
+%attr(644, root, root) %{_libdir}/mysql/plugin/daemon_example.ini
+%attr(755, root, root) %{_libdir}/mysql/plugin/libdaemon_example.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_client.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_interface.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/qa_auth_server.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/auth_test_plugin.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/libdaemon_example.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_client.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_interface.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/qa_auth_server.so
+
+%if 0%{?commercial}
+%attr(755, root, root) %{_libdir}/mysql/plugin/audit_log.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/authentication_pam.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/thread_pool.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/audit_log.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/authentication_pam.so
+%attr(755, root, root) %{_libdir}/mysql/plugin/debug/thread_pool.so
+%endif
%attr(644, root, root) %{_datadir}/mysql/fill_help_tables.sql
%attr(644, root, root) %{_datadir}/mysql/mysql_system_tables.sql
@@ -819,6 +881,19 @@ fi
%endif
%changelog
+* Sun May 11 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.38-2
+- Increment release version to resolve upgrade conflict issue
+
+* Thu Apr 24 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.38-1
+- Updated for 5.5.38
+
+* Mon Apr 07 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.37-6
+- Fix Cflags for el7
+
+* Mon Mar 31 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.37-5
+- Support for enterprise packages
+- Upgrade from MySQL-* packages
+
* Fri Mar 14 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.37-4
- Resolve mysql conflict with mysql-community-client
diff --git a/packaging/solaris/CMakeLists.txt b/packaging/solaris/CMakeLists.txt
index 02881e0af8f..899847d0f38 100644
--- a/packaging/solaris/CMakeLists.txt
+++ b/packaging/solaris/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
# Any files in this directory are auxiliary files for Solaris "pkg" packages.
# They will be configured during "pkg" creation, not during (binary) build.
+IF(NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ RETURN()
+ENDIF()
+
# Currently, this expands to "support-files/" in most layouts,
# but to "/usr/share/mysql/" in a RPM.
# It is important not to pollute "/usr/bin".
diff --git a/pcre/AUTHORS b/pcre/AUTHORS
index 97d8c71dd67..5eee1af4c6f 100644
--- a/pcre/AUTHORS
+++ b/pcre/AUTHORS
@@ -8,7 +8,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2013 University of Cambridge
+Copyright (c) 1997-2014 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-2013 Zoltan Herczeg
+Copyright(c) 2010-2014 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2013 Zoltan Herczeg
+Copyright(c) 2009-2014 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/CMakeLists.txt b/pcre/CMakeLists.txt
index f885237c395..90ebc0d5100 100644
--- a/pcre/CMakeLists.txt
+++ b/pcre/CMakeLists.txt
@@ -513,4 +513,6 @@ IF(PCRE_SHOW_REPORT)
MESSAGE(STATUS "")
ENDIF(PCRE_SHOW_REPORT)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/pcre/pcre.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
# end CMakeLists.txt
diff --git a/pcre/ChangeLog b/pcre/ChangeLog
index 1f1e8600356..7801ef84117 100644
--- a/pcre/ChangeLog
+++ b/pcre/ChangeLog
@@ -1,6 +1,126 @@
ChangeLog for PCRE
------------------
+Version 8.35 04-April-2014
+--------------------------
+
+1. A new flag is set, when property checks are present in an XCLASS.
+ When this flag is not set, PCRE can perform certain optimizations
+ such as studying these XCLASS-es.
+
+2. The auto-possessification of character sets were improved: a normal
+ and an extended character set can be compared now. Furthermore
+ the JIT compiler optimizes more character set checks.
+
+3. Got rid of some compiler warnings for potentially uninitialized variables
+ that show up only when compiled with -O2.
+
+4. A pattern such as (?=ab\K) that uses \K in an assertion can set the start
+ of a match later then the end of the match. The pcretest program was not
+ handling the case sensibly - it was outputting from the start to the next
+ binary zero. It now reports this situation in a message, and outputs the
+ text from the end to the start.
+
+5. Fast forward search is improved in JIT. Instead of the first three
+ characters, any three characters with fixed position can be searched.
+ Search order: first, last, middle.
+
+6. Improve character range checks in JIT. Characters are read by an inprecise
+ function now, which returns with an unknown value if the character code is
+ above a certain treshold (e.g: 256). The only limitation is that the value
+ must be bigger than the treshold as well. This function is useful, when
+ the characters above the treshold are handled in the same way.
+
+7. The macros whose names start with RAWUCHAR are placeholders for a future
+ mode in which only the bottom 21 bits of 32-bit data items are used. To
+ make this more memorable for those maintaining the code, the names have
+ been changed to start with UCHAR21, and an extensive comment has been added
+ to their definition.
+
+8. Add missing (new) files sljitNativeTILEGX.c and sljitNativeTILEGX-encoder.c
+ to the export list in Makefile.am (they were accidentally omitted from the
+ 8.34 tarball).
+
+9. The informational output from pcretest used the phrase "starting byte set"
+ which is inappropriate for the 16-bit and 32-bit libraries. As the output
+ for "first char" and "need char" really means "non-UTF-char", I've changed
+ "byte" to "char", and slightly reworded the output. The documentation about
+ these values has also been (I hope) clarified.
+
+10. Another JIT related optimization: use table jumps for selecting the correct
+ backtracking path, when more than four alternatives are present inside a
+ bracket.
+
+11. Empty match is not possible, when the minimum length is greater than zero,
+ and there is no \K in the pattern. JIT should avoid empty match checks in
+ such cases.
+
+12. In a caseless character class with UCP support, when a character with more
+ than one alternative case was not the first character of a range, not all
+ the alternative cases were added to the class. For example, s and \x{17f}
+ are both alternative cases for S: the class [RST] was handled correctly,
+ but [R-T] was not.
+
+13. The configure.ac file always checked for pthread support when JIT was
+ enabled. This is not used in Windows, so I have put this test inside a
+ check for the presence of windows.h (which was already tested for).
+
+14. Improve pattern prefix search by a simplified Boyer-Moore algorithm in JIT.
+ The algorithm provides a way to skip certain starting offsets, and usually
+ faster than linear prefix searches.
+
+15. Change 13 for 8.20 updated RunTest to check for the 'fr' locale as well
+ as for 'fr_FR' and 'french'. For some reason, however, it then used the
+ Windows-specific input and output files, which have 'french' screwed in.
+ So this could never have worked. One of the problems with locales is that
+ they aren't always the same. I have now updated RunTest so that it checks
+ the output of the locale test (test 3) against three different output
+ files, and it allows the test to pass if any one of them matches. With luck
+ this should make the test pass on some versions of Solaris where it was
+ failing. Because of the uncertainty, the script did not used to stop if
+ test 3 failed; it now does. If further versions of a French locale ever
+ come to light, they can now easily be added.
+
+16. If --with-pcregrep-bufsize was given a non-integer value such as "50K",
+ there was a message during ./configure, but it did not stop. This now
+ provokes an error. The invalid example in README has been corrected.
+ If a value less than the minimum is given, the minimum value has always
+ been used, but now a warning is given.
+
+17. If --enable-bsr-anycrlf was set, the special 16/32-bit test failed. This
+ was a bug in the test system, which is now fixed. Also, the list of various
+ configurations that are tested for each release did not have one with both
+ 16/32 bits and --enable-bar-anycrlf. It now does.
+
+18. pcretest was missing "-C bsr" for displaying the \R default setting.
+
+19. Little endian PowerPC systems are supported now by the JIT compiler.
+
+20. The fast forward newline mechanism could enter to an infinite loop on
+ certain invalid UTF-8 input. Although we don't support these cases
+ this issue can be fixed by a performance optimization.
+
+21. Change 33 of 8.34 is not sufficient to ensure stack safety because it does
+ not take account if existing stack usage. There is now a new global
+ variable called pcre_stack_guard that can be set to point to an external
+ function to check stack availability. It is called at the start of
+ processing every parenthesized group.
+
+22. A typo in the code meant that in ungreedy mode the max/min qualifier
+ behaved like a min-possessive qualifier, and, for example, /a{1,3}b/U did
+ not match "ab".
+
+23. When UTF was disabled, the JIT program reported some incorrect compile
+ errors. These messages are silenced now.
+
+24. Experimental support for ARM-64 and MIPS-64 has been added to the JIT
+ compiler.
+
+25. Change all the temporary files used in RunGrepTest to be different to those
+ used by RunTest so that the tests can be run simultaneously, for example by
+ "make -j check".
+
+
Version 8.34 15-December-2013
-----------------------------
diff --git a/pcre/INSTALL b/pcre/INSTALL
index 007e9396d0a..2099840756e 100644
--- a/pcre/INSTALL
+++ b/pcre/INSTALL
@@ -12,8 +12,8 @@ without warranty of any kind.
Basic Installation
==================
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
+ Briefly, the shell command `./configure && make && make install'
+should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
diff --git a/pcre/LICENCE b/pcre/LICENCE
index 3aff6a62c00..602e4ae6804 100644
--- a/pcre/LICENCE
+++ b/pcre/LICENCE
@@ -24,7 +24,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2013 University of Cambridge
+Copyright (c) 1997-2014 University of Cambridge
All rights reserved.
@@ -35,7 +35,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2013 Zoltan Herczeg
+Copyright(c) 2010-2014 Zoltan Herczeg
All rights reserved.
@@ -46,7 +46,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2013 Zoltan Herczeg
+Copyright(c) 2009-2014 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/NEWS b/pcre/NEWS
index 5f52f153460..6331e9908d1 100644
--- a/pcre/NEWS
+++ b/pcre/NEWS
@@ -1,6 +1,17 @@
News about PCRE releases
------------------------
+Release 8.35 04-April-2014
+--------------------------
+
+There have been performance improvements for classes containing non-ASCII
+characters and the "auto-possessification" feature has been extended. Other
+minor improvements have been implemented and bugs fixed. There is a new callout
+feature to enable applications to do detailed stack checks at compile time, to
+avoid running out of stack for deeply nested parentheses. The JIT compiler has
+been extended with experimental support for ARM-64, MIPS-64, and PPC-LE.
+
+
Release 8.34 15-December-2013
-----------------------------
diff --git a/pcre/README b/pcre/README
index 51197df7213..88f2dfd4efd 100644
--- a/pcre/README
+++ b/pcre/README
@@ -85,11 +85,12 @@ documentation is supplied in two other forms:
1. There are files called doc/pcre.txt, doc/pcregrep.txt, and
doc/pcretest.txt in the source distribution. The first of these is a
concatenation of the text forms of all the section 3 man pages except
- those that summarize individual functions. The other two are the text
- forms of the section 1 man pages for the pcregrep and pcretest commands.
- These text forms are provided for ease of scanning with text editors or
- similar tools. They are installed in <prefix>/share/doc/pcre, where
- <prefix> is the installation prefix (defaulting to /usr/local).
+ the listing of pcredemo.c and those that summarize individual functions.
+ The other two are the text forms of the section 1 man pages for the
+ pcregrep and pcretest commands. These text forms are provided for ease of
+ scanning with text editors or similar tools. They are installed in
+ <prefix>/share/doc/pcre, where <prefix> is the installation prefix
+ (defaulting to /usr/local).
2. A set of files containing all the documentation in HTML form, hyperlinked
in various ways, and rooted in a file called index.html, is distributed in
@@ -372,12 +373,12 @@ library. They are also documented in the pcrebuild man page.
Of course, the relevant libraries must be installed on your system.
-. The default size of internal buffer used by pcregrep can be set by, for
- example:
+. The default size (in bytes) of the internal buffer used by pcregrep can be
+ set by, for example:
- --with-pcregrep-bufsize=50K
+ --with-pcregrep-bufsize=51200
- The default value is 20K.
+ The value must be a plain integer. The default is 20480.
. It is possible to compile pcretest so that it links with the libreadline
or libedit libraries, by specifying, respectively,
@@ -987,4 +988,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
-Last updated: 05 November 2013
+Last updated: 17 January 2014
diff --git a/pcre/RunGrepTest b/pcre/RunGrepTest
index e192ed77f7c..f1b03484067 100755
--- a/pcre/RunGrepTest
+++ b/pcre/RunGrepTest
@@ -69,447 +69,447 @@ utf8=$?
echo "Testing pcregrep main features"
-echo "---------------------------- Test 1 ------------------------------" >testtry
-(cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 2 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 3 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 4 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 5 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 6 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 7 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 8 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 9 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 10 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 11 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 12 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 13 -----------------------------" >>testtry
-echo seventeen >testtemp1
-(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist -f $builddir/testtemp1 ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 14 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 15 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtry >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 16 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtry >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 17 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 18 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 19 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 20 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 21 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 22 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 23 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 24 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 25 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 26 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 27 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 28 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 29 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 30 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 31 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 32 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 33 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 34 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 35 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 36 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 37 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtry 2>teststderr
-echo "RC=$?" >>testtry
-echo "======== STDERR ========" >>testtry
-cat teststderr >>testtry
+echo "---------------------------- Test 1 ------------------------------" >testtrygrep
+(cd $srcdir; $valgrind $pcregrep PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 2 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep '^PATTERN' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 3 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 4 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -ic PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 5 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -in PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 6 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -inh PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 7 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -il PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 8 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -l PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 9 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -q PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 10 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -q NEVER-PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 11 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -vn pattern ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 12 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -ix pattern ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 13 -----------------------------" >>testtrygrep
+echo seventeen >testtemp1grep
+(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist -f $builddir/testtemp1grep ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 14 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -w pat ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 15 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep 'abc^*' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 16 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep abc ./testdata/grepinput ./testdata/nonexistfile) 2>>testtrygrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 17 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -M 'the\noutput' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 18 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -Mn '(the\noutput|dog\.\n--)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 19 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -Mix 'Pattern' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 20 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -Mixn 'complete pair\nof lines' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 21 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -nA3 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 22 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -nB3 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 23 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -C3 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 24 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -A9 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 25 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -nB9 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 26 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -A9 -B9 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 27 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -A10 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 28 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -nB10 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 29 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -C12 -B10 'four' ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 30 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -inB3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 31 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -inA3 'pattern' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 32 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -L 'fox' ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 33 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 34 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -s 'fox' ./testdata/grepnonexist) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 35 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 36 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude 'grepinput$' --exclude=grepinput8 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 37 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep '^(a+)*\d' ./testdata/grepinput) >>testtrygrep 2>teststderrgrep
+echo "RC=$?" >>testtrygrep
+echo "======== STDERR ========" >>testtrygrep
+cat teststderrgrep >>testtrygrep
-echo "---------------------------- Test 38 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 38 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep '>\x00<' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 39 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 39 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -A1 'before the binary zero' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 40 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 40 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -B1 'after the binary zero' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 41 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 41 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -B1 -o '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 42 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 42 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -B1 -onH '\w+ the binary zero' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 43 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 43 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -on 'before|zero|after' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 44 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -on -e before -ezero -e after ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 44 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -on -e before -ezero -e after ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 45 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 45 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -on -f ./testdata/greplist -e binary ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 46 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtry >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 46 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -eabc -e '(unclosed' ./testdata/grepinput) 2>>testtrygrep >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 47 ------------------------------" >>testtry
+echo "---------------------------- Test 47 ------------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep -Fx "AB.VE
-elephant" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+elephant" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 48 ------------------------------" >>testtry
+echo "---------------------------- Test 48 ------------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep -F "AB.VE
-elephant" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+elephant" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 49 ------------------------------" >>testtry
+echo "---------------------------- Test 49 ------------------------------" >>testtrygrep
(cd $srcdir; $valgrind $pcregrep -F -e DATA -e "AB.VE
-elephant" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+elephant" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 50 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 50 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep "^(abc|def|ghi|jkl)" ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 51 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 51 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -Mv "brown\sfox" ./testdata/grepinputv) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 52 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 52 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --colour=always jumps ./testdata/grepinputv) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 53 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 53 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --file-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 54 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 54 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --line-offsets 'before|zero|after' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 55 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 55 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -f./testdata/greplist --color=always ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 56 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -c lazy ./testdata/grepinput*) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 56 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -c lazy ./testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 57 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -c -l lazy ./testdata/grepinput*) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 57 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -c -l lazy ./testdata/grepinput*) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 58 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --regex=PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 58 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --regex=PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 59 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --regexp=PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 59 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --regexp=PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 60 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --regex PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 60 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --regex PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 61 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --regexp PATTERN ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 61 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --regexp PATTERN ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 62 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 62 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --match-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 63 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 63 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --recursion-limit=1000 --no-jit -M 'This is a file(.|\R)*file.' ./testdata/grepinput) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 64 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 64 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o1 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 65 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 65 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 66 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 66 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o3 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 67 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 67 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o12 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 68 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 68 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --only-matching=2 '(?<=PAT)TERN (ap(pear)s)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 69 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -vn --colour=always pattern ./testdata/grepinputx) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 69 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -vn --colour=always pattern ./testdata/grepinputx) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 70 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 70 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --color=always -M "triple:\t.*\n\n" ./testdata/grepinput3) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 71 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o "^01|^02|^03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 71 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o "^01|^02|^03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 72 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 72 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 73 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 73 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|^03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 74 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o "^01|02|^03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 75 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --color=always "^01|02|^03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 76 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 77 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o "^01|^02|03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 78 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 79 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 80 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o "\b01|\b02" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 81 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 82 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 83 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 74 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o "^01|02|^03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 75 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --color=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 76 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|02|^03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 77 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o "^01|^02|03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 78 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --color=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 79 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o --colour=always "^01|^02|03" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 80 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o "\b01|\b02" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 81 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --color=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 82 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o --colour=always "\\b01|\\b02" ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 83 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --buffer-size=100 "^a" ./testdata/grepinput3) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 84 -----------------------------" >>testtry
-echo testdata/grepinput3 >testtemp1
-(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1 "fox|complete|t7") >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 85 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 86 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep "dog" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 87 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep "cat" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 88 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -v "cat" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 89 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -I "dog" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 90 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 91 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -a "dog" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 92 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --binary-files=text "dog" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 93 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --text "dog" ./testdata/grepbinary) >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 94 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 95 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtry 2>&1
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 96 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 97 -----------------------------" >>testtry
-echo "grepinput$" >testtemp1
-echo "grepinput8" >>testtemp1
-(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude-from $builddir/testtemp1 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 84 -----------------------------" >>testtrygrep
+echo testdata/grepinput3 >testtemp1grep
+(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --file-list $builddir/testtemp1grep "fox|complete|t7") >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 85 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --file-list=./testdata/grepfilelist "dolor" ./testdata/grepinput3) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 86 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep "dog" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 87 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep "cat" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 88 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -v "cat" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 89 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -I "dog" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 90 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --binary-files=without-match "dog" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 91 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -a "dog" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 92 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --binary-files=text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 93 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --text "dog" ./testdata/grepbinary) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 94 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinputx --include grepinput8 'fox' ./testdata/grepinput* | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 95 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --file-list ./testdata/grepfilelist --exclude grepinputv "fox|complete") >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 96 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -L -r --include-dir=testdata --exclude '^(?!grepinput)' 'fox' ./test* | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 97 -----------------------------" >>testtrygrep
+echo "grepinput$" >testtemp1grep
+echo "grepinput8" >>testtemp1grep
+(cd $srcdir; $valgrind $pcregrep -L -r --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 98 -----------------------------" >>testtry
-echo "grepinput$" >testtemp1
-echo "grepinput8" >>testtemp1
-(cd $srcdir; $valgrind $pcregrep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry
-echo "RC=$?" >>testtry
-
-echo "---------------------------- Test 99 -----------------------------" >>testtry
-echo "grepinput$" >testtemp1
-echo "grepinput8" >testtemp2
-(cd $srcdir; $valgrind $pcregrep -L -r --include grepinput --exclude-from $builddir/testtemp1 --exclude-from=$builddir/testtemp2 --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 98 -----------------------------" >>testtrygrep
+echo "grepinput$" >testtemp1grep
+echo "grepinput8" >>testtemp1grep
+(cd $srcdir; $valgrind $pcregrep -L -r --exclude=grepinput3 --include=grepinput --exclude-from $builddir/testtemp1grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 99 -----------------------------" >>testtrygrep
+echo "grepinput$" >testtemp1grep
+echo "grepinput8" >testtemp2grep
+(cd $srcdir; $valgrind $pcregrep -L -r --include grepinput --exclude-from $builddir/testtemp1grep --exclude-from=$builddir/testtemp2grep --exclude-dir='^\.' 'fox' ./testdata | sort) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 100 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 100 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -Ho2 --only-matching=1 -o3 '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 101 ------------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtry
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 101 ------------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -o3 -Ho2 -o12 --only-matching=1 -o3 --colour=always --om-separator='|' '(\w+) binary (\w+)(\.)?' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 102 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -n "^$" ./testdata/grepinput3) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 102 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -n "^$" ./testdata/grepinput3) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 103 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --only-matching "^$" ./testdata/grepinput3) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 103 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 104 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep -n --only-matching "^$" ./testdata/grepinput3) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 104 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep -n --only-matching "^$" ./testdata/grepinput3) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 105 -----------------------------" >>testtry
-(cd $srcdir; $valgrind $pcregrep --colour=always "ipsum|" ./testdata/grepinput3) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 105 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $pcregrep --colour=always "ipsum|" ./testdata/grepinput3) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
-echo "---------------------------- Test 106 -----------------------------" >>testtry
-(cd $srcdir; echo "a" | $valgrind $pcregrep -M "|a" ) >>testtry 2>&1
-echo "RC=$?" >>testtry
+echo "---------------------------- Test 106 -----------------------------" >>testtrygrep
+(cd $srcdir; echo "a" | $valgrind $pcregrep -M "|a" ) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
# Now compare the results.
-$cf $srcdir/testdata/grepoutput testtry
+$cf $srcdir/testdata/grepoutput testtrygrep
if [ $? != 0 ] ; then exit 1; fi
@@ -518,15 +518,15 @@ if [ $? != 0 ] ; then exit 1; fi
if [ $utf8 -ne 0 ] ; then
echo "Testing pcregrep UTF-8 features"
- echo "---------------------------- Test U1 ------------------------------" >testtry
- (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtry
- echo "RC=$?" >>testtry
+ echo "---------------------------- Test U1 ------------------------------" >testtrygrep
+ (cd $srcdir; $valgrind $pcregrep -n -u --newline=any "^X" ./testdata/grepinput8) >>testtrygrep
+ echo "RC=$?" >>testtrygrep
- echo "---------------------------- Test U2 ------------------------------" >>testtry
- (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtry
- echo "RC=$?" >>testtry
+ echo "---------------------------- Test U2 ------------------------------" >>testtrygrep
+ (cd $srcdir; $valgrind $pcregrep -n -u -C 3 --newline=any "Match" ./testdata/grepinput8) >>testtrygrep
+ echo "RC=$?" >>testtrygrep
- $cf $srcdir/testdata/grepoutput8 testtry
+ $cf $srcdir/testdata/grepoutput8 testtrygrep
if [ $? != 0 ] ; then exit 1; fi
else
@@ -542,28 +542,28 @@ fi
# starts with a hyphen. These tests are run in the build directory.
echo "Testing pcregrep newline settings"
-printf "abc\rdef\r\nghi\njkl" >testNinput
+printf "abc\rdef\r\nghi\njkl" >testNinputgrep
-printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtry
-$valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinput >>testtry
+printf "%c--------------------------- Test N1 ------------------------------\r\n" - >testtrygrep
+$valgrind $pcregrep -n -N CR "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep
-printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinput >>testtry
+printf "%c--------------------------- Test N2 ------------------------------\r\n" - >>testtrygrep
+$valgrind $pcregrep -n --newline=crlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep
-printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtry
+printf "%c--------------------------- Test N3 ------------------------------\r\n" - >>testtrygrep
pattern=`printf 'def\rjkl'`
-$valgrind $pcregrep -n --newline=cr -F "$pattern" testNinput >>testtry
+$valgrind $pcregrep -n --newline=cr -F "$pattern" testNinputgrep >>testtrygrep
-printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinput >>testtry
+printf "%c--------------------------- Test N4 ------------------------------\r\n" - >>testtrygrep
+$valgrind $pcregrep -n --newline=crlf -F -f $srcdir/testdata/greppatN4 testNinputgrep >>testtrygrep
-printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinput >>testtry
+printf "%c--------------------------- Test N5 ------------------------------\r\n" - >>testtrygrep
+$valgrind $pcregrep -n --newline=any "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep
-printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtry
-$valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinput >>testtry
+printf "%c--------------------------- Test N6 ------------------------------\r\n" - >>testtrygrep
+$valgrind $pcregrep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgrep >>testtrygrep
-$cf $srcdir/testdata/grepoutputN testtry
+$cf $srcdir/testdata/grepoutputN testtrygrep
if [ $? != 0 ] ; then exit 1; fi
exit 0
diff --git a/pcre/RunTest b/pcre/RunTest
index 7caa51d6772..67cfbf07cf9 100755
--- a/pcre/RunTest
+++ b/pcre/RunTest
@@ -31,6 +31,11 @@
# except test 10. Whatever order the arguments are in, the tests are always run
# in numerical order.
#
+# The special argument "3S" runs test 3, stopping if it fails. Test 3 is the
+# locale test, and failure usually means there's an issue with the locale
+# rather than a bug in PCRE, so normally subsequent tests are run. "3S" is
+# useful when you want to debug or update the test.
+#
# Inappropriate tests are automatically skipped (with a comment to say so): for
# example, if JIT support is not compiled, test 12 is skipped, whereas if JIT
# support is compiled, test 13 is skipped.
@@ -458,8 +463,9 @@ fi
# Locale-specific tests, provided that either the "fr_FR" or the "french"
# locale is available. The former is the Unix-like standard; the latter is
-# for Windows. Another possibility is "fr", which needs to be run against
-# the Windows-specific input and output files.
+# for Windows. Another possibility is "fr". Unfortunately, different versions
+# of the French locale give different outputs for some items. This test passes
+# if the output matches any one of the alternative output files.
if [ $do3 = yes ] ; then
locale -a | grep '^fr_FR$' >/dev/null
@@ -467,20 +473,28 @@ if [ $do3 = yes ] ; then
locale=fr_FR
infile=$testdata/testinput3
outfile=$testdata/testoutput3
+ outfile2=$testdata/testoutput3A
+ outfile3=$testdata/testoutput3B
else
infile=test3input
outfile=test3output
+ outfile2=test3outputA
+ outfile3=test3outputB
locale -a | grep '^french$' >/dev/null
if [ $? -eq 0 ] ; then
locale=french
sed 's/fr_FR/french/' $testdata/testinput3 >test3input
sed 's/fr_FR/french/' $testdata/testoutput3 >test3output
+ sed 's/fr_FR/french/' $testdata/testoutput3A >test3outputA
+ sed 's/fr_FR/french/' $testdata/testoutput3B >test3outputB
else
locale -a | grep '^fr$' >/dev/null
if [ $? -eq 0 ] ; then
locale=fr
- sed 's/fr_FR/fr/' $testdata/wintestinput3 >test3input
- sed 's/fr_FR/fr/' $testdata/wintestoutput3 >test3output
+ sed 's/fr_FR/fr/' $testdata/intestinput3 >test3input
+ sed 's/fr_FR/fr/' $testdata/intestoutput3 >test3output
+ sed 's/fr_FR/fr/' $testdata/intestoutput3A >test3outputA
+ sed 's/fr_FR/fr/' $testdata/intestoutput3B >test3outputB
else
locale=
fi
@@ -492,18 +506,20 @@ if [ $do3 = yes ] ; then
for opt in "" "-s" $jitopt; do
$sim $valgrind ./pcretest -q $bmode $opt $infile testtry
if [ $? = 0 ] ; then
- $cf $outfile testtry
- if [ $? != 0 ] ; then
- echo " "
- echo "Locale test did not run entirely successfully."
- echo "This usually means that there is a problem with the locale"
- echo "settings rather than a bug in PCRE."
- break;
- else
+ if $cf $outfile testtry >teststdout || \
+ $cf $outfile2 testtry >teststdout || \
+ $cf $outfile3 testtry >teststdout
+ then
if [ "$opt" = "-s" ] ; then echo " OK with study"
elif [ "$opt" = "-s+" ] ; then echo " OK with JIT study"
else echo " OK"
fi
+ else
+ echo "** Locale test did not run successfully. The output did not match"
+ echo " $outfile, $outfile2 or $outfile3."
+ echo " This may mean that there is a problem with the locale settings rather"
+ echo " than a bug in PCRE."
+ exit 1
fi
else exit 1
fi
@@ -989,6 +1005,6 @@ fi
done
# Clean up local working files
-rm -f test3input test3output testNinput testsaved* teststderr teststdout testtry
+rm -f test3input test3output test3outputA testNinput testsaved* teststderr teststdout testtry
# End
diff --git a/pcre/configure.ac b/pcre/configure.ac
index 5ce6c62c0d3..aab2f56c218 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, [34])
+m4_define(pcre_minor, [35])
m4_define(pcre_prerelease, [])
-m4_define(pcre_date, [2013-12-15])
+m4_define(pcre_date, [2014-04-04])
# 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:2:2])
-m4_define(libpcre16_version, [2:2:2])
-m4_define(libpcre32_version, [0:2:0])
+m4_define(libpcre_version, [3:3:2])
+m4_define(libpcre16_version, [2:3:2])
+m4_define(libpcre32_version, [0:3:0])
m4_define(libpcreposix_version, [0:2:0])
m4_define(libpcrecpp_version, [0:0:0])
@@ -248,7 +248,7 @@ AC_ARG_ENABLE(pcregrep-libbz2,
# Handle --with-pcregrep-bufsize=N
AC_ARG_WITH(pcregrep-bufsize,
AS_HELP_STRING([--with-pcregrep-bufsize=N],
- [pcregrep buffer size (default=20480)]),
+ [pcregrep buffer size (default=20480, minimum=8192)]),
, with_pcregrep_bufsize=20480)
# Handle --enable-pcretest-libedit
@@ -461,7 +461,8 @@ sure both macros are undefined; an emulation function will then be used. */])
# Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h windows.h)
+AC_CHECK_HEADERS(limits.h sys/types.h sys/stat.h dirent.h)
+AC_CHECK_HEADERS([windows.h], [HAVE_WINDOWS_H=1])
# The files below are C++ header files.
pcre_have_type_traits="0"
@@ -686,11 +687,15 @@ if test "$enable_pcre32" = "yes"; then
Define to any value to enable the 32 bit PCRE library.])
fi
+# Unless running under Windows, JIT support requires pthreads.
+
if test "$enable_jit" = "yes"; then
- AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])])
- CC="$PTHREAD_CC"
- CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
+ if test "$HAVE_WINDOWS_H" != "1"; then
+ AX_PTHREAD([], [AC_MSG_ERROR([JIT support requires pthreads])])
+ CC="$PTHREAD_CC"
+ CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ fi
AC_DEFINE([SUPPORT_JIT], [], [
Define to any value to enable support for Just-In-Time compiling.])
else
@@ -739,7 +744,12 @@ if test "$enable_pcregrep_libbz2" = "yes"; then
fi
if test $with_pcregrep_bufsize -lt 8192 ; then
+ AC_MSG_WARN([$with_pcregrep_bufsize is too small for --with-pcregrep-bufsize; using 8192])
with_pcregrep_bufsize="8192"
+else
+ if test $? -gt 1 ; then
+ AC_MSG_ERROR([Bad value for --with-pcregrep-bufsize])
+ fi
fi
AC_DEFINE_UNQUOTED([PCREGREP_BUFSIZE], [$with_pcregrep_bufsize], [
diff --git a/pcre/doc/html/README.txt b/pcre/doc/html/README.txt
index 51197df7213..88f2dfd4efd 100644
--- a/pcre/doc/html/README.txt
+++ b/pcre/doc/html/README.txt
@@ -85,11 +85,12 @@ documentation is supplied in two other forms:
1. There are files called doc/pcre.txt, doc/pcregrep.txt, and
doc/pcretest.txt in the source distribution. The first of these is a
concatenation of the text forms of all the section 3 man pages except
- those that summarize individual functions. The other two are the text
- forms of the section 1 man pages for the pcregrep and pcretest commands.
- These text forms are provided for ease of scanning with text editors or
- similar tools. They are installed in <prefix>/share/doc/pcre, where
- <prefix> is the installation prefix (defaulting to /usr/local).
+ the listing of pcredemo.c and those that summarize individual functions.
+ The other two are the text forms of the section 1 man pages for the
+ pcregrep and pcretest commands. These text forms are provided for ease of
+ scanning with text editors or similar tools. They are installed in
+ <prefix>/share/doc/pcre, where <prefix> is the installation prefix
+ (defaulting to /usr/local).
2. A set of files containing all the documentation in HTML form, hyperlinked
in various ways, and rooted in a file called index.html, is distributed in
@@ -372,12 +373,12 @@ library. They are also documented in the pcrebuild man page.
Of course, the relevant libraries must be installed on your system.
-. The default size of internal buffer used by pcregrep can be set by, for
- example:
+. The default size (in bytes) of the internal buffer used by pcregrep can be
+ set by, for example:
- --with-pcregrep-bufsize=50K
+ --with-pcregrep-bufsize=51200
- The default value is 20K.
+ The value must be a plain integer. The default is 20480.
. It is possible to compile pcretest so that it links with the libreadline
or libedit libraries, by specifying, respectively,
@@ -987,4 +988,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
-Last updated: 05 November 2013
+Last updated: 17 January 2014
diff --git a/pcre/doc/html/pcre.html b/pcre/doc/html/pcre.html
index 93b129ecd83..c2b29aa8121 100644
--- a/pcre/doc/html/pcre.html
+++ b/pcre/doc/html/pcre.html
@@ -154,8 +154,11 @@ page.
The user documentation for PCRE comprises a number of different sections. In
the "man" format, each of these is a separate "man page". In the HTML format,
each is a separate page, linked from the index page. In the plain text format,
-all the sections, except the <b>pcredemo</b> section, are concatenated, for ease
-of searching. The sections are as follows:
+the descriptions of the <b>pcregrep</b> and <b>pcretest</b> programs are in files
+called <b>pcregrep.txt</b> and <b>pcretest.txt</b>, respectively. The remaining
+sections, except for the <b>pcredemo</b> section (which is a program listing),
+are concatenated in <b>pcre.txt</b>, for ease of searching. The sections are as
+follows:
<pre>
pcre this document
pcre-config show PCRE installation configuration information
@@ -182,8 +185,8 @@ of searching. The sections are as follows:
pcretest description of the <b>pcretest</b> testing command
pcreunicode discussion of Unicode and UTF-8/16/32 support
</pre>
-In addition, in the "man" and HTML formats, there is a short page for each
-C library function, listing its arguments and results.
+In the "man" and HTML formats, there is also a short page for each C library
+function, listing its arguments and results.
</P>
<br><a name="SEC4" href="#TOC1">AUTHOR</a><br>
<P>
@@ -201,9 +204,9 @@ two digits 10, at the domain cam.ac.uk.
</P>
<br><a name="SEC5" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 13 May 2013
+Last updated: 08 January 2014
<br>
-Copyright &copy; 1997-2013 University of Cambridge.
+Copyright &copy; 1997-2014 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 abc3d2663fc..b401ecc76df 100644
--- a/pcre/doc/html/pcreapi.html
+++ b/pcre/doc/html/pcreapi.html
@@ -166,6 +166,9 @@ man page, in case the conversion went wrong.
<br>
<br>
<b>int (*pcre_callout)(pcre_callout_block *);</b>
+<br>
+<br>
+<b>int (*pcre_stack_guard)(void);</b>
</P>
<br><a name="SEC5" href="#TOC1">PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES</a><br>
<P>
@@ -324,6 +327,15 @@ by the caller to a "callout" function, which PCRE will then call at specified
points during a matching operation. Details are given in the
<a href="pcrecallout.html"><b>pcrecallout</b></a>
documentation.
+</P>
+<P>
+The global variable <b>pcre_stack_guard</b> initially contains NULL. It can be
+set by the caller to a function that is called by PCRE whenever it starts
+to compile a parenthesized part of a pattern. When parentheses are nested, PCRE
+uses recursive function calls, which use up the system stack. This function is
+provided so that applications with restricted stacks can force a compilation
+error if the stack runs out. The function should return zero if all is well, or
+non-zero to force an error.
<a name="newlines"></a></P>
<br><a name="SEC7" href="#TOC1">NEWLINES</a><br>
<P>
@@ -369,7 +381,8 @@ controlled in a similar way, but by separate options.
The PCRE functions can be used in multi-threading applications, with the
proviso that the memory management functions pointed to by <b>pcre_malloc</b>,
<b>pcre_free</b>, <b>pcre_stack_malloc</b>, and <b>pcre_stack_free</b>, and the
-callout function pointed to by <b>pcre_callout</b>, are shared by all threads.
+callout and stack-checking functions pointed to by <b>pcre_callout</b> and
+<b>pcre_stack_guard</b>, are shared by all threads.
</P>
<P>
The compiled form of a regular expression is not altered during matching, so
@@ -489,7 +502,10 @@ documentation.
The output is a long integer that gives the maximum depth of nesting of
parentheses (of any kind) in a pattern. This limit is imposed to cap the amount
of system stack used when a pattern is compiled. It is specified when PCRE is
-built; the default is 250.
+built; the default is 250. This limit does not take into account the stack that
+may already be used by the calling application. For finer control over
+compilation stack usage, you can set a pointer to an external checking function
+in <b>pcre_stack_guard</b>.
<pre>
PCRE_CONFIG_MATCH_LIMIT
</pre>
@@ -1008,6 +1024,8 @@ have fallen out of use. To avoid confusion, they have not been re-used.
81 missing opening brace after \o
82 parentheses are too deeply nested
83 invalid range in character class
+ 84 group name must start with a non-digit
+ 85 parentheses are too deeply nested (stack check)
</pre>
The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may
be used if the limits were changed when PCRE was built.
@@ -1265,12 +1283,15 @@ information call is provided for internal use by the <b>pcre_study()</b>
function. External callers can cause PCRE to use its internal tables by passing
a NULL table pointer.
<pre>
- PCRE_INFO_FIRSTBYTE
+ PCRE_INFO_FIRSTBYTE (deprecated)
</pre>
Return information about the first data unit of any matched string, for a
-non-anchored pattern. (The name of this option refers to the 8-bit library,
-where data units are bytes.) The fourth argument should point to an <b>int</b>
-variable.
+non-anchored pattern. The name of this option refers to the 8-bit library,
+where data units are bytes. The fourth argument should point to an <b>int</b>
+variable. Negative values are used for special cases. However, this means that
+when the 32-bit library is in non-UTF-32 mode, the full 32-bit range of
+characters cannot be returned. For this reason, this value is deprecated; use
+PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER instead.
</P>
<P>
If there is a fixed first value, for example, the letter "c" from a pattern
@@ -1293,12 +1314,43 @@ starts with "^", or
-1 is returned, indicating that the pattern matches only at the start of a
subject string or after any newline within the string. Otherwise -2 is
returned. For anchored patterns, -2 is returned.
+<pre>
+ PCRE_INFO_FIRSTCHARACTER
+</pre>
+Return the value of the first data unit (non-UTF character) of any matched
+string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS returns 1;
+otherwise return 0. The fourth argument should point to an <b>uint_t</b>
+variable.
</P>
<P>
-Since for the 32-bit library using the non-UTF-32 mode, this function is unable
-to return the full 32-bit range of the character, this value is deprecated;
-instead the PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER values
-should be used.
+In the 8-bit library, the value is always less than 256. In the 16-bit library
+the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value
+can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode.
+<pre>
+ PCRE_INFO_FIRSTCHARACTERFLAGS
+</pre>
+Return information about the first data unit of any matched string, for a
+non-anchored pattern. The fourth argument should point to an <b>int</b>
+variable.
+</P>
+<P>
+If there is a fixed first value, for example, the letter "c" from a pattern
+such as (cat|cow|coyote), 1 is returned, and the character value can be
+retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no fixed first value, and
+if either
+<br>
+<br>
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
+starts with "^", or
+<br>
+<br>
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
+(if it were set, the pattern would be anchored),
+<br>
+<br>
+2 is returned, indicating that the pattern matches only at the start of a
+subject string or after any newline within the string. Otherwise 0 is
+returned. For anchored patterns, 0 is returned.
<pre>
PCRE_INFO_FIRSTTABLE
</pre>
@@ -1509,44 +1561,6 @@ is made available via this option so that it can be saved and restored (see the
<a href="pcreprecompile.html"><b>pcreprecompile</b></a>
documentation for details).
<pre>
- PCRE_INFO_FIRSTCHARACTERFLAGS
-</pre>
-Return information about the first data unit of any matched string, for a
-non-anchored pattern. The fourth argument should point to an <b>int</b>
-variable.
-</P>
-<P>
-If there is a fixed first value, for example, the letter "c" from a pattern
-such as (cat|cow|coyote), 1 is returned, and the character value can be
-retrieved using PCRE_INFO_FIRSTCHARACTER.
-</P>
-<P>
-If there is no fixed first value, and if either
-<br>
-<br>
-(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
-starts with "^", or
-<br>
-<br>
-(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
-(if it were set, the pattern would be anchored),
-<br>
-<br>
-2 is returned, indicating that the pattern matches only at the start of a
-subject string or after any newline within the string. Otherwise 0 is
-returned. For anchored patterns, 0 is returned.
-<pre>
- PCRE_INFO_FIRSTCHARACTER
-</pre>
-Return the fixed first character value in the situation where
-PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; otherwise return 0. The fourth
-argument should point to an <b>uint_t</b> variable.
-</P>
-<P>
-In the 8-bit library, the value is always less than 256. In the 16-bit library
-the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value
-can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode.
-<pre>
PCRE_INFO_REQUIREDCHARFLAGS
</pre>
Returns 1 if there is a rightmost literal data unit that must exist in any
@@ -2899,9 +2913,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC26" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 12 November 2013
+Last updated: 09 February 2014
<br>
-Copyright &copy; 1997-2013 University of Cambridge.
+Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/html/pcregrep.html b/pcre/doc/html/pcregrep.html
index bac8f9a43fd..dacbb4998f8 100644
--- a/pcre/doc/html/pcregrep.html
+++ b/pcre/doc/html/pcregrep.html
@@ -37,8 +37,10 @@ man page, in case the conversion went wrong.
<b>pcregrep</b> searches files for character patterns, in the same way as other
grep commands do, but it uses the PCRE regular expression library to support
patterns that are compatible with the regular expressions of Perl 5. See
+<a href="pcresyntax.html"><b>pcresyntax</b>(3)</a>
+for a quick-reference summary of pattern syntax, or
<a href="pcrepattern.html"><b>pcrepattern</b>(3)</a>
-for a full description of syntax and semantics of the regular expressions
+for a full description of the syntax and semantics of the regular expressions
that PCRE supports.
</P>
<P>
@@ -748,9 +750,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC14" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 13 September 2012
+Last updated: 03 April 2014
<br>
-Copyright &copy; 1997-2012 University of Cambridge.
+Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/html/pcrepattern.html b/pcre/doc/html/pcrepattern.html
index 624cb447238..c06d1e03f11 100644
--- a/pcre/doc/html/pcrepattern.html
+++ b/pcre/doc/html/pcrepattern.html
@@ -1003,7 +1003,9 @@ matches "foobar", the first substring is still set to "foo".
<P>
Perl documents that the use of \K within assertions is "not well defined". In
PCRE, \K is acted upon when it occurs inside positive assertions, but is
-ignored in negative assertions.
+ignored in negative assertions. Note that when a pattern such as (?=ab\K)
+matches, the reported start of the match can be greater than the end of the
+match.
<a name="smallassertions"></a></P>
<br><b>
Simple assertions
@@ -2990,19 +2992,22 @@ match does not always guarantee that a match must be at this starting point.
<P>
Note that (*COMMIT) at the start of a pattern is not the same as an anchor,
unless PCRE's start-of-match optimizations are turned off, as shown in this
-<b>pcretest</b> example:
+output from <b>pcretest</b>:
<pre>
re&#62; /(*COMMIT)abc/
data&#62; xyzabc
0: abc
- xyzabc\Y
+ data&#62; xyzabc\Y
No match
</pre>
-PCRE knows that any match must start with "a", so the optimization skips along
-the subject to "a" before running the first match attempt, which succeeds. When
-the optimization is disabled by the \Y escape in the second subject, the match
-starts at "x" and so the (*COMMIT) causes it to fail without trying any other
-starting points.
+For this pattern, PCRE knows that any match must start with "a", so the
+optimization skips along the subject to "a" before applying the pattern to the
+first set of data. The match attempt then succeeds. In the second set of data,
+the escape sequence \Y is interpreted by the <b>pcretest</b> program. It causes
+the PCRE_NO_START_OPTIMIZE option to be set when <b>pcre_exec()</b> is called.
+This disables the optimization that skips along to the first character. The
+pattern is now applied starting at "x", and so the (*COMMIT) causes the match
+to fail without trying any other starting points.
<pre>
(*PRUNE) or (*PRUNE:NAME)
</pre>
@@ -3221,9 +3226,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC30" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 03 December 2013
+Last updated: 08 January 2014
<br>
-Copyright &copy; 1997-2013 University of Cambridge.
+Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/html/pcresyntax.html b/pcre/doc/html/pcresyntax.html
index 0764a33a376..89f35737b4f 100644
--- a/pcre/doc/html/pcresyntax.html
+++ b/pcre/doc/html/pcresyntax.html
@@ -29,13 +29,13 @@ man page, in case the conversion went wrong.
<li><a name="TOC14" href="#SEC14">ATOMIC GROUPS</a>
<li><a name="TOC15" href="#SEC15">COMMENT</a>
<li><a name="TOC16" href="#SEC16">OPTION SETTING</a>
-<li><a name="TOC17" href="#SEC17">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a>
-<li><a name="TOC18" href="#SEC18">BACKREFERENCES</a>
-<li><a name="TOC19" href="#SEC19">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a>
-<li><a name="TOC20" href="#SEC20">CONDITIONAL PATTERNS</a>
-<li><a name="TOC21" href="#SEC21">BACKTRACKING CONTROL</a>
-<li><a name="TOC22" href="#SEC22">NEWLINE CONVENTIONS</a>
-<li><a name="TOC23" href="#SEC23">WHAT \R MATCHES</a>
+<li><a name="TOC17" href="#SEC17">NEWLINE CONVENTION</a>
+<li><a name="TOC18" href="#SEC18">WHAT \R MATCHES</a>
+<li><a name="TOC19" href="#SEC19">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a>
+<li><a name="TOC20" href="#SEC20">BACKREFERENCES</a>
+<li><a name="TOC21" href="#SEC21">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a>
+<li><a name="TOC22" href="#SEC22">CONDITIONAL PATTERNS</a>
+<li><a name="TOC23" href="#SEC23">BACKTRACKING CONTROL</a>
<li><a name="TOC24" href="#SEC24">CALLOUTS</a>
<li><a name="TOC25" href="#SEC25">SEE ALSO</a>
<li><a name="TOC26" href="#SEC26">AUTHOR</a>
@@ -339,7 +339,8 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use
<P>
<pre>
\K reset start of match
-</PRE>
+</pre>
+\K is honoured in positive assertions, but ignored in negative ones.
</P>
<br><a name="SEC12" href="#TOC1">ALTERNATION</a><br>
<P>
@@ -382,11 +383,13 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use
(?x) extended (ignore white space)
(?-...) unset option(s)
</pre>
-The following are recognized only at the start of a pattern or after one of the
-newline-setting options with similar syntax:
+The following are recognized only at the very start of a pattern or after one
+of the newline or \R options with similar syntax. More than one of them may
+appear.
<pre>
(*LIMIT_MATCH=d) set the match limit to d (decimal number)
(*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
+ (*NO_AUTO_POSSESS) no auto-possessification (PCRE_NO_AUTO_POSSESS)
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
(*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
(*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
@@ -397,7 +400,28 @@ newline-setting options with similar syntax:
Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of the
limits set by the caller of pcre_exec(), not increase them.
</P>
-<br><a name="SEC17" href="#TOC1">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a><br>
+<br><a name="SEC17" href="#TOC1">NEWLINE CONVENTION</a><br>
+<P>
+These are recognized only at the very start of the pattern or after option
+settings with a similar syntax.
+<pre>
+ (*CR) carriage return only
+ (*LF) linefeed only
+ (*CRLF) carriage return followed by linefeed
+ (*ANYCRLF) all three of the above
+ (*ANY) any Unicode newline sequence
+</PRE>
+</P>
+<br><a name="SEC18" href="#TOC1">WHAT \R MATCHES</a><br>
+<P>
+These are recognized only at the very start of the pattern or after option
+setting with a similar syntax.
+<pre>
+ (*BSR_ANYCRLF) CR, LF, or CRLF
+ (*BSR_UNICODE) any Unicode newline sequence
+</PRE>
+</P>
+<br><a name="SEC19" href="#TOC1">LOOKAHEAD AND LOOKBEHIND ASSERTIONS</a><br>
<P>
<pre>
(?=...) positive look ahead
@@ -407,7 +431,7 @@ limits set by the caller of pcre_exec(), not increase them.
</pre>
Each top-level branch of a look behind must be of a fixed length.
</P>
-<br><a name="SEC18" href="#TOC1">BACKREFERENCES</a><br>
+<br><a name="SEC20" href="#TOC1">BACKREFERENCES</a><br>
<P>
<pre>
\n reference by number (can be ambiguous)
@@ -421,7 +445,7 @@ Each top-level branch of a look behind must be of a fixed length.
(?P=name) reference by name (Python)
</PRE>
</P>
-<br><a name="SEC19" href="#TOC1">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a><br>
+<br><a name="SEC21" href="#TOC1">SUBROUTINE REFERENCES (POSSIBLY RECURSIVE)</a><br>
<P>
<pre>
(?R) recurse whole pattern
@@ -440,7 +464,7 @@ Each top-level branch of a look behind must be of a fixed length.
\g'-n' call subpattern by relative number (PCRE extension)
</PRE>
</P>
-<br><a name="SEC20" href="#TOC1">CONDITIONAL PATTERNS</a><br>
+<br><a name="SEC22" href="#TOC1">CONDITIONAL PATTERNS</a><br>
<P>
<pre>
(?(condition)yes-pattern)
@@ -459,7 +483,7 @@ Each top-level branch of a look behind must be of a fixed length.
(?(assert)... assertion condition
</PRE>
</P>
-<br><a name="SEC21" href="#TOC1">BACKTRACKING CONTROL</a><br>
+<br><a name="SEC23" href="#TOC1">BACKTRACKING CONTROL</a><br>
<P>
The following act immediately they are reached:
<pre>
@@ -482,27 +506,6 @@ pattern is not anchored.
(*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
</PRE>
</P>
-<br><a name="SEC22" href="#TOC1">NEWLINE CONVENTIONS</a><br>
-<P>
-These are recognized only at the very start of the pattern or after a
-(*BSR_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option.
-<pre>
- (*CR) carriage return only
- (*LF) linefeed only
- (*CRLF) carriage return followed by linefeed
- (*ANYCRLF) all three of the above
- (*ANY) any Unicode newline sequence
-</PRE>
-</P>
-<br><a name="SEC23" href="#TOC1">WHAT \R MATCHES</a><br>
-<P>
-These are recognized only at the very start of the pattern or after a
-(*...) option that sets the newline convention or a UTF or UCP mode.
-<pre>
- (*BSR_ANYCRLF) CR, LF, or CRLF
- (*BSR_UNICODE) any Unicode newline sequence
-</PRE>
-</P>
<br><a name="SEC24" href="#TOC1">CALLOUTS</a><br>
<P>
<pre>
@@ -526,9 +529,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC27" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 12 November 2013
+Last updated: 08 January 2014
<br>
-Copyright &copy; 1997-2013 University of Cambridge.
+Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/html/pcretest.html b/pcre/doc/html/pcretest.html
index 4ed1dfd0c74..839fabf189b 100644
--- a/pcre/doc/html/pcretest.html
+++ b/pcre/doc/html/pcretest.html
@@ -138,6 +138,9 @@ following options output the value and set the exit code as indicated:
newline the default newline setting:
CR, LF, CRLF, ANYCRLF, or ANY
exit code is always 0
+ bsr the default setting for what \R matches:
+ ANYCRLF or ANY
+ exit code is always 0
</pre>
The following options output 1 for true or 0 for false, and set the exit code
to the same value:
@@ -373,6 +376,7 @@ sections.
<b>/N</b> set PCRE_NO_AUTO_CAPTURE
<b>/O</b> set PCRE_NO_AUTO_POSSESS
<b>/P</b> use the POSIX wrapper
+ <b>/Q</b> test external stack check function
<b>/S</b> study the pattern after compilation
<b>/s</b> set PCRE_DOTALL
<b>/T</b> select character tables
@@ -534,7 +538,10 @@ below.
The <b>/I</b> modifier requests that <b>pcretest</b> output information about the
compiled pattern (whether it is anchored, has a fixed first character, and
so on). It does this by calling <b>pcre[16|32]_fullinfo()</b> after compiling a
-pattern. If the pattern is studied, the results of that are also output.
+pattern. If the pattern is studied, the results of that are also output. In
+this output, the word "char" means a non-UTF character, that is, the value of a
+single data item (8-bit, 16-bit, or 32-bit, depending on the library that is
+being tested).
</P>
<P>
The <b>/K</b> modifier requests <b>pcretest</b> to show names from backtracking
@@ -568,6 +575,14 @@ successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the
JIT compiled code is also output.
</P>
<P>
+The <b>/Q</b> modifier is used to test the use of <b>pcre_stack_guard</b>. It
+must be followed by '0' or '1', specifying the return code to be given from an
+external function that is passed to PCRE and used for stack checking during
+compilation (see the
+<a href="pcreapi.html"><b>pcreapi</b></a>
+documentation for details).
+</P>
+<P>
The <b>/S</b> modifier causes <b>pcre[16|32]_study()</b> to be called after the
expression has been compiled, and the results used when the expression is
matched. There are a number of qualifying characters that may follow <b>/S</b>.
@@ -1134,9 +1149,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC17" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 12 November 2013
+Last updated: 09 February 2014
<br>
-Copyright &copy; 1997-2013 University of Cambridge.
+Copyright &copy; 1997-2014 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/pcre.3 b/pcre/doc/pcre.3
index d92f9ef08de..4eda404ccff 100644
--- a/pcre/doc/pcre.3
+++ b/pcre/doc/pcre.3
@@ -1,4 +1,4 @@
-.TH PCRE 3 "01 Oct 2013" "PCRE 8.33"
+.TH PCRE 3 "08 January 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH INTRODUCTION
@@ -158,8 +158,11 @@ page.
The user documentation for PCRE comprises a number of different sections. In
the "man" format, each of these is a separate "man page". In the HTML format,
each is a separate page, linked from the index page. In the plain text format,
-all the sections, except the \fBpcredemo\fP section, are concatenated, for ease
-of searching. The sections are as follows:
+the descriptions of the \fBpcregrep\fP and \fBpcretest\fP programs are in files
+called \fBpcregrep.txt\fP and \fBpcretest.txt\fP, respectively. The remaining
+sections, except for the \fBpcredemo\fP section (which is a program listing),
+are concatenated in \fBpcre.txt\fP, for ease of searching. The sections are as
+follows:
.sp
pcre this document
pcre-config show PCRE installation configuration information
@@ -188,8 +191,8 @@ of searching. The sections are as follows:
pcretest description of the \fBpcretest\fP testing command
pcreunicode discussion of Unicode and UTF-8/16/32 support
.sp
-In addition, in the "man" and HTML formats, there is a short page for each
-C library function, listing its arguments and results.
+In the "man" and HTML formats, there is also a short page for each C library
+function, listing its arguments and results.
.
.
.SH AUTHOR
@@ -210,6 +213,6 @@ two digits 10, at the domain cam.ac.uk.
.rs
.sp
.nf
-Last updated: 13 May 2013
-Copyright (c) 1997-2013 University of Cambridge.
+Last updated: 08 January 2014
+Copyright (c) 1997-2014 University of Cambridge.
.fi
diff --git a/pcre/doc/pcre.txt b/pcre/doc/pcre.txt
index 9d69515c3b8..14cbb8bf2be 100644
--- a/pcre/doc/pcre.txt
+++ b/pcre/doc/pcre.txt
@@ -130,9 +130,11 @@ USER DOCUMENTATION
The user documentation for PCRE comprises a number of different sec-
tions. In the "man" format, each of these is a separate "man page". In
the HTML format, each is a separate page, linked from the index page.
- In the plain text format, all the sections, except the pcredemo sec-
- tion, are concatenated, for ease of searching. The sections are as fol-
- lows:
+ In the plain text format, the descriptions of the pcregrep and pcretest
+ programs are in files called pcregrep.txt and pcretest.txt, respec-
+ tively. The remaining sections, except for the pcredemo section (which
+ is a program listing), are concatenated in pcre.txt, for ease of
+ searching. The sections are as follows:
pcre this document
pcre-config show PCRE installation configuration information
@@ -160,8 +162,8 @@ USER DOCUMENTATION
pcretest description of the pcretest testing command
pcreunicode discussion of Unicode and UTF-8/16/32 support
- In addition, in the "man" and HTML formats, there is a short page for
- each C library function, listing its arguments and results.
+ In the "man" and HTML formats, there is also a short page for each C
+ library function, listing its arguments and results.
AUTHOR
@@ -177,8 +179,8 @@ AUTHOR
REVISION
- Last updated: 13 May 2013
- Copyright (c) 1997-2013 University of Cambridge.
+ Last updated: 08 January 2014
+ Copyright (c) 1997-2014 University of Cambridge.
------------------------------------------------------------------------------
@@ -1674,6 +1676,8 @@ PCRE NATIVE API INDIRECTED FUNCTIONS
int (*pcre_callout)(pcre_callout_block *);
+ int (*pcre_stack_guard)(void);
+
PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES
@@ -1809,6 +1813,14 @@ PCRE API OVERVIEW
specified points during a matching operation. Details are given in the
pcrecallout documentation.
+ The global variable pcre_stack_guard initially contains NULL. It can be
+ set by the caller to a function that is called by PCRE whenever it
+ starts to compile a parenthesized part of a pattern. When parentheses
+ are nested, PCRE uses recursive function calls, which use up the system
+ stack. This function is provided so that applications with restricted
+ stacks can force a compilation error if the stack runs out. The func-
+ tion should return zero if all is well, or non-zero to force an error.
+
NEWLINES
@@ -1849,25 +1861,26 @@ MULTITHREADING
The PCRE functions can be used in multi-threading applications, with
the proviso that the memory management functions pointed to by
pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the
- callout function pointed to by pcre_callout, are shared by all threads.
+ callout and stack-checking functions pointed to by pcre_callout and
+ pcre_stack_guard, are shared by all threads.
- The compiled form of a regular expression is not altered during match-
+ The compiled form of a regular expression is not altered during match-
ing, so the same compiled pattern can safely be used by several threads
at once.
- If the just-in-time optimization feature is being used, it needs sepa-
- rate memory stack areas for each thread. See the pcrejit documentation
+ If the just-in-time optimization feature is being used, it needs sepa-
+ rate memory stack areas for each thread. See the pcrejit documentation
for more details.
SAVING PRECOMPILED PATTERNS FOR LATER USE
The compiled form of a regular expression can be saved and re-used at a
- later time, possibly by a different program, and even on a host other
- than the one on which it was compiled. Details are given in the
- pcreprecompile documentation, which includes a description of the
- pcre_pattern_to_host_byte_order() function. However, compiling a regu-
- lar expression with one version of PCRE for use with a different ver-
+ later time, possibly by a different program, and even on a host other
+ than the one on which it was compiled. Details are given in the
+ pcreprecompile documentation, which includes a description of the
+ pcre_pattern_to_host_byte_order() function. However, compiling a regu-
+ lar expression with one version of PCRE for use with a different ver-
sion is not guaranteed to work and may cause crashes.
@@ -1875,45 +1888,45 @@ CHECKING BUILD-TIME OPTIONS
int pcre_config(int what, void *where);
- The function pcre_config() makes it possible for a PCRE client to dis-
+ The function pcre_config() makes it possible for a PCRE client to dis-
cover which optional features have been compiled into the PCRE library.
- The pcrebuild documentation has more details about these optional fea-
+ The pcrebuild documentation has more details about these optional fea-
tures.
- The first argument for pcre_config() is an integer, specifying which
+ The first argument for pcre_config() is an integer, specifying which
information is required; the second argument is a pointer to a variable
- into which the information is placed. The returned value is zero on
- success, or the negative error code PCRE_ERROR_BADOPTION if the value
- in the first argument is not recognized. The following information is
+ into which the information is placed. The returned value is zero on
+ success, or the negative error code PCRE_ERROR_BADOPTION if the value
+ in the first argument is not recognized. The following information is
available:
PCRE_CONFIG_UTF8
- The output is an integer that is set to one if UTF-8 support is avail-
- able; otherwise it is set to zero. This value should normally be given
+ The output is an integer that is set to one if UTF-8 support is avail-
+ able; otherwise it is set to zero. This value should normally be given
to the 8-bit version of this function, pcre_config(). If it is given to
- the 16-bit or 32-bit version of this function, the result is
+ the 16-bit or 32-bit version of this function, the result is
PCRE_ERROR_BADOPTION.
PCRE_CONFIG_UTF16
The output is an integer that is set to one if UTF-16 support is avail-
- able; otherwise it is set to zero. This value should normally be given
+ able; otherwise it is set to zero. This value should normally be given
to the 16-bit version of this function, pcre16_config(). If it is given
- to the 8-bit or 32-bit version of this function, the result is
+ to the 8-bit or 32-bit version of this function, the result is
PCRE_ERROR_BADOPTION.
PCRE_CONFIG_UTF32
The output is an integer that is set to one if UTF-32 support is avail-
- able; otherwise it is set to zero. This value should normally be given
+ able; otherwise it is set to zero. This value should normally be given
to the 32-bit version of this function, pcre32_config(). If it is given
- to the 8-bit or 16-bit version of this function, the result is
+ to the 8-bit or 16-bit version of this function, the result is
PCRE_ERROR_BADOPTION.
PCRE_CONFIG_UNICODE_PROPERTIES
- The output is an integer that is set to one if support for Unicode
+ The output is an integer that is set to one if support for Unicode
character properties is available; otherwise it is set to zero.
PCRE_CONFIG_JIT
@@ -1923,55 +1936,58 @@ CHECKING BUILD-TIME OPTIONS
PCRE_CONFIG_JITTARGET
- The output is a pointer to a zero-terminated "const char *" string. If
+ The output is a pointer to a zero-terminated "const char *" string. If
JIT support is available, the string contains the name of the architec-
- ture for which the JIT compiler is configured, for example "x86 32bit
- (little endian + unaligned)". If JIT support is not available, the
+ ture for which the JIT compiler is configured, for example "x86 32bit
+ (little endian + unaligned)". If JIT support is not available, the
result is NULL.
PCRE_CONFIG_NEWLINE
- The output is an integer whose value specifies the default character
- sequence that is recognized as meaning "newline". The values that are
+ The output is an integer whose value specifies the default character
+ sequence that is recognized as meaning "newline". The values that are
supported in ASCII/Unicode environments are: 10 for LF, 13 for CR, 3338
- for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR,
- ANYCRLF, and ANY yield the same values. However, the value for LF is
- normally 21, though some EBCDIC environments use 37. The corresponding
- values for CRLF are 3349 and 3365. The default should normally corre-
+ for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR,
+ ANYCRLF, and ANY yield the same values. However, the value for LF is
+ normally 21, though some EBCDIC environments use 37. The corresponding
+ values for CRLF are 3349 and 3365. The default should normally corre-
spond to the standard sequence for your operating system.
PCRE_CONFIG_BSR
The output is an integer whose value indicates what character sequences
- the \R escape sequence matches by default. A value of 0 means that \R
- matches any Unicode line ending sequence; a value of 1 means that \R
+ the \R escape sequence matches by default. A value of 0 means that \R
+ matches any Unicode line ending sequence; a value of 1 means that \R
matches only CR, LF, or CRLF. The default can be overridden when a pat-
tern is compiled or matched.
PCRE_CONFIG_LINK_SIZE
- The output is an integer that contains the number of bytes used for
+ The output is an integer that contains the number of bytes used for
internal linkage in compiled regular expressions. For the 8-bit
library, the value can be 2, 3, or 4. For the 16-bit library, the value
- is either 2 or 4 and is still a number of bytes. For the 32-bit
+ is either 2 or 4 and is still a number of bytes. For the 32-bit
library, the value is either 2 or 4 and is still a number of bytes. The
default value of 2 is sufficient for all but the most massive patterns,
- since it allows the compiled pattern to be up to 64K in size. Larger
- values allow larger regular expressions to be compiled, at the expense
+ since it allows the compiled pattern to be up to 64K in size. Larger
+ values allow larger regular expressions to be compiled, at the expense
of slower matching.
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
- The output is an integer that contains the threshold above which the
- POSIX interface uses malloc() for output vectors. Further details are
+ The output is an integer that contains the threshold above which the
+ POSIX interface uses malloc() for output vectors. Further details are
given in the pcreposix documentation.
PCRE_CONFIG_PARENS_LIMIT
The output is a long integer that gives the maximum depth of nesting of
- parentheses (of any kind) in a pattern. This limit is imposed to cap
+ parentheses (of any kind) in a pattern. This limit is imposed to cap
the amount of system stack used when a pattern is compiled. It is spec-
- ified when PCRE is built; the default is 250.
+ ified when PCRE is built; the default is 250. This limit does not take
+ into account the stack that may already be used by the calling applica-
+ tion. For finer control over compilation stack usage, you can set a
+ pointer to an external checking function in pcre_stack_guard.
PCRE_CONFIG_MATCH_LIMIT
@@ -2474,6 +2490,8 @@ COMPILATION ERROR CODES
81 missing opening brace after \o
82 parentheses are too deeply nested
83 invalid range in character class
+ 84 group name must start with a non-digit
+ 85 parentheses are too deeply nested (stack check)
The numbers 32 and 10000 in errors 48 and 49 are defaults; different
values may be used if the limits were changed when PCRE was built.
@@ -2714,12 +2732,16 @@ INFORMATION ABOUT A PATTERN
tion. External callers can cause PCRE to use its internal tables by
passing a NULL table pointer.
- PCRE_INFO_FIRSTBYTE
+ PCRE_INFO_FIRSTBYTE (deprecated)
Return information about the first data unit of any matched string, for
- a non-anchored pattern. (The name of this option refers to the 8-bit
- library, where data units are bytes.) The fourth argument should point
- to an int variable.
+ a non-anchored pattern. The name of this option refers to the 8-bit
+ library, where data units are bytes. The fourth argument should point
+ to an int variable. Negative values are used for special cases. How-
+ ever, this means that when the 32-bit library is in non-UTF-32 mode,
+ the full 32-bit range of characters cannot be returned. For this rea-
+ son, this value is deprecated; use PCRE_INFO_FIRSTCHARACTERFLAGS and
+ PCRE_INFO_FIRSTCHARACTER instead.
If there is a fixed first value, for example, the letter "c" from a
pattern such as (cat|cow|coyote), its value is returned. In the 8-bit
@@ -2739,10 +2761,38 @@ INFORMATION ABOUT A PATTERN
of a subject string or after any newline within the string. Otherwise
-2 is returned. For anchored patterns, -2 is returned.
- Since for the 32-bit library using the non-UTF-32 mode, this function
- is unable to return the full 32-bit range of the character, this value
- is deprecated; instead the PCRE_INFO_FIRSTCHARACTERFLAGS and
- PCRE_INFO_FIRSTCHARACTER values should be used.
+ PCRE_INFO_FIRSTCHARACTER
+
+ Return the value of the first data unit (non-UTF character) of any
+ matched string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS
+ returns 1; otherwise return 0. The fourth argument should point to an
+ uint_t variable.
+
+ In the 8-bit library, the value is always less than 256. In the 16-bit
+ library the value can be up to 0xffff. In the 32-bit library in UTF-32
+ mode the value can be up to 0x10ffff, and up to 0xffffffff when not
+ using UTF-32 mode.
+
+ PCRE_INFO_FIRSTCHARACTERFLAGS
+
+ Return information about the first data unit of any matched string, for
+ a non-anchored pattern. The fourth argument should point to an int
+ variable.
+
+ If there is a fixed first value, for example, the letter "c" from a
+ pattern such as (cat|cow|coyote), 1 is returned, and the character
+ value can be retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no
+ fixed first value, and if either
+
+ (a) the pattern was compiled with the PCRE_MULTILINE option, and every
+ branch starts with "^", or
+
+ (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not
+ set (if it were set, the pattern would be anchored),
+
+ 2 is returned, indicating that the pattern matches only at the start of
+ a subject string or after any newline within the string. Otherwise 0 is
+ returned. For anchored patterns, 0 is returned.
PCRE_INFO_FIRSTTABLE
@@ -2954,57 +3004,24 @@ INFORMATION ABOUT A PATTERN
option so that it can be saved and restored (see the pcreprecompile
documentation for details).
- PCRE_INFO_FIRSTCHARACTERFLAGS
-
- Return information about the first data unit of any matched string, for
- a non-anchored pattern. The fourth argument should point to an int
- variable.
-
- If there is a fixed first value, for example, the letter "c" from a
- pattern such as (cat|cow|coyote), 1 is returned, and the character
- value can be retrieved using PCRE_INFO_FIRSTCHARACTER.
-
- If there is no fixed first value, and if either
-
- (a) the pattern was compiled with the PCRE_MULTILINE option, and every
- branch starts with "^", or
-
- (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not
- set (if it were set, the pattern would be anchored),
-
- 2 is returned, indicating that the pattern matches only at the start of
- a subject string or after any newline within the string. Otherwise 0 is
- returned. For anchored patterns, 0 is returned.
-
- PCRE_INFO_FIRSTCHARACTER
-
- Return the fixed first character value in the situation where
- PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; otherwise return 0. The fourth
- argument should point to an uint_t variable.
-
- In the 8-bit library, the value is always less than 256. In the 16-bit
- library the value can be up to 0xffff. In the 32-bit library in UTF-32
- mode the value can be up to 0x10ffff, and up to 0xffffffff when not
- using UTF-32 mode.
-
PCRE_INFO_REQUIREDCHARFLAGS
- Returns 1 if there is a rightmost literal data unit that must exist in
+ Returns 1 if there is a rightmost literal data unit that must exist in
any matched string, other than at its start. The fourth argument should
- point to an int variable. If there is no such value, 0 is returned. If
+ point to an int variable. If there is no such value, 0 is returned. If
returning 1, the character value itself can be retrieved using
PCRE_INFO_REQUIREDCHAR.
For anchored patterns, a last literal value is recorded only if it fol-
- lows something of variable length. For example, for the pattern
- /^a\d+z\d+/ the returned value 1 (with "z" returned from
+ lows something of variable length. For example, for the pattern
+ /^a\d+z\d+/ the returned value 1 (with "z" returned from
PCRE_INFO_REQUIREDCHAR), but for /^a\dz\d/ the returned value is 0.
PCRE_INFO_REQUIREDCHAR
- Return the value of the rightmost literal data unit that must exist in
- any matched string, other than at its start, if such a value has been
- recorded. The fourth argument should point to an uint32_t variable. If
+ Return the value of the rightmost literal data unit that must exist in
+ any matched string, other than at its start, if such a value has been
+ recorded. The fourth argument should point to an uint32_t variable. If
there is no such value, 0 is returned.
@@ -3012,21 +3029,21 @@ REFERENCE COUNTS
int pcre_refcount(pcre *code, int adjust);
- The pcre_refcount() function is used to maintain a reference count in
+ The pcre_refcount() function is used to maintain a reference count in
the data block that contains a compiled pattern. It is provided for the
- benefit of applications that operate in an object-oriented manner,
+ benefit of applications that operate in an object-oriented manner,
where different parts of the application may be using the same compiled
pattern, but you want to free the block when they are all done.
When a pattern is compiled, the reference count field is initialized to
- zero. It is changed only by calling this function, whose action is to
- add the adjust value (which may be positive or negative) to it. The
+ zero. It is changed only by calling this function, whose action is to
+ add the adjust value (which may be positive or negative) to it. The
yield of the function is the new value. However, the value of the count
- is constrained to lie between 0 and 65535, inclusive. If the new value
+ is constrained to lie between 0 and 65535, inclusive. If the new value
is outside these limits, it is forced to the appropriate limit value.
- Except when it is zero, the reference count is not correctly preserved
- if a pattern is compiled on one host and then transferred to a host
+ Except when it is zero, the reference count is not correctly preserved
+ if a pattern is compiled on one host and then transferred to a host
whose byte-order is different. (This seems a highly unlikely scenario.)
@@ -3036,22 +3053,22 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
const char *subject, int length, int startoffset,
int options, int *ovector, int ovecsize);
- The function pcre_exec() is called to match a subject string against a
- compiled pattern, which is passed in the code argument. If the pattern
- was studied, the result of the study should be passed in the extra
- argument. You can call pcre_exec() with the same code and extra argu-
- ments as many times as you like, in order to match different subject
+ The function pcre_exec() is called to match a subject string against a
+ compiled pattern, which is passed in the code argument. If the pattern
+ was studied, the result of the study should be passed in the extra
+ argument. You can call pcre_exec() with the same code and extra argu-
+ ments as many times as you like, in order to match different subject
strings with the same pattern.
- This function is the main matching facility of the library, and it
- operates in a Perl-like manner. For specialist use there is also an
- alternative matching function, which is described below in the section
+ This function is the main matching facility of the library, and it
+ operates in a Perl-like manner. For specialist use there is also an
+ alternative matching function, which is described below in the section
about the pcre_dfa_exec() function.
- In most applications, the pattern will have been compiled (and option-
- ally studied) in the same process that calls pcre_exec(). However, it
+ In most applications, the pattern will have been compiled (and option-
+ ally studied) in the same process that calls pcre_exec(). However, it
is possible to save compiled patterns and study data, and then use them
- later in different processes, possibly even on different hosts. For a
+ later in different processes, possibly even on different hosts. For a
discussion about this, see the pcreprecompile documentation.
Here is an example of a simple call to pcre_exec():
@@ -3070,10 +3087,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
Extra data for pcre_exec()
- If the extra argument is not NULL, it must point to a pcre_extra data
- block. The pcre_study() function returns such a block (when it doesn't
- return NULL), but you can also create one for yourself, and pass addi-
- tional information in it. The pcre_extra block contains the following
+ If the extra argument is not NULL, it must point to a pcre_extra data
+ block. The pcre_study() function returns such a block (when it doesn't
+ return NULL), but you can also create one for yourself, and pass addi-
+ tional information in it. The pcre_extra block contains the following
fields (not necessarily in this order):
unsigned long int flags;
@@ -3085,13 +3102,13 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
const unsigned char *tables;
unsigned char **mark;
- In the 16-bit version of this structure, the mark field has type
+ In the 16-bit version of this structure, the mark field has type
"PCRE_UCHAR16 **".
- In the 32-bit version of this structure, the mark field has type
+ In the 32-bit version of this structure, the mark field has type
"PCRE_UCHAR32 **".
- The flags field is used to specify which of the other fields are set.
+ The flags field is used to specify which of the other fields are set.
The flag bits are:
PCRE_EXTRA_CALLOUT_DATA
@@ -3102,134 +3119,134 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_EXTRA_STUDY_DATA
PCRE_EXTRA_TABLES
- Other flag bits should be set to zero. The study_data field and some-
- times the executable_jit field are set in the pcre_extra block that is
- returned by pcre_study(), together with the appropriate flag bits. You
- should not set these yourself, but you may add to the block by setting
+ Other flag bits should be set to zero. The study_data field and some-
+ times the executable_jit field are set in the pcre_extra block that is
+ returned by pcre_study(), together with the appropriate flag bits. You
+ should not set these yourself, but you may add to the block by setting
other fields and their corresponding flag bits.
The match_limit field provides a means of preventing PCRE from using up
- a vast amount of resources when running patterns that are not going to
- match, but which have a very large number of possibilities in their
- search trees. The classic example is a pattern that uses nested unlim-
+ a vast amount of resources when running patterns that are not going to
+ match, but which have a very large number of possibilities in their
+ search trees. The classic example is a pattern that uses nested unlim-
ited repeats.
- Internally, pcre_exec() uses a function called match(), which it calls
- repeatedly (sometimes recursively). The limit set by match_limit is
- imposed on the number of times this function is called during a match,
- which has the effect of limiting the amount of backtracking that can
+ Internally, pcre_exec() uses a function called match(), which it calls
+ repeatedly (sometimes recursively). The limit set by match_limit is
+ imposed on the number of times this function is called during a match,
+ which has the effect of limiting the amount of backtracking that can
take place. For patterns that are not anchored, the count restarts from
zero for each position in the subject string.
When pcre_exec() is called with a pattern that was successfully studied
- with a JIT option, the way that the matching is executed is entirely
+ with a JIT option, the way that the matching is executed is entirely
different. However, there is still the possibility of runaway matching
that goes on for a very long time, and so the match_limit value is also
used in this case (but in a different way) to limit how long the match-
ing can continue.
- 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 pcre_exec() with a
- pcre_extra block in which match_limit is set, and
- PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is
+ 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 pcre_exec() with a
+ pcre_extra block in which match_limit is set, and
+ PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is
exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT.
- A value for the match limit may also be supplied by an item at the
+ A value for the match limit may also be supplied by an item at the
start of a pattern of the form
(*LIMIT_MATCH=d)
- where d is a decimal number. However, such a setting is ignored unless
- d is less than the limit set by the caller of pcre_exec() or, if no
+ where d is a decimal number. However, such a setting is ignored unless
+ d is less than the limit set by the caller of pcre_exec() or, if no
such limit is set, less than the default.
- The match_limit_recursion field is similar to match_limit, but instead
+ The match_limit_recursion field is similar to match_limit, but instead
of limiting the total number of times that match() is called, it limits
- the depth of recursion. The recursion depth is a smaller number than
- the total number of calls, because not all calls to match() are recur-
+ the depth of recursion. The recursion depth is a smaller number than
+ the total number of calls, because not all calls to match() are recur-
sive. This limit is of use only if it is set smaller than match_limit.
- Limiting the recursion depth limits the amount of machine stack that
- can be used, or, when PCRE has been compiled to use memory on the heap
- instead of the stack, the amount of heap memory that can be used. This
- limit is not relevant, and is ignored, when matching is done using JIT
+ Limiting the recursion depth limits the amount of machine stack that
+ can be used, or, when PCRE has been compiled to use memory on the heap
+ instead of the stack, the amount of heap memory that can be used. This
+ limit is not relevant, and is ignored, when matching is done using JIT
compiled code.
- 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
- a pcre_extra block in which match_limit_recursion is set, and
- PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the
+ 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
+ a pcre_extra block in which match_limit_recursion is set, and
+ PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the
limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT.
- A value for the recursion limit may also be supplied by an item at the
+ A value for the recursion limit may also be supplied by an item at the
start of a pattern of the form
(*LIMIT_RECURSION=d)
- where d is a decimal number. However, such a setting is ignored unless
- d is less than the limit set by the caller of pcre_exec() or, if no
+ where d is a decimal number. However, such a setting is ignored unless
+ d is less than the limit set by the caller of pcre_exec() or, if no
such limit is set, less than the default.
- The callout_data field is used in conjunction with the "callout" fea-
+ The callout_data field is used in conjunction with the "callout" fea-
ture, and is described in the pcrecallout documentation.
- The tables field is provided for use with patterns that have been pre-
+ The tables field is provided for use with patterns that have been pre-
compiled using custom character tables, saved to disc or elsewhere, and
- then reloaded, because the tables that were used to compile a pattern
- are not saved with it. See the pcreprecompile documentation for a dis-
- cussion of saving compiled patterns for later use. If NULL is passed
+ then reloaded, because the tables that were used to compile a pattern
+ are not saved with it. See the pcreprecompile documentation for a dis-
+ cussion of saving compiled patterns for later use. If NULL is passed
using this mechanism, it forces PCRE's internal tables to be used.
- Warning: The tables that pcre_exec() uses must be the same as those
- that were used when the pattern was compiled. If this is not the case,
+ Warning: The tables that pcre_exec() uses must be the same as those
+ that were used when the pattern was compiled. If this is not the case,
the behaviour of pcre_exec() is undefined. Therefore, when a pattern is
- compiled and matched in the same process, this field should never be
+ compiled and matched in the same process, this field should never be
set. In this (the most common) case, the correct table pointer is auto-
- matically passed with the compiled pattern from pcre_compile() to
+ matically passed with the compiled pattern from pcre_compile() to
pcre_exec().
- If PCRE_EXTRA_MARK is set in the flags field, the mark field must be
- set to point to a suitable variable. If the pattern contains any back-
- tracking control verbs such as (*MARK:NAME), and the execution ends up
- with a name to pass back, a pointer to the name string (zero termi-
- nated) is placed in the variable pointed to by the mark field. The
- names are within the compiled pattern; if you wish to retain such a
- name you must copy it before freeing the memory of a compiled pattern.
- If there is no name to pass back, the variable pointed to by the mark
- field is set to NULL. For details of the backtracking control verbs,
+ If PCRE_EXTRA_MARK is set in the flags field, the mark field must be
+ set to point to a suitable variable. If the pattern contains any back-
+ tracking control verbs such as (*MARK:NAME), and the execution ends up
+ with a name to pass back, a pointer to the name string (zero termi-
+ nated) is placed in the variable pointed to by the mark field. The
+ names are within the compiled pattern; if you wish to retain such a
+ name you must copy it before freeing the memory of a compiled pattern.
+ If there is no name to pass back, the variable pointed to by the mark
+ field is set to NULL. For details of the backtracking control verbs,
see the section entitled "Backtracking control" in the pcrepattern doc-
umentation.
Option bits for pcre_exec()
- The unused bits of the options argument for pcre_exec() must be zero.
- The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx,
- PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
- PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and
+ The unused bits of the options argument for pcre_exec() must be zero.
+ The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx,
+ PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
+ PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and
PCRE_PARTIAL_SOFT.
- If the pattern was successfully studied with one of the just-in-time
+ If the pattern was successfully studied with one of the just-in-time
(JIT) compile options, the only supported options for JIT execution are
- PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
- PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an
- unsupported option is used, JIT execution is disabled and the normal
+ PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
+ PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an
+ unsupported option is used, JIT execution is disabled and the normal
interpretive code in pcre_exec() is run.
PCRE_ANCHORED
- The PCRE_ANCHORED option limits pcre_exec() to matching at the first
- matching position. If a pattern was compiled with PCRE_ANCHORED, or
- turned out to be anchored by virtue of its contents, it cannot be made
+ The PCRE_ANCHORED option limits pcre_exec() to matching at the first
+ matching position. If a pattern was compiled with PCRE_ANCHORED, or
+ turned out to be anchored by virtue of its contents, it cannot be made
unachored at matching time.
PCRE_BSR_ANYCRLF
PCRE_BSR_UNICODE
These options (which are mutually exclusive) control what the \R escape
- sequence matches. The choice is either to match only CR, LF, or CRLF,
- or to match any Unicode newline sequence. These options override the
+ sequence matches. The choice is either to match only CR, LF, or CRLF,
+ or to match any Unicode newline sequence. These options override the
choice that was made or defaulted when the pattern was compiled.
PCRE_NEWLINE_CR
@@ -3238,345 +3255,345 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_NEWLINE_ANYCRLF
PCRE_NEWLINE_ANY
- These options override the newline definition that was chosen or
- defaulted when the pattern was compiled. For details, see the descrip-
- tion of pcre_compile() above. During matching, the newline choice
- affects the behaviour of the dot, circumflex, and dollar metacharac-
- ters. It may also alter the way the match position is advanced after a
+ These options override the newline definition that was chosen or
+ defaulted when the pattern was compiled. For details, see the descrip-
+ tion of pcre_compile() above. During matching, the newline choice
+ affects the behaviour of the dot, circumflex, and dollar metacharac-
+ ters. It may also alter the way the match position is advanced after a
match failure for an unanchored pattern.
- When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is
- set, and a match attempt for an unanchored pattern fails when the cur-
- rent position is at a CRLF sequence, and the pattern contains no
- explicit matches for CR or LF characters, the match position is
+ When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is
+ set, and a match attempt for an unanchored pattern fails when the cur-
+ rent position is at a CRLF sequence, and the pattern contains no
+ explicit matches for CR or LF characters, the match position is
advanced by two characters instead of one, in other words, to after the
CRLF.
The above rule is a compromise that makes the most common cases work as
- expected. For example, if the pattern is .+A (and the PCRE_DOTALL
+ expected. For example, if the pattern is .+A (and the PCRE_DOTALL
option is not set), it does not match the string "\r\nA" because, after
- failing at the start, it skips both the CR and the LF before retrying.
- However, the pattern [\r\n]A does match that string, because it con-
+ failing at the start, it skips both the CR and the LF before retrying.
+ However, the pattern [\r\n]A does match that string, because it con-
tains an explicit CR or LF reference, and so advances only by one char-
acter after the first failure.
An explicit match for CR of LF is either a literal appearance of one of
- those characters, or one of the \r or \n escape sequences. Implicit
- matches such as [^X] do not count, nor does \s (which includes CR and
+ those characters, or one of the \r or \n escape sequences. Implicit
+ matches such as [^X] do not count, nor does \s (which includes CR and
LF in the characters that it matches).
- Notwithstanding the above, anomalous effects may still occur when CRLF
+ Notwithstanding the above, anomalous effects may still occur when CRLF
is a valid newline sequence and explicit \r or \n escapes appear in the
pattern.
PCRE_NOTBOL
This option specifies that first character of the subject string is not
- the beginning of a line, so the circumflex metacharacter should not
- match before it. Setting this without PCRE_MULTILINE (at compile time)
- causes circumflex never to match. This option affects only the behav-
+ the beginning of a line, so the circumflex metacharacter should not
+ match before it. Setting this without PCRE_MULTILINE (at compile time)
+ causes circumflex never to match. This option affects only the behav-
iour of the circumflex metacharacter. It does not affect \A.
PCRE_NOTEOL
This option specifies that the end of the subject string is not the end
- of a line, so the dollar metacharacter should not match it nor (except
- in multiline mode) a newline immediately before it. Setting this with-
+ of a line, so the dollar metacharacter should not match it nor (except
+ in multiline mode) a newline immediately before it. Setting this with-
out PCRE_MULTILINE (at compile time) causes dollar never to match. This
- option affects only the behaviour of the dollar metacharacter. It does
+ option affects only the behaviour of the dollar metacharacter. It does
not affect \Z or \z.
PCRE_NOTEMPTY
An empty string is not considered to be a valid match if this option is
- set. If there are alternatives in the pattern, they are tried. If all
- the alternatives match the empty string, the entire match fails. For
+ set. If there are alternatives in the pattern, they are tried. If all
+ the alternatives match the empty string, the entire match fails. For
example, if the pattern
a?b?
- is applied to a string not beginning with "a" or "b", it matches an
- empty string at the start of the subject. With PCRE_NOTEMPTY set, this
+ is applied to a string not beginning with "a" or "b", it matches an
+ empty string at the start of the subject. With PCRE_NOTEMPTY set, this
match is not valid, so PCRE searches further into the string for occur-
rences of "a" or "b".
PCRE_NOTEMPTY_ATSTART
- This is like PCRE_NOTEMPTY, except that an empty string match that is
- not at the start of the subject is permitted. If the pattern is
+ This is like PCRE_NOTEMPTY, except that an empty string match that is
+ not at the start of the subject is permitted. If the pattern is
anchored, such a match can occur only if the pattern contains \K.
- Perl has no direct equivalent of PCRE_NOTEMPTY or
- PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern
- match of the empty string within its split() function, and when using
- the /g modifier. It is possible to emulate Perl's behaviour after
+ Perl has no direct equivalent of PCRE_NOTEMPTY or
+ PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern
+ match of the empty string within its split() function, and when using
+ the /g modifier. It is possible to emulate Perl's behaviour after
matching a null string by first trying the match again at the same off-
- set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that
+ set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that
fails, by advancing the starting offset (see below) and trying an ordi-
- nary match again. There is some code that demonstrates how to do this
- in the pcredemo sample program. In the most general case, you have to
- check to see if the newline convention recognizes CRLF as a newline,
- and if so, and the current character is CR followed by LF, advance the
+ nary match again. There is some code that demonstrates how to do this
+ in the pcredemo sample program. In the most general case, you have to
+ check to see if the newline convention recognizes CRLF as a newline,
+ and if so, and the current character is CR followed by LF, advance the
starting offset by two characters instead of one.
PCRE_NO_START_OPTIMIZE
- There are a number of optimizations that pcre_exec() uses at the start
- of a match, in order to speed up the process. For example, if it is
+ There are a number of optimizations that pcre_exec() uses at the start
+ of a match, in order to speed up the process. For example, if it is
known that an unanchored match must start with a specific character, it
- searches the subject for that character, and fails immediately if it
- cannot find it, without actually running the main matching function.
+ searches the subject for that character, and fails immediately if it
+ cannot find it, without actually running the main matching function.
This means that a special item such as (*COMMIT) at the start of a pat-
- tern is not considered until after a suitable starting point for the
- match has been found. Also, when callouts or (*MARK) items are in use,
+ tern is not considered until after a suitable starting point for the
+ match has been found. Also, when callouts or (*MARK) items are in use,
these "start-up" optimizations can cause them to be skipped if the pat-
tern is never actually used. The start-up optimizations are in effect a
pre-scan of the subject that takes place before the pattern is run.
- The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations,
- possibly causing performance to suffer, but ensuring that in cases
- where the result is "no match", the callouts do occur, and that items
+ The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations,
+ possibly causing performance to suffer, but ensuring that in cases
+ where the result is "no match", the callouts do occur, and that items
such as (*COMMIT) and (*MARK) are considered at every possible starting
- position in the subject string. If PCRE_NO_START_OPTIMIZE is set at
- compile time, it cannot be unset at matching time. The use of
+ position in the subject string. If PCRE_NO_START_OPTIMIZE is set at
+ compile time, it cannot be unset at matching time. The use of
PCRE_NO_START_OPTIMIZE at matching time (that is, passing it to
- pcre_exec()) disables JIT execution; in this situation, matching is
+ pcre_exec()) disables JIT execution; in this situation, matching is
always done using interpretively.
- Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching
+ Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching
operation. Consider the pattern
(*COMMIT)ABC
- When this is compiled, PCRE records the fact that a match must start
- with the character "A". Suppose the subject string is "DEFABC". The
- start-up optimization scans along the subject, finds "A" and runs the
- first match attempt from there. The (*COMMIT) item means that the pat-
- tern must match the current starting position, which in this case, it
- does. However, if the same match is run with PCRE_NO_START_OPTIMIZE
- set, the initial scan along the subject string does not happen. The
- first match attempt is run starting from "D" and when this fails,
- (*COMMIT) prevents any further matches being tried, so the overall
- result is "no match". If the pattern is studied, more start-up opti-
- mizations may be used. For example, a minimum length for the subject
+ When this is compiled, PCRE records the fact that a match must start
+ with the character "A". Suppose the subject string is "DEFABC". The
+ start-up optimization scans along the subject, finds "A" and runs the
+ first match attempt from there. The (*COMMIT) item means that the pat-
+ tern must match the current starting position, which in this case, it
+ does. However, if the same match is run with PCRE_NO_START_OPTIMIZE
+ set, the initial scan along the subject string does not happen. The
+ first match attempt is run starting from "D" and when this fails,
+ (*COMMIT) prevents any further matches being tried, so the overall
+ result is "no match". If the pattern is studied, more start-up opti-
+ mizations may be used. For example, a minimum length for the subject
may be recorded. Consider the pattern
(*MARK:A)(X|Y)
- The minimum length for a match is one character. If the subject is
- "ABC", there will be attempts to match "ABC", "BC", "C", and then
- finally an empty string. If the pattern is studied, the final attempt
- does not take place, because PCRE knows that the subject is too short,
- and so the (*MARK) is never encountered. In this case, studying the
- pattern does not affect the overall match result, which is still "no
+ The minimum length for a match is one character. If the subject is
+ "ABC", there will be attempts to match "ABC", "BC", "C", and then
+ finally an empty string. If the pattern is studied, the final attempt
+ does not take place, because PCRE knows that the subject is too short,
+ and so the (*MARK) is never encountered. In this case, studying the
+ pattern does not affect the overall match result, which is still "no
match", but it does affect the auxiliary information that is returned.
PCRE_NO_UTF8_CHECK
When PCRE_UTF8 is set at compile time, the validity of the subject as a
- UTF-8 string is automatically checked when pcre_exec() is subsequently
+ UTF-8 string is automatically checked when pcre_exec() is subsequently
called. The entire string is checked before any other processing takes
- place. The value of startoffset is also checked to ensure that it
- points to the start of a UTF-8 character. There is a discussion about
- the validity of UTF-8 strings in the pcreunicode page. If an invalid
- sequence of bytes is found, pcre_exec() returns the error
+ place. The value of startoffset is also checked to ensure that it
+ points to the start of a UTF-8 character. There is a discussion about
+ the validity of UTF-8 strings in the pcreunicode page. If an invalid
+ sequence of bytes is found, pcre_exec() returns the error
PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a
truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In
- both cases, information about the precise nature of the error may also
- be returned (see the descriptions of these errors in the section enti-
- tled Error return values from pcre_exec() below). If startoffset con-
+ both cases, information about the precise nature of the error may also
+ be returned (see the descriptions of these errors in the section enti-
+ tled Error return values from pcre_exec() below). If startoffset con-
tains a value that does not point to the start of a UTF-8 character (or
to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned.
- If you already know that your subject is valid, and you want to skip
- these checks for performance reasons, you can set the
- PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to
- do this for the second and subsequent calls to pcre_exec() if you are
- making repeated calls to find all the matches in a single subject
- string. However, you should be sure that the value of startoffset
- points to the start of a character (or the end of the subject). When
+ If you already know that your subject is valid, and you want to skip
+ these checks for performance reasons, you can set the
+ PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to
+ do this for the second and subsequent calls to pcre_exec() if you are
+ making repeated calls to find all the matches in a single subject
+ string. However, you should be sure that the value of startoffset
+ points to the start of a character (or the end of the subject). When
PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a
- subject or an invalid value of startoffset is undefined. Your program
+ subject or an invalid value of startoffset is undefined. Your program
may crash or loop.
PCRE_PARTIAL_HARD
PCRE_PARTIAL_SOFT
- These options turn on the partial matching feature. For backwards com-
- patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial
- match occurs if the end of the subject string is reached successfully,
- but there are not enough subject characters to complete the match. If
+ These options turn on the partial matching feature. For backwards com-
+ patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial
+ match occurs if the end of the subject string is reached successfully,
+ but there are not enough subject characters to complete the match. If
this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set,
- matching continues by testing any remaining alternatives. Only if no
- complete match can be found is PCRE_ERROR_PARTIAL returned instead of
- PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the
- caller is prepared to handle a partial match, but only if no complete
+ matching continues by testing any remaining alternatives. Only if no
+ complete match can be found is PCRE_ERROR_PARTIAL returned instead of
+ PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the
+ caller is prepared to handle a partial match, but only if no complete
match can be found.
- If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this
- case, if a partial match is found, pcre_exec() immediately returns
- PCRE_ERROR_PARTIAL, without considering any other alternatives. In
- other words, when PCRE_PARTIAL_HARD is set, a partial match is consid-
+ If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this
+ case, if a partial match is found, pcre_exec() immediately returns
+ PCRE_ERROR_PARTIAL, without considering any other alternatives. In
+ other words, when PCRE_PARTIAL_HARD is set, a partial match is consid-
ered to be more important that an alternative complete match.
- In both cases, the portion of the string that was inspected when the
+ In both cases, the portion of the string that was inspected when the
partial match was found is set as the first matching string. There is a
- more detailed discussion of partial and multi-segment matching, with
+ more detailed discussion of partial and multi-segment matching, with
examples, in the pcrepartial documentation.
The string to be matched by pcre_exec()
- The subject string is passed to pcre_exec() as a pointer in subject, a
- length in length, and a starting offset in startoffset. The units for
- length and startoffset are bytes for the 8-bit library, 16-bit data
- items for the 16-bit library, and 32-bit data items for the 32-bit
+ The subject string is passed to pcre_exec() as a pointer in subject, a
+ length in length, and a starting offset in startoffset. The units for
+ length and startoffset are bytes for the 8-bit library, 16-bit data
+ items for the 16-bit library, and 32-bit data items for the 32-bit
library.
- If startoffset is negative or greater than the length of the subject,
- pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is
- zero, the search for a match starts at the beginning of the subject,
- and this is by far the most common case. In UTF-8 or UTF-16 mode, the
- offset must point to the start of a character, or the end of the sub-
- ject (in UTF-32 mode, one data unit equals one character, so all off-
- sets are valid). Unlike the pattern string, the subject may contain
+ If startoffset is negative or greater than the length of the subject,
+ pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is
+ zero, the search for a match starts at the beginning of the subject,
+ and this is by far the most common case. In UTF-8 or UTF-16 mode, the
+ offset must point to the start of a character, or the end of the sub-
+ ject (in UTF-32 mode, one data unit equals one character, so all off-
+ sets are valid). Unlike the pattern string, the subject may contain
binary zeroes.
- A non-zero starting offset is useful when searching for another match
- in the same subject by calling pcre_exec() again after a previous suc-
- cess. Setting startoffset differs from just passing over a shortened
- string and setting PCRE_NOTBOL in the case of a pattern that begins
+ A non-zero starting offset is useful when searching for another match
+ in the same subject by calling pcre_exec() again after a previous suc-
+ cess. Setting startoffset differs from just passing over a shortened
+ string and setting PCRE_NOTBOL in the case of a pattern that begins
with any kind of lookbehind. For example, consider the pattern
\Biss\B
- 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()
- finds the first occurrence. If pcre_exec() is called again with just
- the remainder of the subject, namely "issipi", it does not match,
+ 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()
+ finds the first occurrence. If pcre_exec() 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 pcre_exec() is passed the entire
+ 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-
- rence of "iss" because it is able to look behind the starting point to
+ rence of "iss" because it is able to look behind the starting point to
discover that it is preceded by a letter.
- Finding all the matches in a subject is tricky when the pattern can
+ Finding all the matches in a subject is tricky when the pattern can
match an empty string. It is possible to emulate Perl's /g behaviour by
- first trying the match again at the same offset, with the
- PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that
- fails, advancing the starting offset and trying an ordinary match
+ first trying the match again at the same offset, with the
+ PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that
+ fails, advancing the starting offset and trying an ordinary match
again. There is some code that demonstrates how to do this in the pcre-
demo sample program. In the most general case, you have to check to see
- if the newline convention recognizes CRLF as a newline, and if so, and
+ if the newline convention recognizes CRLF as a newline, and if so, and
the current character is CR followed by LF, advance the starting offset
by two characters instead of one.
- If a non-zero starting offset is passed when the pattern is anchored,
+ If a non-zero starting offset is passed when the pattern is anchored,
one attempt to match at the given offset is made. This can only succeed
- if the pattern does not require the match to be at the start of the
+ if the pattern does not require the match to be at the start of the
subject.
How pcre_exec() returns captured substrings
- In general, a pattern matches a certain portion of the subject, and in
- addition, further substrings from the subject may be picked out by
- parts of the pattern. Following the usage in Jeffrey Friedl's book,
- this is called "capturing" in what follows, and the phrase "capturing
- subpattern" is used for a fragment of a pattern that picks out a sub-
- string. PCRE supports several other kinds of parenthesized subpattern
+ In general, a pattern matches a certain portion of the subject, and in
+ addition, further substrings from the subject may be picked out by
+ parts of the pattern. Following the usage in Jeffrey Friedl's book,
+ this is called "capturing" in what follows, and the phrase "capturing
+ subpattern" is used for a fragment of a pattern that picks out a sub-
+ string. PCRE supports several other kinds of parenthesized subpattern
that do not cause substrings to be captured.
Captured substrings are returned to the caller via a vector of integers
- whose address is passed in ovector. The number of elements in the vec-
- tor is passed in ovecsize, which must be a non-negative number. Note:
+ whose address is passed in ovector. The number of elements in the vec-
+ tor is passed in ovecsize, which must be a non-negative number. Note:
this argument is NOT the size of ovector in bytes.
- The first two-thirds of the vector is used to pass back captured sub-
- strings, each substring using a pair of integers. The remaining third
- of the vector is used as workspace by pcre_exec() while matching cap-
- turing subpatterns, and is not available for passing back information.
- The number passed in ovecsize should always be a multiple of three. If
+ The first two-thirds of the vector is used to pass back captured sub-
+ strings, each substring using a pair of integers. The remaining third
+ of the vector is used as workspace by pcre_exec() while matching cap-
+ turing subpatterns, and is not available for passing back information.
+ The number passed in ovecsize should always be a multiple of three. If
it is not, it is rounded down.
- When a match is successful, information about captured substrings is
- returned in pairs of integers, starting at the beginning of ovector,
- and continuing up to two-thirds of its length at the most. The first
- element of each pair is set to the offset of the first character in a
- substring, and the second is set to the offset of the first character
- after the end of a substring. These values are always data unit off-
- sets, even in UTF mode. They are byte offsets in the 8-bit library,
- 16-bit data item offsets in the 16-bit library, and 32-bit data item
+ When a match is successful, information about captured substrings is
+ returned in pairs of integers, starting at the beginning of ovector,
+ and continuing up to two-thirds of its length at the most. The first
+ element of each pair is set to the offset of the first character in a
+ substring, and the second is set to the offset of the first character
+ after the end of a substring. These values are always data unit off-
+ sets, even in UTF mode. They are byte offsets in the 8-bit library,
+ 16-bit data item offsets in the 16-bit library, and 32-bit data item
offsets in the 32-bit library. Note: they are not character counts.
- The first pair of integers, ovector[0] and ovector[1], identify the
- portion of the subject string matched by the entire pattern. The next
- pair is used for the first capturing subpattern, and so on. The value
+ The first pair of integers, ovector[0] and ovector[1], identify the
+ portion of the subject string matched by the entire pattern. The next
+ pair is used for the first capturing subpattern, and so on. The value
returned by pcre_exec() is one more than the highest numbered pair that
- has been set. For example, if two substrings have been captured, the
- returned value is 3. If there are no capturing subpatterns, the return
+ has been set. For example, if two substrings have been captured, the
+ returned value is 3. If there are no capturing subpatterns, the return
value from a successful match is 1, indicating that just the first pair
of offsets has been set.
If a capturing subpattern is matched repeatedly, it is the last portion
of the string that it matched that is returned.
- If the vector is too small to hold all the captured substring offsets,
+ If the vector is too small to hold all the captured substring offsets,
it is used as far as possible (up to two-thirds of its length), and the
- function returns a value of zero. If neither the actual string matched
- nor any captured substrings are of interest, pcre_exec() may be called
- with ovector passed as NULL and ovecsize as zero. However, if the pat-
- tern contains back references and the ovector is not big enough to
- remember the related substrings, PCRE has to get additional memory for
- use during matching. Thus it is usually advisable to supply an ovector
+ function returns a value of zero. If neither the actual string matched
+ nor any captured substrings are of interest, pcre_exec() may be called
+ with ovector passed as NULL and ovecsize as zero. However, if the pat-
+ tern contains back references and the ovector is not big enough to
+ remember the related substrings, PCRE has to get additional memory for
+ use during matching. Thus it is usually advisable to supply an ovector
of reasonable size.
- There are some cases where zero is returned (indicating vector over-
- flow) when in fact the vector is exactly the right size for the final
+ There are some cases where zero is returned (indicating vector over-
+ flow) when in fact the vector is exactly the right size for the final
match. For example, consider the pattern
(a)(?:(b)c|bd)
- If a vector of 6 elements (allowing for only 1 captured substring) is
+ If a vector of 6 elements (allowing for only 1 captured substring) is
given with subject string "abd", pcre_exec() will try to set the second
captured string, thereby recording a vector overflow, before failing to
- match "c" and backing up to try the second alternative. The zero
- return, however, does correctly indicate that the maximum number of
+ match "c" and backing up to try the second alternative. The zero
+ return, however, does correctly indicate that the maximum number of
slots (namely 2) have been filled. In similar cases where there is tem-
- porary overflow, but the final number of used slots is actually less
+ porary overflow, but the final number of used slots is actually less
than the maximum, a non-zero value is returned.
The pcre_fullinfo() function can be used to find out how many capturing
- subpatterns there are in a compiled pattern. The smallest size for
- ovector that will allow for n captured substrings, in addition to the
+ subpatterns there are in a compiled pattern. The smallest size for
+ ovector that will allow for n captured substrings, in addition to the
offsets of the substring matched by the whole pattern, is (n+1)*3.
- It is possible for capturing subpattern number n+1 to match some part
+ It is possible for capturing subpattern number n+1 to match some part
of the subject when subpattern n has not been used at all. For example,
- if the string "abc" is matched against the pattern (a|(z))(bc) the
+ if the string "abc" is matched against the pattern (a|(z))(bc) the
return from the function is 4, and subpatterns 1 and 3 are matched, but
- 2 is not. When this happens, both values in the offset pairs corre-
+ 2 is not. When this happens, both values in the offset pairs corre-
sponding to unused subpatterns are set to -1.
- Offset values that correspond to unused subpatterns at the end of the
- expression are also set to -1. For example, if the string "abc" is
- matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not
- matched. The return from the function is 2, because the highest used
- capturing subpattern number is 1, and the offsets for for the second
- and third capturing subpatterns (assuming the vector is large enough,
+ Offset values that correspond to unused subpatterns at the end of the
+ expression are also set to -1. For example, if the string "abc" is
+ matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not
+ matched. The return from the function is 2, because the highest used
+ capturing subpattern number is 1, and the offsets for for the second
+ and third capturing subpatterns (assuming the vector is large enough,
of course) are set to -1.
- Note: Elements in the first two-thirds of ovector that do not corre-
- spond to capturing parentheses in the pattern are never changed. That
- is, if a pattern contains n capturing parentheses, no more than ovec-
- tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in
+ Note: Elements in the first two-thirds of ovector that do not corre-
+ spond to capturing parentheses in the pattern are never changed. That
+ is, if a pattern contains n capturing parentheses, no more than ovec-
+ tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in
the first two-thirds) retain whatever values they previously had.
- Some convenience functions are provided for extracting the captured
+ Some convenience functions are provided for extracting the captured
substrings as separate strings. These are described below.
Error return values from pcre_exec()
- If pcre_exec() fails, it returns a negative number. The following are
+ If pcre_exec() fails, it returns a negative number. The following are
defined in the header file:
PCRE_ERROR_NOMATCH (-1)
@@ -3585,7 +3602,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_ERROR_NULL (-2)
- Either code or subject was passed as NULL, or ovector was NULL and
+ Either code or subject was passed as NULL, or ovector was NULL and
ovecsize was not zero.
PCRE_ERROR_BADOPTION (-3)
@@ -3594,82 +3611,82 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_ERROR_BADMAGIC (-4)
- PCRE stores a 4-byte "magic number" at the start of the compiled code,
+ PCRE stores a 4-byte "magic number" at the start of the compiled code,
to catch the case when it is passed a junk pointer and to detect when a
pattern that was compiled in an environment of one endianness is run in
- an environment with the other endianness. This is the error that PCRE
+ an environment with the other endianness. This is the error that PCRE
gives when the magic number is not present.
PCRE_ERROR_UNKNOWN_OPCODE (-5)
While running the pattern match, an unknown item was encountered in the
- compiled pattern. This error could be caused by a bug in PCRE or by
+ compiled pattern. This error could be caused by a bug in PCRE or by
overwriting of the compiled pattern.
PCRE_ERROR_NOMEMORY (-6)
- If a pattern contains back references, but the ovector that is passed
+ If a pattern contains back references, but the ovector that is passed
to pcre_exec() is not big enough to remember the referenced substrings,
- PCRE gets a block of memory at the start of matching to use for this
- purpose. If the call via pcre_malloc() fails, this error is given. The
+ PCRE gets a block of memory at the start of matching to use for this
+ purpose. If the call via pcre_malloc() fails, this error is given. The
memory is automatically freed at the end of matching.
- This error is also given if pcre_stack_malloc() fails in pcre_exec().
- This can happen only when PCRE has been compiled with --disable-stack-
+ This error is also given if pcre_stack_malloc() fails in pcre_exec().
+ This can happen only when PCRE has been compiled with --disable-stack-
for-recursion.
PCRE_ERROR_NOSUBSTRING (-7)
- This error is used by the pcre_copy_substring(), pcre_get_substring(),
+ This error is used by the pcre_copy_substring(), pcre_get_substring(),
and pcre_get_substring_list() functions (see below). It is never
returned by pcre_exec().
PCRE_ERROR_MATCHLIMIT (-8)
- The backtracking limit, as specified by the match_limit field in a
- pcre_extra structure (or defaulted) was reached. See the description
+ The backtracking limit, as specified by the match_limit field in a
+ pcre_extra structure (or defaulted) was reached. See the description
above.
PCRE_ERROR_CALLOUT (-9)
This error is never generated by pcre_exec() itself. It is provided for
- use by callout functions that want to yield a distinctive error code.
+ use by callout functions that want to yield a distinctive error code.
See the pcrecallout documentation for details.
PCRE_ERROR_BADUTF8 (-10)
- A string that contains an invalid UTF-8 byte sequence was passed as a
- subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of
- the output vector (ovecsize) is at least 2, the byte offset to the
- start of the the invalid UTF-8 character is placed in the first ele-
- ment, and a reason code is placed in the second element. The reason
+ A string that contains an invalid UTF-8 byte sequence was passed as a
+ subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of
+ the output vector (ovecsize) is at least 2, the byte offset to the
+ start of the the invalid UTF-8 character is placed in the first ele-
+ ment, and a reason code is placed in the second element. The reason
codes are listed in the following section. For backward compatibility,
- if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char-
- acter at the end of the subject (reason codes 1 to 5),
+ if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char-
+ acter at the end of the subject (reason codes 1 to 5),
PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
PCRE_ERROR_BADUTF8_OFFSET (-11)
- The UTF-8 byte sequence that was passed as a subject was checked and
- found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the
- value of startoffset did not point to the beginning of a UTF-8 charac-
+ The UTF-8 byte sequence that was passed as a subject was checked and
+ found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the
+ value of startoffset did not point to the beginning of a UTF-8 charac-
ter or the end of the subject.
PCRE_ERROR_PARTIAL (-12)
- The subject string did not match, but it did match partially. See the
+ The subject string did not match, but it did match partially. See the
pcrepartial documentation for details of partial matching.
PCRE_ERROR_BADPARTIAL (-13)
- This code is no longer in use. It was formerly returned when the
- PCRE_PARTIAL option was used with a compiled pattern containing items
- that were not supported for partial matching. From release 8.00
+ This code is no longer in use. It was formerly returned when the
+ PCRE_PARTIAL option was used with a compiled pattern containing items
+ that were not supported for partial matching. From release 8.00
onwards, there are no restrictions on partial matching.
PCRE_ERROR_INTERNAL (-14)
- An unexpected internal error has occurred. This error could be caused
+ An unexpected internal error has occurred. This error could be caused
by a bug in PCRE or by overwriting of the compiled pattern.
PCRE_ERROR_BADCOUNT (-15)
@@ -3679,7 +3696,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_ERROR_RECURSIONLIMIT (-21)
The internal recursion limit, as specified by the match_limit_recursion
- field in a pcre_extra structure (or defaulted) was reached. See the
+ field in a pcre_extra structure (or defaulted) was reached. See the
description above.
PCRE_ERROR_BADNEWLINE (-23)
@@ -3693,29 +3710,29 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_ERROR_SHORTUTF8 (-25)
- This error is returned instead of PCRE_ERROR_BADUTF8 when the subject
- string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD
- option is set. Information about the failure is returned as for
- PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but
- this special error code for PCRE_PARTIAL_HARD precedes the implementa-
- tion of returned information; it is retained for backwards compatibil-
+ This error is returned instead of PCRE_ERROR_BADUTF8 when the subject
+ string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD
+ option is set. Information about the failure is returned as for
+ PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but
+ this special error code for PCRE_PARTIAL_HARD precedes the implementa-
+ tion of returned information; it is retained for backwards compatibil-
ity.
PCRE_ERROR_RECURSELOOP (-26)
This error is returned when pcre_exec() detects a recursion loop within
- the pattern. Specifically, it means that either the whole pattern or a
- subpattern has been called recursively for the second time at the same
+ the pattern. Specifically, it means that either the whole pattern or a
+ subpattern has been called recursively for the second time at the same
position in the subject string. Some simple patterns that might do this
- are detected and faulted at compile time, but more complicated cases,
+ are detected and faulted at compile time, but more complicated cases,
in particular mutual recursions between two different subpatterns, can-
not be detected until run time.
PCRE_ERROR_JIT_STACKLIMIT (-27)
- This error is returned when a pattern that was successfully studied
- using a JIT compile option is being matched, but the memory available
- for the just-in-time processing stack is not large enough. See the
+ This error is returned when a pattern that was successfully studied
+ using a JIT compile option is being matched, but the memory available
+ for the just-in-time processing stack is not large enough. See the
pcrejit documentation for more details.
PCRE_ERROR_BADMODE (-28)
@@ -3725,38 +3742,38 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_ERROR_BADENDIANNESS (-29)
- This error is given if a pattern that was compiled and saved is
- reloaded on a host with different endianness. The utility function
+ This error is given if a pattern that was compiled and saved is
+ reloaded on a host with different endianness. The utility function
pcre_pattern_to_host_byte_order() can be used to convert such a pattern
so that it runs on the new host.
PCRE_ERROR_JIT_BADOPTION
- This error is returned when a pattern that was successfully studied
- using a JIT compile option is being matched, but the matching mode
- (partial or complete match) does not correspond to any JIT compilation
- mode. When the JIT fast path function is used, this error may be also
- given for invalid options. See the pcrejit documentation for more
+ This error is returned when a pattern that was successfully studied
+ using a JIT compile option is being matched, but the matching mode
+ (partial or complete match) does not correspond to any JIT compilation
+ mode. When the JIT fast path function is used, this error may be also
+ given for invalid options. See the pcrejit documentation for more
details.
PCRE_ERROR_BADLENGTH (-32)
- This error is given if pcre_exec() is called with a negative value for
+ This error is given if pcre_exec() is called with a negative value for
the length argument.
Error numbers -16 to -20, -22, and 30 are not used by pcre_exec().
Reason codes for invalid UTF-8 strings
- This section applies only to the 8-bit library. The corresponding
- information for the 16-bit and 32-bit libraries is given in the pcre16
+ This section applies only to the 8-bit library. The corresponding
+ information for the 16-bit and 32-bit libraries is given in the pcre16
and pcre32 pages.
When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT-
- UTF8, and the size of the output vector (ovecsize) is at least 2, the
- offset of the start of the invalid UTF-8 character is placed in the
+ UTF8, and the size of the output vector (ovecsize) is at least 2, the
+ offset of the start of the invalid UTF-8 character is placed in the
first output vector element (ovector[0]) and a reason code is placed in
- the second element (ovector[1]). The reason codes are given names in
+ the second element (ovector[1]). The reason codes are given names in
the pcre.h header file:
PCRE_UTF8_ERR1
@@ -3765,10 +3782,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_UTF8_ERR4
PCRE_UTF8_ERR5
- The string ends with a truncated UTF-8 character; the code specifies
- how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8
- characters to be no longer than 4 bytes, the encoding scheme (origi-
- nally defined by RFC 2279) allows for up to 6 bytes, and this is
+ The string ends with a truncated UTF-8 character; the code specifies
+ how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8
+ characters to be no longer than 4 bytes, the encoding scheme (origi-
+ nally defined by RFC 2279) allows for up to 6 bytes, and this is
checked first; hence the possibility of 4 or 5 missing bytes.
PCRE_UTF8_ERR6
@@ -3778,24 +3795,24 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_UTF8_ERR10
The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of
- the character do not have the binary value 0b10 (that is, either the
+ the character do not have the binary value 0b10 (that is, either the
most significant bit is 0, or the next bit is 1).
PCRE_UTF8_ERR11
PCRE_UTF8_ERR12
- A character that is valid by the RFC 2279 rules is either 5 or 6 bytes
+ A character that is valid by the RFC 2279 rules is either 5 or 6 bytes
long; these code points are excluded by RFC 3629.
PCRE_UTF8_ERR13
- A 4-byte character has a value greater than 0x10fff; these code points
+ A 4-byte character has a value greater than 0x10fff; these code points
are excluded by RFC 3629.
PCRE_UTF8_ERR14
- A 3-byte character has a value in the range 0xd800 to 0xdfff; this
- range of code points are reserved by RFC 3629 for use with UTF-16, and
+ A 3-byte character has a value in the range 0xd800 to 0xdfff; this
+ range of code points are reserved by RFC 3629 for use with UTF-16, and
so are excluded from UTF-8.
PCRE_UTF8_ERR15
@@ -3804,28 +3821,28 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_UTF8_ERR18
PCRE_UTF8_ERR19
- A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes
- for a value that can be represented by fewer bytes, which is invalid.
- For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor-
+ A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes
+ for a value that can be represented by fewer bytes, which is invalid.
+ For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor-
rect coding uses just one byte.
PCRE_UTF8_ERR20
The two most significant bits of the first byte of a character have the
- binary value 0b10 (that is, the most significant bit is 1 and the sec-
- ond is 0). Such a byte can only validly occur as the second or subse-
+ binary value 0b10 (that is, the most significant bit is 1 and the sec-
+ ond is 0). Such a byte can only validly occur as the second or subse-
quent byte of a multi-byte character.
PCRE_UTF8_ERR21
- The first byte of a character has the value 0xfe or 0xff. These values
+ The first byte of a character has the value 0xfe or 0xff. These values
can never occur in a valid UTF-8 string.
PCRE_UTF8_ERR22
- This error code was formerly used when the presence of a so-called
- "non-character" caused an error. Unicode corrigendum #9 makes it clear
- that such characters should not cause a string to be rejected, and so
+ This error code was formerly used when the presence of a so-called
+ "non-character" caused an error. Unicode corrigendum #9 makes it clear
+ that such characters should not cause a string to be rejected, and so
this code is no longer in use and is never returned.
@@ -3842,78 +3859,78 @@ EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
int pcre_get_substring_list(const char *subject,
int *ovector, int stringcount, const char ***listptr);
- Captured substrings can be accessed directly by using the offsets
- returned by pcre_exec() in ovector. For convenience, the functions
+ Captured substrings can be accessed directly by using the offsets
+ returned by pcre_exec() in ovector. For convenience, the functions
pcre_copy_substring(), pcre_get_substring(), and pcre_get_sub-
- string_list() are provided for extracting captured substrings as new,
- separate, zero-terminated strings. These functions identify substrings
- by number. The next section describes functions for extracting named
+ string_list() are provided for extracting captured substrings as new,
+ separate, zero-terminated strings. These functions identify substrings
+ by number. The next section describes functions for extracting named
substrings.
- A substring that contains a binary zero is correctly extracted and has
- a further zero added on the end, but the result is not, of course, a C
- string. However, you can process such a string by referring to the
- length that is returned by pcre_copy_substring() and pcre_get_sub-
+ A substring that contains a binary zero is correctly extracted and has
+ a further zero added on the end, but the result is not, of course, a C
+ string. However, you can process such a string by referring to the
+ length that is returned by pcre_copy_substring() and pcre_get_sub-
string(). Unfortunately, the interface to pcre_get_substring_list() is
- not adequate for handling strings containing binary zeros, because the
+ not adequate for handling strings containing binary zeros, because the
end of the final string is not independently indicated.
- The first three arguments are the same for all three of these func-
- tions: subject is the subject string that has just been successfully
+ The first three arguments are the same for all three of these func-
+ tions: subject is the subject string that has just been successfully
matched, ovector is a pointer to the vector of integer offsets that was
passed to pcre_exec(), and stringcount is the number of substrings that
- were captured by the match, including the substring that matched the
+ were captured by the match, including the substring that matched the
entire regular expression. This is the value returned by pcre_exec() if
- it is greater than zero. If pcre_exec() returned zero, indicating that
- it ran out of space in ovector, the value passed as stringcount should
+ it is greater than zero. If pcre_exec() returned zero, indicating that
+ it ran out of space in ovector, the value passed as stringcount should
be the number of elements in the vector divided by three.
- The functions pcre_copy_substring() and pcre_get_substring() extract a
- single substring, whose number is given as stringnumber. A value of
- zero extracts the substring that matched the entire pattern, whereas
- higher values extract the captured substrings. For pcre_copy_sub-
- string(), the string is placed in buffer, whose length is given by
- buffersize, while for pcre_get_substring() a new block of memory is
- obtained via pcre_malloc, and its address is returned via stringptr.
- The yield of the function is the length of the string, not including
+ The functions pcre_copy_substring() and pcre_get_substring() extract a
+ single substring, whose number is given as stringnumber. A value of
+ zero extracts the substring that matched the entire pattern, whereas
+ higher values extract the captured substrings. For pcre_copy_sub-
+ string(), the string is placed in buffer, whose length is given by
+ buffersize, while for pcre_get_substring() a new block of memory is
+ obtained via pcre_malloc, and its address is returned via stringptr.
+ The yield of the function is the length of the string, not including
the terminating zero, or one of these error codes:
PCRE_ERROR_NOMEMORY (-6)
- The buffer was too small for pcre_copy_substring(), or the attempt to
+ The buffer was too small for pcre_copy_substring(), or the attempt to
get memory failed for pcre_get_substring().
PCRE_ERROR_NOSUBSTRING (-7)
There is no substring whose number is stringnumber.
- The pcre_get_substring_list() function extracts all available sub-
- strings and builds a list of pointers to them. All this is done in a
+ The pcre_get_substring_list() function extracts all available sub-
+ strings and builds a list of pointers to them. All this is done in a
single block of memory that is obtained via pcre_malloc. The address of
- the memory block is returned via listptr, which is also the start of
- the list of string pointers. The end of the list is marked by a NULL
- pointer. The yield of the function is zero if all went well, or the
+ the memory block is returned via listptr, which is also the start of
+ the list of string pointers. The end of the list is marked by a NULL
+ pointer. The yield of the function is zero if all went well, or the
error code
PCRE_ERROR_NOMEMORY (-6)
if the attempt to get the memory block failed.
- When any of these functions encounter a substring that is unset, which
- can happen when capturing subpattern number n+1 matches some part of
- the subject, but subpattern n has not been used at all, they return an
+ When any of these functions encounter a substring that is unset, which
+ can happen when capturing subpattern number n+1 matches some part of
+ the subject, but subpattern n has not been used at all, they return an
empty string. This can be distinguished from a genuine zero-length sub-
- string by inspecting the appropriate offset in ovector, which is nega-
+ string by inspecting the appropriate offset in ovector, which is nega-
tive for unset substrings.
- The two convenience functions pcre_free_substring() and pcre_free_sub-
- string_list() can be used to free the memory returned by a previous
+ The two convenience functions pcre_free_substring() and pcre_free_sub-
+ string_list() can be used to free the memory returned by a previous
call of pcre_get_substring() or pcre_get_substring_list(), respec-
- tively. They do nothing more than call the function pointed to by
- pcre_free, which of course could be called directly from a C program.
- However, PCRE is used in some situations where it is linked via a spe-
- cial interface to another programming language that cannot use
- pcre_free directly; it is for these cases that the functions are pro-
+ tively. They do nothing more than call the function pointed to by
+ pcre_free, which of course could be called directly from a C program.
+ However, PCRE is used in some situations where it is linked via a spe-
+ cial interface to another programming language that cannot use
+ pcre_free directly; it is for these cases that the functions are pro-
vided.
@@ -3932,7 +3949,7 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME
int stringcount, const char *stringname,
const char **stringptr);
- To extract a substring by name, you first have to find associated num-
+ To extract a substring by name, you first have to find associated num-
ber. For example, for this pattern
(a+)b(?<xxx>\d+)...
@@ -3941,35 +3958,35 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME
be unique (PCRE_DUPNAMES was not set), you can find the number from the
name by calling pcre_get_stringnumber(). The first argument is the com-
piled pattern, and the second is the name. The yield of the function is
- the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no
+ the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no
subpattern of that name.
Given the number, you can extract the substring directly, or use one of
the functions described in the previous section. For convenience, there
are also two functions that do the whole job.
- Most of the arguments of pcre_copy_named_substring() and
- pcre_get_named_substring() are the same as those for the similarly
- named functions that extract by number. As these are described in the
- previous section, they are not re-described here. There are just two
+ Most of the arguments of pcre_copy_named_substring() and
+ pcre_get_named_substring() are the same as those for the similarly
+ named functions that extract by number. As these are described in the
+ previous section, they are not re-described here. There are just two
differences:
- First, instead of a substring number, a substring name is given. Sec-
+ First, instead of a substring number, a substring name is given. Sec-
ond, there is an extra argument, given at the start, which is a pointer
- to the compiled pattern. This is needed in order to gain access to the
+ to the compiled pattern. This is needed in order to gain access to the
name-to-number translation table.
- These functions call pcre_get_stringnumber(), and if it succeeds, they
- then call pcre_copy_substring() or pcre_get_substring(), as appropri-
- ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the
+ These functions call pcre_get_stringnumber(), and if it succeeds, they
+ then call pcre_copy_substring() or pcre_get_substring(), as appropri-
+ ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the
behaviour may not be what you want (see the next section).
Warning: If the pattern uses the (?| feature to set up multiple subpat-
- terns with the same number, as described in the section on duplicate
- subpattern numbers in the pcrepattern page, you cannot use names to
- distinguish the different subpatterns, because names are not included
- in the compiled code. The matching process uses only numbers. For this
- reason, the use of different names for subpatterns of the same number
+ terns with the same number, as described in the section on duplicate
+ subpattern numbers in the pcrepattern page, you cannot use names to
+ distinguish the different subpatterns, because names are not included
+ in the compiled code. The matching process uses only numbers. For this
+ reason, the use of different names for subpatterns of the same number
causes an error at compile time.
@@ -3978,76 +3995,76 @@ DUPLICATE SUBPATTERN NAMES
int pcre_get_stringtable_entries(const pcre *code,
const char *name, char **first, char **last);
- When a pattern is compiled with the PCRE_DUPNAMES option, names for
- subpatterns are not required to be unique. (Duplicate names are always
- allowed for subpatterns with the same number, created by using the (?|
- feature. Indeed, if such subpatterns are named, they are required to
+ When a pattern is compiled with the PCRE_DUPNAMES option, names for
+ subpatterns are not required to be unique. (Duplicate names are always
+ allowed for subpatterns with the same number, created by using the (?|
+ feature. Indeed, if such subpatterns are named, they are required to
use the same names.)
Normally, patterns with duplicate names are such that in any one match,
- only one of the named subpatterns participates. An example is shown in
+ only one of the named subpatterns participates. An example is shown in
the pcrepattern documentation.
- When duplicates are present, pcre_copy_named_substring() and
- pcre_get_named_substring() return the first substring corresponding to
- the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING
- (-7) is returned; no data is returned. The pcre_get_stringnumber()
- function returns one of the numbers that are associated with the name,
+ When duplicates are present, pcre_copy_named_substring() and
+ pcre_get_named_substring() return the first substring corresponding to
+ the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING
+ (-7) is returned; no data is returned. The pcre_get_stringnumber()
+ function returns one of the numbers that are associated with the name,
but it is not defined which it is.
- If you want to get full details of all captured substrings for a given
- name, you must use the pcre_get_stringtable_entries() function. The
+ If you want to get full details of all captured substrings for a given
+ name, you must use the pcre_get_stringtable_entries() function. The
first argument is the compiled pattern, and the second is the name. The
- third and fourth are pointers to variables which are updated by the
+ third and fourth are pointers to variables which are updated by the
function. After it has run, they point to the first and last entries in
- the name-to-number table for the given name. The function itself
- returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if
- there are none. The format of the table is described above in the sec-
- tion entitled Information about a pattern above. Given all the rele-
- vant entries for the name, you can extract each of their numbers, and
+ the name-to-number table for the given name. The function itself
+ returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if
+ there are none. The format of the table is described above in the sec-
+ tion entitled Information about a pattern above. Given all the rele-
+ vant entries for the name, you can extract each of their numbers, and
hence the captured data, if any.
FINDING ALL POSSIBLE MATCHES
- The traditional matching function uses a similar algorithm to Perl,
+ The traditional matching function uses a similar algorithm to Perl,
which stops when it finds the first match, starting at a given point in
- the subject. If you want to find all possible matches, or the longest
- possible match, consider using the alternative matching function (see
- below) instead. If you cannot use the alternative function, but still
- need to find all possible matches, you can kludge it up by making use
+ the subject. If you want to find all possible matches, or the longest
+ possible match, consider using the alternative matching function (see
+ below) instead. If you cannot use the alternative function, but still
+ need to find all possible matches, you can kludge it up by making use
of the callout facility, which is described in the pcrecallout documen-
tation.
What you have to do is to insert a callout right at the end of the pat-
- tern. When your callout function is called, extract and save the cur-
- rent matched substring. Then return 1, which forces pcre_exec() to
- backtrack and try other alternatives. Ultimately, when it runs out of
+ tern. When your callout function is called, extract and save the cur-
+ rent matched substring. Then return 1, which forces pcre_exec() to
+ backtrack and try other alternatives. Ultimately, when it runs out of
matches, pcre_exec() will yield PCRE_ERROR_NOMATCH.
OBTAINING AN ESTIMATE OF STACK USAGE
- Matching certain patterns using pcre_exec() can use a lot of process
- stack, which in certain environments can be rather limited in size.
- Some users find it helpful to have an estimate of the amount of stack
- that is used by pcre_exec(), to help them set recursion limits, as
- described in the pcrestack documentation. The estimate that is output
+ Matching certain patterns using pcre_exec() can use a lot of process
+ stack, which in certain environments can be rather limited in size.
+ Some users find it helpful to have an estimate of the amount of stack
+ that is used by pcre_exec(), to help them set recursion limits, as
+ described in the pcrestack documentation. The estimate that is output
by pcretest when called with the -m and -C options is obtained by call-
- ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its
+ ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its
first five arguments.
- Normally, if its first argument is NULL, pcre_exec() immediately
- returns the negative error code PCRE_ERROR_NULL, but with this special
- combination of arguments, it returns instead a negative number whose
- absolute value is the approximate stack frame size in bytes. (A nega-
- tive number is used so that it is clear that no match has happened.)
- The value is approximate because in some cases, recursive calls to
+ Normally, if its first argument is NULL, pcre_exec() immediately
+ returns the negative error code PCRE_ERROR_NULL, but with this special
+ combination of arguments, it returns instead a negative number whose
+ absolute value is the approximate stack frame size in bytes. (A nega-
+ tive number is used so that it is clear that no match has happened.)
+ The value is approximate because in some cases, recursive calls to
pcre_exec() occur when there are one or two additional variables on the
stack.
- If PCRE has been compiled to use the heap instead of the stack for
- recursion, the value returned is the size of each block that is
+ If PCRE has been compiled to use the heap instead of the stack for
+ recursion, the value returned is the size of each block that is
obtained from the heap.
@@ -4058,26 +4075,26 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
int options, int *ovector, int ovecsize,
int *workspace, int wscount);
- The function pcre_dfa_exec() is called to match a subject string
- against a compiled pattern, using a matching algorithm that scans the
- subject string just once, and does not backtrack. This has different
- characteristics to the normal algorithm, and is not compatible with
- Perl. Some of the features of PCRE patterns are not supported. Never-
- theless, there are times when this kind of matching can be useful. For
- a discussion of the two matching algorithms, and a list of features
- that pcre_dfa_exec() does not support, see the pcrematching documenta-
+ The function pcre_dfa_exec() is called to match a subject string
+ against a compiled pattern, using a matching algorithm that scans the
+ subject string just once, and does not backtrack. This has different
+ characteristics to the normal algorithm, and is not compatible with
+ Perl. Some of the features of PCRE patterns are not supported. Never-
+ theless, there are times when this kind of matching can be useful. For
+ a discussion of the two matching algorithms, and a list of features
+ that pcre_dfa_exec() does not support, see the pcrematching documenta-
tion.
- The arguments for the pcre_dfa_exec() function are the same as for
+ The arguments for the pcre_dfa_exec() function are the same as for
pcre_exec(), plus two extras. The ovector argument is used in a differ-
- ent way, and this is described below. The other common arguments are
- used in the same way as for pcre_exec(), so their description is not
+ ent way, and this is described below. The other common arguments are
+ used in the same way as for pcre_exec(), so their description is not
repeated here.
- The two additional arguments provide workspace for the function. The
- workspace vector should contain at least 20 elements. It is used for
+ The two additional arguments provide workspace for the function. The
+ workspace vector should contain at least 20 elements. It is used for
keeping track of multiple paths through the pattern tree. More
- workspace will be needed for patterns and subjects where there are a
+ workspace will be needed for patterns and subjects where there are a
lot of potential matches.
Here is an example of a simple call to pcre_dfa_exec():
@@ -4099,55 +4116,55 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
Option bits for pcre_dfa_exec()
- The unused bits of the options argument for pcre_dfa_exec() must be
- zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW-
+ The unused bits of the options argument for pcre_dfa_exec() must be
+ zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW-
LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
- PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF,
- PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR-
- TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last
- four of these are exactly the same as for pcre_exec(), so their
+ PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF,
+ PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR-
+ TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last
+ four of these are exactly the same as for pcre_exec(), so their
description is not repeated here.
PCRE_PARTIAL_HARD
PCRE_PARTIAL_SOFT
- These have the same general effect as they do for pcre_exec(), but the
- details are slightly different. When PCRE_PARTIAL_HARD is set for
- pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub-
- ject is reached and there is still at least one matching possibility
+ These have the same general effect as they do for pcre_exec(), but the
+ details are slightly different. When PCRE_PARTIAL_HARD is set for
+ pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub-
+ ject is reached and there is still at least one matching possibility
that requires additional characters. This happens even if some complete
matches have also been found. When PCRE_PARTIAL_SOFT is set, the return
code PCRE_ERROR_NOMATCH is converted into PCRE_ERROR_PARTIAL if the end
- of the subject is reached, there have been no complete matches, but
- there is still at least one matching possibility. The portion of the
- string that was inspected when the longest partial match was found is
- set as the first matching string in both cases. There is a more
- detailed discussion of partial and multi-segment matching, with exam-
+ of the subject is reached, there have been no complete matches, but
+ there is still at least one matching possibility. The portion of the
+ string that was inspected when the longest partial match was found is
+ set as the first matching string in both cases. There is a more
+ detailed discussion of partial and multi-segment matching, with exam-
ples, in the pcrepartial documentation.
PCRE_DFA_SHORTEST
- Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to
+ Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to
stop as soon as it has found one match. Because of the way the alterna-
- tive algorithm works, this is necessarily the shortest possible match
+ tive algorithm works, this is necessarily the shortest possible match
at the first possible matching point in the subject string.
PCRE_DFA_RESTART
When pcre_dfa_exec() returns a partial match, it is possible to call it
- again, with additional subject characters, and have it continue with
- the same match. The PCRE_DFA_RESTART option requests this action; when
- it is set, the workspace and wscount options must reference the same
- vector as before because data about the match so far is left in them
+ again, with additional subject characters, and have it continue with
+ the same match. The PCRE_DFA_RESTART option requests this action; when
+ it is set, the workspace and wscount options must reference the same
+ vector as before because data about the match so far is left in them
after a partial match. There is more discussion of this facility in the
pcrepartial documentation.
Successful returns from pcre_dfa_exec()
- When pcre_dfa_exec() succeeds, it may have matched more than one sub-
+ When pcre_dfa_exec() succeeds, it may have matched more than one sub-
string in the subject. Note, however, that all the matches from one run
- of the function start at the same point in the subject. The shorter
- matches are all initial substrings of the longer matches. For example,
+ of the function start at the same point in the subject. The shorter
+ matches are all initial substrings of the longer matches. For example,
if the pattern
<.*>
@@ -4162,79 +4179,79 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
<something> <something else>
<something> <something else> <something further>
- On success, the yield of the function is a number greater than zero,
- which is the number of matched substrings. The substrings themselves
- are returned in ovector. Each string uses two elements; the first is
- the offset to the start, and the second is the offset to the end. In
- fact, all the strings have the same start offset. (Space could have
- been saved by giving this only once, but it was decided to retain some
- compatibility with the way pcre_exec() returns data, even though the
+ On success, the yield of the function is a number greater than zero,
+ which is the number of matched substrings. The substrings themselves
+ are returned in ovector. Each string uses two elements; the first is
+ the offset to the start, and the second is the offset to the end. In
+ fact, all the strings have the same start offset. (Space could have
+ been saved by giving this only once, but it was decided to retain some
+ compatibility with the way pcre_exec() returns data, even though the
meaning of the strings is different.)
The strings are returned in reverse order of length; that is, the long-
- est matching string is given first. If there were too many matches to
- fit into ovector, the yield of the function is zero, and the vector is
- filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec()
+ est matching string is given first. If there were too many matches to
+ fit into ovector, the yield of the function is zero, and the vector is
+ filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec()
can use the entire ovector for returning matched strings.
- NOTE: PCRE's "auto-possessification" optimization usually applies to
- character repeats at the end of a pattern (as well as internally). For
- example, the pattern "a\d+" is compiled as if it were "a\d++" because
+ NOTE: PCRE's "auto-possessification" optimization usually applies to
+ character repeats at the end of a pattern (as well as internally). For
+ example, the pattern "a\d+" is compiled as if it were "a\d++" because
there is no point even considering the possibility of backtracking into
- the repeated digits. For DFA matching, this means that only one possi-
- ble match is found. If you really do want multiple matches in such
- cases, either use an ungreedy repeat ("a\d+?") or set the
+ the repeated digits. For DFA matching, this means that only one possi-
+ ble match is found. If you really do want multiple matches in such
+ cases, either use an ungreedy repeat ("a\d+?") or set the
PCRE_NO_AUTO_POSSESS option when compiling.
Error returns from pcre_dfa_exec()
- The pcre_dfa_exec() function returns a negative number when it fails.
- Many of the errors are the same as for pcre_exec(), and these are
- described above. There are in addition the following errors that are
+ The pcre_dfa_exec() function returns a negative number when it fails.
+ Many of the errors are the same as for pcre_exec(), and these are
+ described above. There are in addition the following errors that are
specific to pcre_dfa_exec():
PCRE_ERROR_DFA_UITEM (-16)
- This return is given if pcre_dfa_exec() encounters an item in the pat-
- tern that it does not support, for instance, the use of \C or a back
+ This return is given if pcre_dfa_exec() encounters an item in the pat-
+ tern that it does not support, for instance, the use of \C or a back
reference.
PCRE_ERROR_DFA_UCOND (-17)
- This return is given if pcre_dfa_exec() encounters a condition item
- that uses a back reference for the condition, or a test for recursion
+ This return is given if pcre_dfa_exec() encounters a condition item
+ that uses a back reference for the condition, or a test for recursion
in a specific group. These are not supported.
PCRE_ERROR_DFA_UMLIMIT (-18)
- This return is given if pcre_dfa_exec() is called with an extra block
- that contains a setting of the match_limit or match_limit_recursion
- fields. This is not supported (these fields are meaningless for DFA
+ This return is given if pcre_dfa_exec() is called with an extra block
+ that contains a setting of the match_limit or match_limit_recursion
+ fields. This is not supported (these fields are meaningless for DFA
matching).
PCRE_ERROR_DFA_WSSIZE (-19)
- This return is given if pcre_dfa_exec() runs out of space in the
+ This return is given if pcre_dfa_exec() runs out of space in the
workspace vector.
PCRE_ERROR_DFA_RECURSE (-20)
- When a recursive subpattern is processed, the matching function calls
- itself recursively, using private vectors for ovector and workspace.
- This error is given if the output vector is not large enough. This
+ When a recursive subpattern is processed, the matching function calls
+ itself recursively, using private vectors for ovector and workspace.
+ This error is given if the output vector is not large enough. This
should be extremely rare, as a vector of size 1000 is used.
PCRE_ERROR_DFA_BADRESTART (-30)
- When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some
- plausibility checks are made on the contents of the workspace, which
- should contain data about the previous partial match. If any of these
+ When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some
+ plausibility checks are made on the contents of the workspace, which
+ should contain data about the previous partial match. If any of these
checks fail, this error is given.
SEE ALSO
- pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3),
+ pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3),
pcrematching(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcre-
sample(3), pcrestack(3).
@@ -4248,8 +4265,8 @@ AUTHOR
REVISION
- Last updated: 12 November 2013
- Copyright (c) 1997-2013 University of Cambridge.
+ Last updated: 09 February 2014
+ Copyright (c) 1997-2014 University of Cambridge.
------------------------------------------------------------------------------
@@ -5510,7 +5527,9 @@ BACKSLASH
Perl documents that the use of \K within assertions is "not well
defined". In PCRE, \K is acted upon when it occurs inside positive
- assertions, but is ignored in negative assertions.
+ assertions, but is ignored in negative assertions. Note that when a
+ pattern such as (?=ab\K) matches, the reported start of the match can
+ be greater than the end of the match.
Simple assertions
@@ -7399,19 +7418,23 @@ BACKTRACKING CONTROL
Note that (*COMMIT) at the start of a pattern is not the same as an
anchor, unless PCRE's start-of-match optimizations are turned off, as
- shown in this pcretest example:
+ shown in this output from pcretest:
re> /(*COMMIT)abc/
data> xyzabc
0: abc
- xyzabc\Y
+ data> xyzabc\Y
No match
- PCRE knows that any match must start with "a", so the optimization
- skips along the subject to "a" before running the first match attempt,
- which succeeds. When the optimization is disabled by the \Y escape in
- the second subject, the match starts at "x" and so the (*COMMIT) causes
- it to fail without trying any other starting points.
+ For this pattern, PCRE knows that any match must start with "a", so the
+ optimization skips along the subject to "a" before applying the pattern
+ to the first set of data. The match attempt then succeeds. In the sec-
+ ond set of data, the escape sequence \Y is interpreted by the pcretest
+ program. It causes the PCRE_NO_START_OPTIMIZE option to be set when
+ pcre_exec() is called. This disables the optimization that skips along
+ to the first character. The pattern is now applied starting at "x", and
+ so the (*COMMIT) causes the match to fail without trying any other
+ starting points.
(*PRUNE) or (*PRUNE:NAME)
@@ -7618,8 +7641,8 @@ AUTHOR
REVISION
- Last updated: 03 December 2013
- Copyright (c) 1997-2013 University of Cambridge.
+ Last updated: 08 January 2014
+ Copyright (c) 1997-2014 University of Cambridge.
------------------------------------------------------------------------------
@@ -7840,6 +7863,8 @@ MATCH POINT RESET
\K reset start of match
+ \K is honoured in positive assertions, but ignored in negative ones.
+
ALTERNATION
@@ -7877,11 +7902,13 @@ OPTION SETTING
(?x) extended (ignore white space)
(?-...) unset option(s)
- The following are recognized only at the start of a pattern or after
- one of the newline-setting options with similar syntax:
+ The following are recognized only at the very start of a pattern or
+ after one of the newline or \R options with similar syntax. More than
+ one of them may appear.
(*LIMIT_MATCH=d) set the match limit to d (decimal number)
(*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
+ (*NO_AUTO_POSSESS) no auto-possessification (PCRE_NO_AUTO_POSSESS)
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
(*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
(*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
@@ -7889,10 +7916,31 @@ OPTION SETTING
(*UTF) set appropriate UTF mode for the library in use
(*UCP) set PCRE_UCP (use Unicode properties for \d etc)
- Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of
+ Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of
the limits set by the caller of pcre_exec(), not increase them.
+NEWLINE CONVENTION
+
+ These are recognized only at the very start of the pattern or after
+ option settings with a similar syntax.
+
+ (*CR) carriage return only
+ (*LF) linefeed only
+ (*CRLF) carriage return followed by linefeed
+ (*ANYCRLF) all three of the above
+ (*ANY) any Unicode newline sequence
+
+
+WHAT \R MATCHES
+
+ These are recognized only at the very start of the pattern or after
+ option setting with a similar syntax.
+
+ (*BSR_ANYCRLF) CR, LF, or CRLF
+ (*BSR_UNICODE) any Unicode newline sequence
+
+
LOOKAHEAD AND LOOKBEHIND ASSERTIONS
(?=...) positive look ahead
@@ -7960,7 +8008,7 @@ BACKTRACKING CONTROL
(*FAIL) force backtrack; synonym (*F)
(*MARK:NAME) set name to be passed back; synonym (*:NAME)
- The following act only when a subsequent match failure causes a back-
+ The following act only when a subsequent match failure causes a back-
track to reach them. They all force a match failure, but they differ in
what happens afterwards. Those that advance the start-of-match point do
so only if the pattern is not anchored.
@@ -7975,27 +8023,6 @@ BACKTRACKING CONTROL
(*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
-NEWLINE CONVENTIONS
-
- These are recognized only at the very start of the pattern or after a
- (*BSR_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option.
-
- (*CR) carriage return only
- (*LF) linefeed only
- (*CRLF) carriage return followed by linefeed
- (*ANYCRLF) all three of the above
- (*ANY) any Unicode newline sequence
-
-
-WHAT \R MATCHES
-
- These are recognized only at the very start of the pattern or after a
- (*...) option that sets the newline convention or a UTF or UCP mode.
-
- (*BSR_ANYCRLF) CR, LF, or CRLF
- (*BSR_UNICODE) any Unicode newline sequence
-
-
CALLOUTS
(?C) callout
@@ -8016,8 +8043,8 @@ AUTHOR
REVISION
- Last updated: 12 November 2013
- Copyright (c) 1997-2013 University of Cambridge.
+ Last updated: 08 January 2014
+ Copyright (c) 1997-2014 University of Cambridge.
------------------------------------------------------------------------------
diff --git a/pcre/doc/pcreapi.3 b/pcre/doc/pcreapi.3
index ebbd20fc4d5..ab3eaa0b521 100644
--- a/pcre/doc/pcreapi.3
+++ b/pcre/doc/pcreapi.3
@@ -1,4 +1,4 @@
-.TH PCREAPI 3 "12 November 2013" "PCRE 8.34"
+.TH PCREAPI 3 "09 February 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.sp
@@ -116,6 +116,8 @@ PCRE - Perl-compatible regular expressions
.B void (*pcre_stack_free)(void *);
.sp
.B int (*pcre_callout)(pcre_callout_block *);
+.sp
+.B int (*pcre_stack_guard)(void);
.fi
.
.
@@ -286,6 +288,14 @@ points during a matching operation. Details are given in the
\fBpcrecallout\fP
.\"
documentation.
+.P
+The global variable \fBpcre_stack_guard\fP initially contains NULL. It can be
+set by the caller to a function that is called by PCRE whenever it starts
+to compile a parenthesized part of a pattern. When parentheses are nested, PCRE
+uses recursive function calls, which use up the system stack. This function is
+provided so that applications with restricted stacks can force a compilation
+error if the stack runs out. The function should return zero if all is well, or
+non-zero to force an error.
.
.
.\" HTML <a name="newlines"></a>
@@ -337,7 +347,8 @@ controlled in a similar way, but by separate options.
The PCRE functions can be used in multi-threading applications, with the
proviso that the memory management functions pointed to by \fBpcre_malloc\fP,
\fBpcre_free\fP, \fBpcre_stack_malloc\fP, and \fBpcre_stack_free\fP, and the
-callout function pointed to by \fBpcre_callout\fP, are shared by all threads.
+callout and stack-checking functions pointed to by \fBpcre_callout\fP and
+\fBpcre_stack_guard\fP, are shared by all threads.
.P
The compiled form of a regular expression is not altered during matching, so
the same compiled pattern can safely be used by several threads at once.
@@ -465,7 +476,10 @@ documentation.
The output is a long integer that gives the maximum depth of nesting of
parentheses (of any kind) in a pattern. This limit is imposed to cap the amount
of system stack used when a pattern is compiled. It is specified when PCRE is
-built; the default is 250.
+built; the default is 250. This limit does not take into account the stack that
+may already be used by the calling application. For finer control over
+compilation stack usage, you can set a pointer to an external checking function
+in \fBpcre_stack_guard\fP.
.sp
PCRE_CONFIG_MATCH_LIMIT
.sp
@@ -991,6 +1005,8 @@ have fallen out of use. To avoid confusion, they have not been re-used.
81 missing opening brace after \eo
82 parentheses are too deeply nested
83 invalid range in character class
+ 84 group name must start with a non-digit
+ 85 parentheses are too deeply nested (stack check)
.sp
The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may
be used if the limits were changed when PCRE was built.
@@ -1248,12 +1264,15 @@ information call is provided for internal use by the \fBpcre_study()\fP
function. External callers can cause PCRE to use its internal tables by passing
a NULL table pointer.
.sp
- PCRE_INFO_FIRSTBYTE
+ PCRE_INFO_FIRSTBYTE (deprecated)
.sp
Return information about the first data unit of any matched string, for a
-non-anchored pattern. (The name of this option refers to the 8-bit library,
-where data units are bytes.) The fourth argument should point to an \fBint\fP
-variable.
+non-anchored pattern. The name of this option refers to the 8-bit library,
+where data units are bytes. The fourth argument should point to an \fBint\fP
+variable. Negative values are used for special cases. However, this means that
+when the 32-bit library is in non-UTF-32 mode, the full 32-bit range of
+characters cannot be returned. For this reason, this value is deprecated; use
+PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER instead.
.P
If there is a fixed first value, for example, the letter "c" from a pattern
such as (cat|cow|coyote), its value is returned. In the 8-bit library, the
@@ -1271,11 +1290,38 @@ starts with "^", or
-1 is returned, indicating that the pattern matches only at the start of a
subject string or after any newline within the string. Otherwise -2 is
returned. For anchored patterns, -2 is returned.
+.sp
+ PCRE_INFO_FIRSTCHARACTER
+.sp
+Return the value of the first data unit (non-UTF character) of any matched
+string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS returns 1;
+otherwise return 0. The fourth argument should point to an \fBuint_t\fP
+variable.
.P
-Since for the 32-bit library using the non-UTF-32 mode, this function is unable
-to return the full 32-bit range of the character, this value is deprecated;
-instead the PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER values
-should be used.
+In the 8-bit library, the value is always less than 256. In the 16-bit library
+the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value
+can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode.
+.sp
+ PCRE_INFO_FIRSTCHARACTERFLAGS
+.sp
+Return information about the first data unit of any matched string, for a
+non-anchored pattern. The fourth argument should point to an \fBint\fP
+variable.
+.P
+If there is a fixed first value, for example, the letter "c" from a pattern
+such as (cat|cow|coyote), 1 is returned, and the character value can be
+retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no fixed first value, and
+if either
+.sp
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
+starts with "^", or
+.sp
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
+(if it were set, the pattern would be anchored),
+.sp
+2 is returned, indicating that the pattern matches only at the start of a
+subject string or after any newline within the string. Otherwise 0 is
+returned. For anchored patterns, 0 is returned.
.sp
PCRE_INFO_FIRSTTABLE
.sp
@@ -1499,38 +1545,6 @@ is made available via this option so that it can be saved and restored (see the
.\"
documentation for details).
.sp
- PCRE_INFO_FIRSTCHARACTERFLAGS
-.sp
-Return information about the first data unit of any matched string, for a
-non-anchored pattern. The fourth argument should point to an \fBint\fP
-variable.
-.P
-If there is a fixed first value, for example, the letter "c" from a pattern
-such as (cat|cow|coyote), 1 is returned, and the character value can be
-retrieved using PCRE_INFO_FIRSTCHARACTER.
-.P
-If there is no fixed first value, and if either
-.sp
-(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
-starts with "^", or
-.sp
-(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
-(if it were set, the pattern would be anchored),
-.sp
-2 is returned, indicating that the pattern matches only at the start of a
-subject string or after any newline within the string. Otherwise 0 is
-returned. For anchored patterns, 0 is returned.
-.sp
- PCRE_INFO_FIRSTCHARACTER
-.sp
-Return the fixed first character value in the situation where
-PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; otherwise return 0. The fourth
-argument should point to an \fBuint_t\fP variable.
-.P
-In the 8-bit library, the value is always less than 256. In the 16-bit library
-the value can be up to 0xffff. In the 32-bit library in UTF-32 mode the value
-can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode.
-.sp
PCRE_INFO_REQUIREDCHARFLAGS
.sp
Returns 1 if there is a rightmost literal data unit that must exist in any
@@ -2900,6 +2914,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
-Last updated: 12 November 2013
-Copyright (c) 1997-2013 University of Cambridge.
+Last updated: 09 February 2014
+Copyright (c) 1997-2014 University of Cambridge.
.fi
diff --git a/pcre/doc/pcregrep.1 b/pcre/doc/pcregrep.1
index 7fa5b65e030..988667542f2 100644
--- a/pcre/doc/pcregrep.1
+++ b/pcre/doc/pcregrep.1
@@ -1,4 +1,4 @@
-.TH PCREGREP 1 "13 September 2012" "PCRE 8.32"
+.TH PCREGREP 1 "03 April 2014" "PCRE 8.35"
.SH NAME
pcregrep - a grep with Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -11,9 +11,13 @@ pcregrep - a grep with Perl-compatible regular expressions.
grep commands do, but it uses the PCRE regular expression library to support
patterns that are compatible with the regular expressions of Perl 5. See
.\" HREF
+\fBpcresyntax\fP(3)
+.\"
+for a quick-reference summary of pattern syntax, or
+.\" HREF
\fBpcrepattern\fP(3)
.\"
-for a full description of syntax and semantics of the regular expressions
+for a full description of the syntax and semantics of the regular expressions
that PCRE supports.
.P
Patterns, whether supplied on the command line or in a separate file, are given
@@ -674,6 +678,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
-Last updated: 13 September 2012
-Copyright (c) 1997-2012 University of Cambridge.
+Last updated: 03 April 2014
+Copyright (c) 1997-2014 University of Cambridge.
.fi
diff --git a/pcre/doc/pcregrep.txt b/pcre/doc/pcregrep.txt
index b31eb77c304..97d9a7bd379 100644
--- a/pcre/doc/pcregrep.txt
+++ b/pcre/doc/pcregrep.txt
@@ -14,394 +14,395 @@ DESCRIPTION
pcregrep searches files for character patterns, in the same way as
other grep commands do, but it uses the PCRE regular expression library
to support patterns that are compatible with the regular expressions of
- Perl 5. See pcrepattern(3) for a full description of syntax and seman-
+ Perl 5. See pcresyntax(3) for a quick-reference summary of pattern syn-
+ tax, or pcrepattern(3) for a full description of the syntax and seman-
tics of the regular expressions that PCRE supports.
- Patterns, whether supplied on the command line or in a separate file,
+ Patterns, whether supplied on the command line or in a separate file,
are given without delimiters. For example:
pcregrep Thursday /etc/motd
If you attempt to use delimiters (for example, by surrounding a pattern
- with slashes, as is common in Perl scripts), they are interpreted as
- part of the pattern. Quotes can of course be used to delimit patterns
- on the command line because they are interpreted by the shell, and
- indeed quotes are required if a pattern contains white space or shell
+ with slashes, as is common in Perl scripts), they are interpreted as
+ part of the pattern. Quotes can of course be used to delimit patterns
+ on the command line because they are interpreted by the shell, and
+ indeed quotes are required if a pattern contains white space or shell
metacharacters.
- The first argument that follows any option settings is treated as the
- single pattern to be matched when neither -e nor -f is present. Con-
- versely, when one or both of these options are used to specify pat-
+ The first argument that follows any option settings is treated as the
+ single pattern to be matched when neither -e nor -f is present. Con-
+ versely, when one or both of these options are used to specify pat-
terns, all arguments are treated as path names. At least one of -e, -f,
or an argument pattern must be provided.
If no files are specified, pcregrep reads the standard input. The stan-
- dard input can also be referenced by a name consisting of a single
+ dard input can also be referenced by a name consisting of a single
hyphen. For example:
pcregrep some-pattern /file1 - /file3
- By default, each line that matches a pattern is copied to the standard
- output, and if there is more than one file, the file name is output at
+ By default, each line that matches a pattern is copied to the standard
+ output, and if there is more than one file, the file name is output at
the start of each line, followed by a colon. However, there are options
- that can change how pcregrep behaves. In particular, the -M option
- makes it possible to search for patterns that span line boundaries.
- What defines a line boundary is controlled by the -N (--newline)
+ that can change how pcregrep behaves. In particular, the -M option
+ makes it possible to search for patterns that span line boundaries.
+ What defines a line boundary is controlled by the -N (--newline)
option.
The amount of memory used for buffering files that are being scanned is
- controlled by a parameter that can be set by the --buffer-size option.
- The default value for this parameter is specified when pcregrep is
- built, with the default default being 20K. A block of memory three
- times this size is used (to allow for buffering "before" and "after"
+ controlled by a parameter that can be set by the --buffer-size option.
+ The default value for this parameter is specified when pcregrep is
+ built, with the default default being 20K. A block of memory three
+ times this size is used (to allow for buffering "before" and "after"
lines). An error occurs if a line overflows the buffer.
- Patterns can be no longer than 8K or BUFSIZ bytes, whichever is the
- greater. BUFSIZ is defined in <stdio.h>. When there is more than one
+ Patterns can be no longer than 8K or BUFSIZ bytes, whichever is the
+ greater. BUFSIZ is defined in <stdio.h>. When there is more than one
pattern (specified by the use of -e and/or -f), each pattern is applied
- to each line in the order in which they are defined, except that all
+ to each line in the order in which they are defined, except that all
the -e patterns are tried before the -f patterns.
- By default, as soon as one pattern matches a line, no further patterns
+ By default, as soon as one pattern matches a line, no further patterns
are considered. However, if --colour (or --color) is used to colour the
- matching substrings, or if --only-matching, --file-offsets, or --line-
- offsets is used to output only the part of the line that matched
+ matching substrings, or if --only-matching, --file-offsets, or --line-
+ offsets is used to output only the part of the line that matched
(either shown literally, or as an offset), scanning resumes immediately
- following the match, so that further matches on the same line can be
- found. If there are multiple patterns, they are all tried on the
- remainder of the line, but patterns that follow the one that matched
+ following the match, so that further matches on the same line can be
+ found. If there are multiple patterns, they are all tried on the
+ remainder of the line, but patterns that follow the one that matched
are not tried on the earlier part of the line.
- This behaviour means that the order in which multiple patterns are
- specified can affect the output when one of the above options is used.
- This is no longer the same behaviour as GNU grep, which now manages to
- display earlier matches for later patterns (as long as there is no
+ This behaviour means that the order in which multiple patterns are
+ specified can affect the output when one of the above options is used.
+ This is no longer the same behaviour as GNU grep, which now manages to
+ display earlier matches for later patterns (as long as there is no
overlap).
- Patterns that can match an empty string are accepted, but empty string
+ Patterns that can match an empty string are accepted, but empty string
matches are never recognized. An example is the pattern
- "(super)?(man)?", in which all components are optional. This pattern
- finds all occurrences of both "super" and "man"; the output differs
- from matching with "super|man" when only the matching substrings are
+ "(super)?(man)?", in which all components are optional. This pattern
+ finds all occurrences of both "super" and "man"; the output differs
+ from matching with "super|man" when only the matching substrings are
being shown.
- If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses
- the value to set a locale when calling the PCRE library. The --locale
+ If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses
+ the value to set a locale when calling the PCRE library. The --locale
option can be used to override this.
SUPPORT FOR COMPRESSED FILES
- It is possible to compile pcregrep so that it uses libz or libbz2 to
- read files whose names end in .gz or .bz2, respectively. You can find
+ It is possible to compile pcregrep so that it uses libz or libbz2 to
+ read files whose names end in .gz or .bz2, respectively. You can find
out whether your binary has support for one or both of these file types
by running it with the --help option. If the appropriate support is not
- present, files are treated as plain text. The standard input is always
+ present, files are treated as plain text. The standard input is always
so treated.
BINARY FILES
- By default, a file that contains a binary zero byte within the first
- 1024 bytes is identified as a binary file, and is processed specially.
- (GNU grep also identifies binary files in this manner.) See the
- --binary-files option for a means of changing the way binary files are
+ By default, a file that contains a binary zero byte within the first
+ 1024 bytes is identified as a binary file, and is processed specially.
+ (GNU grep also identifies binary files in this manner.) See the
+ --binary-files option for a means of changing the way binary files are
handled.
OPTIONS
- The order in which some of the options appear can affect the output.
- For example, both the -h and -l options affect the printing of file
- names. Whichever comes later in the command line will be the one that
- takes effect. Similarly, except where noted below, if an option is
- given twice, the later setting is used. Numerical values for options
- may be followed by K or M, to signify multiplication by 1024 or
+ The order in which some of the options appear can affect the output.
+ For example, both the -h and -l options affect the printing of file
+ names. Whichever comes later in the command line will be the one that
+ takes effect. Similarly, except where noted below, if an option is
+ given twice, the later setting is used. Numerical values for options
+ may be followed by K or M, to signify multiplication by 1024 or
1024*1024 respectively.
-- This terminates the list of options. It is useful if the next
- item on the command line starts with a hyphen but is not an
- option. This allows for the processing of patterns and file-
+ item on the command line starts with a hyphen but is not an
+ option. This allows for the processing of patterns and file-
names that start with hyphens.
-A number, --after-context=number
- Output number lines of context after each matching line. If
+ Output number lines of context after each matching line. If
filenames and/or line numbers are being output, a hyphen sep-
- arator is used instead of a colon for the context lines. A
- line containing "--" is output between each group of lines,
- unless they are in fact contiguous in the input file. The
- value of number is expected to be relatively small. However,
+ arator is used instead of a colon for the context lines. A
+ line containing "--" is output between each group of lines,
+ unless they are in fact contiguous in the input file. The
+ value of number is expected to be relatively small. However,
pcregrep guarantees to have up to 8K of following text avail-
able for context output.
-a, --text
- Treat binary files as text. This is equivalent to --binary-
+ Treat binary files as text. This is equivalent to --binary-
files=text.
-B number, --before-context=number
- Output number lines of context before each matching line. If
+ Output number lines of context before each matching line. If
filenames and/or line numbers are being output, a hyphen sep-
- arator is used instead of a colon for the context lines. A
- line containing "--" is output between each group of lines,
- unless they are in fact contiguous in the input file. The
- value of number is expected to be relatively small. However,
+ arator is used instead of a colon for the context lines. A
+ line containing "--" is output between each group of lines,
+ unless they are in fact contiguous in the input file. The
+ value of number is expected to be relatively small. However,
pcregrep guarantees to have up to 8K of preceding text avail-
able for context output.
--binary-files=word
- Specify how binary files are to be processed. If the word is
- "binary" (the default), pattern matching is performed on
- binary files, but the only output is "Binary file <name>
- matches" when a match succeeds. If the word is "text", which
- is equivalent to the -a or --text option, binary files are
- processed in the same way as any other file. In this case,
- when a match succeeds, the output may be binary garbage,
- which can have nasty effects if sent to a terminal. If the
- word is "without-match", which is equivalent to the -I
- option, binary files are not processed at all; they are
+ Specify how binary files are to be processed. If the word is
+ "binary" (the default), pattern matching is performed on
+ binary files, but the only output is "Binary file <name>
+ matches" when a match succeeds. If the word is "text", which
+ is equivalent to the -a or --text option, binary files are
+ processed in the same way as any other file. In this case,
+ when a match succeeds, the output may be binary garbage,
+ which can have nasty effects if sent to a terminal. If the
+ word is "without-match", which is equivalent to the -I
+ option, binary files are not processed at all; they are
assumed not to be of interest.
--buffer-size=number
- Set the parameter that controls how much memory is used for
+ Set the parameter that controls how much memory is used for
buffering files that are being scanned.
-C number, --context=number
- Output number lines of context both before and after each
- matching line. This is equivalent to setting both -A and -B
+ Output number lines of context both before and after each
+ matching line. This is equivalent to setting both -A and -B
to the same value.
-c, --count
- Do not output individual lines from the files that are being
+ Do not output individual lines from the files that are being
scanned; instead output the number of lines that would other-
- wise have been shown. If no lines are selected, the number
- zero is output. If several files are are being scanned, a
- count is output for each of them. However, if the --files-
- with-matches option is also used, only those files whose
+ wise have been shown. If no lines are selected, the number
+ zero is output. If several files are are being scanned, a
+ count is output for each of them. However, if the --files-
+ with-matches option is also used, only those files whose
counts are greater than zero are listed. When -c is used, the
-A, -B, and -C options are ignored.
--colour, --color
If this option is given without any data, it is equivalent to
- "--colour=auto". If data is required, it must be given in
+ "--colour=auto". If data is required, it must be given in
the same shell item, separated by an equals sign.
--colour=value, --color=value
This option specifies under what circumstances the parts of a
line that matched a pattern should be coloured in the output.
- By default, the output is not coloured. The value (which is
- optional, see above) may be "never", "always", or "auto". In
- the latter case, colouring happens only if the standard out-
- put is connected to a terminal. More resources are used when
- colouring is enabled, because pcregrep has to search for all
- possible matches in a line, not just one, in order to colour
+ By default, the output is not coloured. The value (which is
+ optional, see above) may be "never", "always", or "auto". In
+ the latter case, colouring happens only if the standard out-
+ put is connected to a terminal. More resources are used when
+ colouring is enabled, because pcregrep has to search for all
+ possible matches in a line, not just one, in order to colour
them all.
The colour that is used can be specified by setting the envi-
ronment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value
of this variable should be a string of two numbers, separated
- by a semicolon. They are copied directly into the control
- string for setting colour on a terminal, so it is your
- responsibility to ensure that they make sense. If neither of
- the environment variables is set, the default is "1;31",
+ by a semicolon. They are copied directly into the control
+ string for setting colour on a terminal, so it is your
+ responsibility to ensure that they make sense. If neither of
+ the environment variables is set, the default is "1;31",
which gives red.
-D action, --devices=action
- If an input path is not a regular file or a directory,
- "action" specifies how it is to be processed. Valid values
+ If an input path is not a regular file or a directory,
+ "action" specifies how it is to be processed. Valid values
are "read" (the default) or "skip" (silently skip the path).
-d action, --directories=action
If an input path is a directory, "action" specifies how it is
- to be processed. Valid values are "read" (the default in
- non-Windows environments, for compatibility with GNU grep),
- "recurse" (equivalent to the -r option), or "skip" (silently
- skip the path, the default in Windows environments). In the
- "read" case, directories are read as if they were ordinary
- files. In some operating systems the effect of reading a
+ to be processed. Valid values are "read" (the default in
+ non-Windows environments, for compatibility with GNU grep),
+ "recurse" (equivalent to the -r option), or "skip" (silently
+ skip the path, the default in Windows environments). In the
+ "read" case, directories are read as if they were ordinary
+ files. In some operating systems the effect of reading a
directory like this is an immediate end-of-file; in others it
may provoke an error.
-e pattern, --regex=pattern, --regexp=pattern
Specify a pattern to be matched. This option can be used mul-
tiple times in order to specify several patterns. It can also
- be used as a way of specifying a single pattern that starts
- with a hyphen. When -e is used, no argument pattern is taken
- from the command line; all arguments are treated as file
- names. There is no limit to the number of patterns. They are
- applied to each line in the order in which they are defined
+ be used as a way of specifying a single pattern that starts
+ with a hyphen. When -e is used, no argument pattern is taken
+ from the command line; all arguments are treated as file
+ names. There is no limit to the number of patterns. They are
+ applied to each line in the order in which they are defined
until one matches.
- If -f is used with -e, the command line patterns are matched
+ If -f is used with -e, the command line patterns are matched
first, followed by the patterns from the file(s), independent
- of the order in which these options are specified. Note that
- multiple use of -e is not the same as a single pattern with
+ of the order in which these options are specified. Note that
+ multiple use of -e is not the same as a single pattern with
alternatives. For example, X|Y finds the first character in a
- line that is X or Y, whereas if the two patterns are given
- separately, with X first, pcregrep finds X if it is present,
+ line that is X or Y, whereas if the two patterns are given
+ separately, with X first, pcregrep finds X if it is present,
even if it follows Y in the line. It finds Y only if there is
- no X in the line. This matters only if you are using -o or
+ no X in the line. This matters only if you are using -o or
--colo(u)r to show the part(s) of the line that matched.
--exclude=pattern
Files (but not directories) whose names match the pattern are
- skipped without being processed. This applies to all files,
- whether listed on the command line, obtained from --file-
+ skipped without being processed. This applies to all files,
+ whether listed on the command line, obtained from --file-
list, or by scanning a directory. The pattern is a PCRE regu-
lar expression, and is matched against the final component of
- the file name, not the entire path. The -F, -w, and -x
+ the file name, not the entire path. The -F, -w, and -x
options do not apply to this pattern. The option may be given
any number of times in order to specify multiple patterns. If
- a file name matches both an --include and an --exclude pat-
+ a file name matches both an --include and an --exclude pat-
tern, it is excluded. There is no short form for this option.
--exclude-from=filename
- Treat each non-empty line of the file as the data for an
+ Treat each non-empty line of the file as the data for an
--exclude option. What constitutes a newline when reading the
- file is the operating system's default. The --newline option
- has no effect on this option. This option may be given more
+ file is the operating system's default. The --newline option
+ has no effect on this option. This option may be given more
than once in order to specify a number of files to read.
--exclude-dir=pattern
Directories whose names match the pattern are skipped without
- being processed, whatever the setting of the --recursive
- option. This applies to all directories, whether listed on
+ being processed, whatever the setting of the --recursive
+ option. This applies to all directories, whether listed on
the command line, obtained from --file-list, or by scanning a
- parent directory. The pattern is a PCRE regular expression,
- and is matched against the final component of the directory
- name, not the entire path. The -F, -w, and -x options do not
- apply to this pattern. The option may be given any number of
- times in order to specify more than one pattern. If a direc-
- tory matches both --include-dir and --exclude-dir, it is
+ parent directory. The pattern is a PCRE regular expression,
+ and is matched against the final component of the directory
+ name, not the entire path. The -F, -w, and -x options do not
+ apply to this pattern. The option may be given any number of
+ times in order to specify more than one pattern. If a direc-
+ tory matches both --include-dir and --exclude-dir, it is
excluded. There is no short form for this option.
-F, --fixed-strings
- Interpret each data-matching pattern as a list of fixed
- strings, separated by newlines, instead of as a regular
- expression. What constitutes a newline for this purpose is
- controlled by the --newline option. The -w (match as a word)
- and -x (match whole line) options can be used with -F. They
+ Interpret each data-matching pattern as a list of fixed
+ strings, separated by newlines, instead of as a regular
+ expression. What constitutes a newline for this purpose is
+ controlled by the --newline option. The -w (match as a word)
+ and -x (match whole line) options can be used with -F. They
apply to each of the fixed strings. A line is selected if any
of the fixed strings are found in it (subject to -w or -x, if
- present). This option applies only to the patterns that are
- matched against the contents of files; it does not apply to
- patterns specified by any of the --include or --exclude
+ present). This option applies only to the patterns that are
+ matched against the contents of files; it does not apply to
+ patterns specified by any of the --include or --exclude
options.
-f filename, --file=filename
- Read patterns from the file, one per line, and match them
- against each line of input. What constitutes a newline when
- reading the file is the operating system's default. The
+ Read patterns from the file, one per line, and match them
+ against each line of input. What constitutes a newline when
+ reading the file is the operating system's default. The
--newline option has no effect on this option. Trailing white
space is removed from each line, and blank lines are ignored.
- An empty file contains no patterns and therefore matches
+ An empty file contains no patterns and therefore matches
nothing. See also the comments about multiple patterns versus
- a single pattern with alternatives in the description of -e
+ a single pattern with alternatives in the description of -e
above.
- If this option is given more than once, all the specified
- files are read. A data line is output if any of the patterns
- match it. A filename can be given as "-" to refer to the
- standard input. When -f is used, patterns specified on the
- command line using -e may also be present; they are tested
- before the file's patterns. However, no other pattern is
+ If this option is given more than once, all the specified
+ files are read. A data line is output if any of the patterns
+ match it. A filename can be given as "-" to refer to the
+ standard input. When -f is used, patterns specified on the
+ command line using -e may also be present; they are tested
+ before the file's patterns. However, no other pattern is
taken from the command line; all arguments are treated as the
names of paths to be searched.
--file-list=filename
- Read a list of files and/or directories that are to be
- scanned from the given file, one per line. Trailing white
+ Read a list of files and/or directories that are to be
+ scanned from the given file, one per line. Trailing white
space is removed from each line, and blank lines are ignored.
- These paths are processed before any that are listed on the
- command line. The filename can be given as "-" to refer to
+ These paths are processed before any that are listed on the
+ command line. The filename can be given as "-" to refer to
the standard input. If --file and --file-list are both spec-
- ified as "-", patterns are read first. This is useful only
- when the standard input is a terminal, from which further
- lines (the list of files) can be read after an end-of-file
- indication. If this option is given more than once, all the
+ ified as "-", patterns are read first. This is useful only
+ when the standard input is a terminal, from which further
+ lines (the list of files) can be read after an end-of-file
+ indication. If this option is given more than once, all the
specified files are read.
--file-offsets
- Instead of showing lines or parts of lines that match, show
- each match as an offset from the start of the file and a
- length, separated by a comma. In this mode, no context is
- shown. That is, the -A, -B, and -C options are ignored. If
+ Instead of showing lines or parts of lines that match, show
+ each match as an offset from the start of the file and a
+ length, separated by a comma. In this mode, no context is
+ shown. That is, the -A, -B, and -C options are ignored. If
there is more than one match in a line, each of them is shown
- separately. This option is mutually exclusive with --line-
+ separately. This option is mutually exclusive with --line-
offsets and --only-matching.
-H, --with-filename
- Force the inclusion of the filename at the start of output
- lines when searching a single file. By default, the filename
- is not shown in this case. For matching lines, the filename
+ Force the inclusion of the filename at the start of output
+ lines when searching a single file. By default, the filename
+ is not shown in this case. For matching lines, the filename
is followed by a colon; for context lines, a hyphen separator
- is used. If a line number is also being output, it follows
+ is used. If a line number is also being output, it follows
the file name.
-h, --no-filename
- Suppress the output filenames when searching multiple files.
- By default, filenames are shown when multiple files are
- searched. For matching lines, the filename is followed by a
- colon; for context lines, a hyphen separator is used. If a
+ Suppress the output filenames when searching multiple files.
+ By default, filenames are shown when multiple files are
+ searched. For matching lines, the filename is followed by a
+ colon; for context lines, a hyphen separator is used. If a
line number is also being output, it follows the file name.
- --help Output a help message, giving brief details of the command
- options and file type support, and then exit. Anything else
+ --help Output a help message, giving brief details of the command
+ options and file type support, and then exit. Anything else
on the command line is ignored.
- -I Treat binary files as never matching. This is equivalent to
+ -I Treat binary files as never matching. This is equivalent to
--binary-files=without-match.
-i, --ignore-case
Ignore upper/lower case distinctions during comparisons.
--include=pattern
- If any --include patterns are specified, the only files that
- are processed are those that match one of the patterns (and
- do not match an --exclude pattern). This option does not
- affect directories, but it applies to all files, whether
- listed on the command line, obtained from --file-list, or by
- scanning a directory. The pattern is a PCRE regular expres-
- sion, and is matched against the final component of the file
- name, not the entire path. The -F, -w, and -x options do not
- apply to this pattern. The option may be given any number of
- times. If a file name matches both an --include and an
- --exclude pattern, it is excluded. There is no short form
+ If any --include patterns are specified, the only files that
+ are processed are those that match one of the patterns (and
+ do not match an --exclude pattern). This option does not
+ affect directories, but it applies to all files, whether
+ listed on the command line, obtained from --file-list, or by
+ scanning a directory. The pattern is a PCRE regular expres-
+ sion, and is matched against the final component of the file
+ name, not the entire path. The -F, -w, and -x options do not
+ apply to this pattern. The option may be given any number of
+ times. If a file name matches both an --include and an
+ --exclude pattern, it is excluded. There is no short form
for this option.
--include-from=filename
- Treat each non-empty line of the file as the data for an
+ Treat each non-empty line of the file as the data for an
--include option. What constitutes a newline for this purpose
- is the operating system's default. The --newline option has
+ is the operating system's default. The --newline option has
no effect on this option. This option may be given any number
of times; all the files are read.
--include-dir=pattern
- If any --include-dir patterns are specified, the only direc-
- tories that are processed are those that match one of the
- patterns (and do not match an --exclude-dir pattern). This
- applies to all directories, whether listed on the command
- line, obtained from --file-list, or by scanning a parent
- directory. The pattern is a PCRE regular expression, and is
- matched against the final component of the directory name,
- not the entire path. The -F, -w, and -x options do not apply
+ If any --include-dir patterns are specified, the only direc-
+ tories that are processed are those that match one of the
+ patterns (and do not match an --exclude-dir pattern). This
+ applies to all directories, whether listed on the command
+ line, obtained from --file-list, or by scanning a parent
+ directory. The pattern is a PCRE regular expression, and is
+ matched against the final component of the directory name,
+ not the entire path. The -F, -w, and -x options do not apply
to this pattern. The option may be given any number of times.
- If a directory matches both --include-dir and --exclude-dir,
+ If a directory matches both --include-dir and --exclude-dir,
it is excluded. There is no short form for this option.
-L, --files-without-match
- Instead of outputting lines from the files, just output the
- names of the files that do not contain any lines that would
- have been output. Each file name is output once, on a sepa-
+ Instead of outputting lines from the files, just output the
+ names of the files that do not contain any lines that would
+ have been output. Each file name is output once, on a sepa-
rate line.
-l, --files-with-matches
- Instead of outputting lines from the files, just output the
+ Instead of outputting lines from the files, just output the
names of the files containing lines that would have been out-
- put. Each file name is output once, on a separate line.
- Searching normally stops as soon as a matching line is found
- in a file. However, if the -c (count) option is also used,
- matching continues in order to obtain the correct count, and
- those files that have at least one match are listed along
+ put. Each file name is output once, on a separate line.
+ Searching normally stops as soon as a matching line is found
+ in a file. However, if the -c (count) option is also used,
+ matching continues in order to obtain the correct count, and
+ those files that have at least one match are listed along
with their counts. Using this option with -c is a way of sup-
pressing the listing of files with no matches.
@@ -411,313 +412,313 @@ OPTIONS
input)" is used. There is no short form for this option.
--line-buffered
- When this option is given, input is read and processed line
- by line, and the output is flushed after each write. By
- default, input is read in large chunks, unless pcregrep can
- determine that it is reading from a terminal (which is cur-
- rently possible only in Unix-like environments). Output to
- terminal is normally automatically flushed by the operating
+ When this option is given, input is read and processed line
+ by line, and the output is flushed after each write. By
+ default, input is read in large chunks, unless pcregrep can
+ determine that it is reading from a terminal (which is cur-
+ rently possible only in Unix-like environments). Output to
+ terminal is normally automatically flushed by the operating
system. This option can be useful when the input or output is
- attached to a pipe and you do not want pcregrep to buffer up
- large amounts of data. However, its use will affect perfor-
+ attached to a pipe and you do not want pcregrep to buffer up
+ large amounts of data. However, its use will affect perfor-
mance, and the -M (multiline) option ceases to work.
--line-offsets
- Instead of showing lines or parts of lines that match, show
+ Instead of showing lines or parts of lines that match, show
each match as a line number, the offset from the start of the
- line, and a length. The line number is terminated by a colon
- (as usual; see the -n option), and the offset and length are
- separated by a comma. In this mode, no context is shown.
- That is, the -A, -B, and -C options are ignored. If there is
- more than one match in a line, each of them is shown sepa-
+ line, and a length. The line number is terminated by a colon
+ (as usual; see the -n option), and the offset and length are
+ separated by a comma. In this mode, no context is shown.
+ That is, the -A, -B, and -C options are ignored. If there is
+ more than one match in a line, each of them is shown sepa-
rately. This option is mutually exclusive with --file-offsets
and --only-matching.
--locale=locale-name
- This option specifies a locale to be used for pattern match-
- ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
- ronment variables. If no locale is specified, the PCRE
- library's default (usually the "C" locale) is used. There is
+ This option specifies a locale to be used for pattern match-
+ ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
+ ronment variables. If no locale is specified, the PCRE
+ library's default (usually the "C" locale) is used. There is
no short form for this option.
--match-limit=number
- Processing some regular expression patterns can require a
- very large amount of memory, leading in some cases to a pro-
- gram crash if not enough is available. Other patterns may
- take a very long time to search for all possible matching
- strings. The pcre_exec() function that is called by pcregrep
- to do the matching has two parameters that can limit the
+ Processing some regular expression patterns can require a
+ very large amount of memory, leading in some cases to a pro-
+ gram crash if not enough is available. Other patterns may
+ take a very long time to search for all possible matching
+ strings. The pcre_exec() function that is called by pcregrep
+ to do the matching has two parameters that can limit the
resources that it uses.
- The --match-limit option provides a means of limiting
+ The --match-limit option provides a means of limiting
resource usage when processing patterns that are not going to
match, but which have a very large number of possibilities in
- their search trees. The classic example is a pattern that
- uses nested unlimited repeats. Internally, PCRE uses a func-
- tion called match() which it calls repeatedly (sometimes
- recursively). The limit set by --match-limit is imposed on
- the number of times this function is called during a match,
- which has the effect of limiting the amount of backtracking
+ their search trees. The classic example is a pattern that
+ uses nested unlimited repeats. Internally, PCRE uses a func-
+ tion called match() which it calls repeatedly (sometimes
+ recursively). The limit set by --match-limit is imposed on
+ the number of times this function is called during a match,
+ which has the effect of limiting the amount of backtracking
that can take place.
The --recursion-limit option is similar to --match-limit, but
instead of limiting the total number of times that match() is
called, it limits the depth of recursive calls, which in turn
- limits the amount of memory that can be used. The recursion
- depth is a smaller number than the total number of calls,
+ limits the amount of memory that can be used. The recursion
+ depth is a smaller number than the total number of calls,
because not all calls to match() are recursive. This limit is
of use only if it is set smaller than --match-limit.
- There are no short forms for these options. The default set-
- tings are specified when the PCRE library is compiled, with
+ There are no short forms for these options. The default set-
+ tings are specified when the PCRE library is compiled, with
the default default being 10 million.
-M, --multiline
- Allow patterns to match more than one line. When this option
+ Allow patterns to match more than one line. When this option
is given, patterns may usefully contain literal newline char-
- acters and internal occurrences of ^ and $ characters. The
- output for a successful match may consist of more than one
- line, the last of which is the one in which the match ended.
+ acters and internal occurrences of ^ and $ characters. The
+ output for a successful match may consist of more than one
+ line, the last of which is the one in which the match ended.
If the matched string ends with a newline sequence the output
ends at the end of that line.
- When this option is set, the PCRE library is called in "mul-
- tiline" mode. There is a limit to the number of lines that
- can be matched, imposed by the way that pcregrep buffers the
- input file as it scans it. However, pcregrep ensures that at
+ When this option is set, the PCRE library is called in "mul-
+ tiline" mode. There is a limit to the number of lines that
+ can be matched, imposed by the way that pcregrep buffers the
+ input file as it scans it. However, pcregrep ensures that at
least 8K characters or the rest of the document (whichever is
- the shorter) are available for forward matching, and simi-
+ the shorter) are available for forward matching, and simi-
larly the previous 8K characters (or all the previous charac-
- ters, if fewer than 8K) are guaranteed to be available for
- lookbehind assertions. This option does not work when input
+ ters, if fewer than 8K) are guaranteed to be available for
+ lookbehind assertions. This option does not work when input
is read line by line (see --line-buffered.)
-N newline-type, --newline=newline-type
- The PCRE library supports five different conventions for
- indicating the ends of lines. They are the single-character
- sequences CR (carriage return) and LF (linefeed), the two-
- character sequence CRLF, an "anycrlf" convention, which rec-
- ognizes any of the preceding three types, and an "any" con-
+ The PCRE library supports five different conventions for
+ indicating the ends of lines. They are the single-character
+ sequences CR (carriage return) and LF (linefeed), the two-
+ character sequence CRLF, an "anycrlf" convention, which rec-
+ ognizes any of the preceding three types, and an "any" con-
vention, in which any Unicode line ending sequence is assumed
- to end a line. The Unicode sequences are the three just men-
- tioned, plus VT (vertical tab, U+000B), FF (form feed,
- U+000C), NEL (next line, U+0085), LS (line separator,
+ to end a line. The Unicode sequences are the three just men-
+ tioned, plus VT (vertical tab, U+000B), FF (form feed,
+ U+000C), NEL (next line, U+0085), LS (line separator,
U+2028), and PS (paragraph separator, U+2029).
When the PCRE library is built, a default line-ending
- sequence is specified. This is normally the standard
+ sequence is specified. This is normally the standard
sequence for the operating system. Unless otherwise specified
- by this option, pcregrep uses the library's default. The
+ by this option, pcregrep uses the library's default. The
possible values for this option are CR, LF, CRLF, ANYCRLF, or
- ANY. This makes it possible to use pcregrep to scan files
+ ANY. This makes it possible to use pcregrep to scan files
that have come from other environments without having to mod-
- ify their line endings. If the data that is being scanned
- does not agree with the convention set by this option, pcre-
- grep may behave in strange ways. Note that this option does
- not apply to files specified by the -f, --exclude-from, or
+ ify their line endings. If the data that is being scanned
+ does not agree with the convention set by this option, pcre-
+ grep may behave in strange ways. Note that this option does
+ not apply to files specified by the -f, --exclude-from, or
--include-from options, which are expected to use the operat-
ing system's standard newline sequence.
-n, --line-number
Precede each output line by its line number in the file, fol-
- lowed by a colon for matching lines or a hyphen for context
- lines. If the filename is also being output, it precedes the
+ lowed by a colon for matching lines or a hyphen for context
+ lines. If the filename is also being output, it precedes the
line number. This option is forced if --line-offsets is used.
- --no-jit If the PCRE library is built with support for just-in-time
- compiling (which speeds up matching), pcregrep automatically
+ --no-jit If the PCRE library is built with support for just-in-time
+ compiling (which speeds up matching), pcregrep automatically
makes use of this, unless it was explicitly disabled at build
- time. This option can be used to disable the use of JIT at
- run time. It is provided for testing and working round prob-
+ time. This option can be used to disable the use of JIT at
+ run time. It is provided for testing and working round prob-
lems. It should never be needed in normal use.
-o, --only-matching
Show only the part of the line that matched a pattern instead
- of the whole line. In this mode, no context is shown. That
- is, the -A, -B, and -C options are ignored. If there is more
- than one match in a line, each of them is shown separately.
- If -o is combined with -v (invert the sense of the match to
- find non-matching lines), no output is generated, but the
- return code is set appropriately. If the matched portion of
- the line is empty, nothing is output unless the file name or
- line number are being printed, in which case they are shown
+ of the whole line. In this mode, no context is shown. That
+ is, the -A, -B, and -C options are ignored. If there is more
+ than one match in a line, each of them is shown separately.
+ If -o is combined with -v (invert the sense of the match to
+ find non-matching lines), no output is generated, but the
+ return code is set appropriately. If the matched portion of
+ the line is empty, nothing is output unless the file name or
+ line number are being printed, in which case they are shown
on an otherwise empty line. This option is mutually exclusive
with --file-offsets and --line-offsets.
-onumber, --only-matching=number
- Show only the part of the line that matched the capturing
+ Show only the part of the line that matched the capturing
parentheses of the given number. Up to 32 capturing parenthe-
ses are supported, and -o0 is equivalent to -o without a num-
- ber. Because these options can be given without an argument
- (see above), if an argument is present, it must be given in
- the same shell item, for example, -o3 or --only-matching=2.
+ ber. Because these options can be given without an argument
+ (see above), if an argument is present, it must be given in
+ the same shell item, for example, -o3 or --only-matching=2.
The comments given for the non-argument case above also apply
- to this case. If the specified capturing parentheses do not
- exist in the pattern, or were not set in the match, nothing
- is output unless the file name or line number are being
+ to this case. If the specified capturing parentheses do not
+ exist in the pattern, or were not set in the match, nothing
+ is output unless the file name or line number are being
printed.
- If this option is given multiple times, multiple substrings
- are output, in the order the options are given. For example,
+ If this option is given multiple times, multiple substrings
+ are output, in the order the options are given. For example,
-o3 -o1 -o3 causes the substrings matched by capturing paren-
- theses 3 and 1 and then 3 again to be output. By default,
+ theses 3 and 1 and then 3 again to be output. By default,
there is no separator (but see the next option).
--om-separator=text
- Specify a separating string for multiple occurrences of -o.
- The default is an empty string. Separating strings are never
+ Specify a separating string for multiple occurrences of -o.
+ The default is an empty string. Separating strings are never
coloured.
-q, --quiet
Work quietly, that is, display nothing except error messages.
- The exit status indicates whether or not any matches were
+ The exit status indicates whether or not any matches were
found.
-r, --recursive
- If any given path is a directory, recursively scan the files
- it contains, taking note of any --include and --exclude set-
- tings. By default, a directory is read as a normal file; in
- some operating systems this gives an immediate end-of-file.
- This option is a shorthand for setting the -d option to
+ If any given path is a directory, recursively scan the files
+ it contains, taking note of any --include and --exclude set-
+ tings. By default, a directory is read as a normal file; in
+ some operating systems this gives an immediate end-of-file.
+ This option is a shorthand for setting the -d option to
"recurse".
--recursion-limit=number
See --match-limit above.
-s, --no-messages
- Suppress error messages about non-existent or unreadable
- files. Such files are quietly skipped. However, the return
+ Suppress error messages about non-existent or unreadable
+ files. Such files are quietly skipped. However, the return
code is still 2, even if matches were found in other files.
-u, --utf-8
- Operate in UTF-8 mode. This option is available only if PCRE
+ Operate in UTF-8 mode. This option is available only if PCRE
has been compiled with UTF-8 support. All patterns (including
- those for any --exclude and --include options) and all sub-
- ject lines that are scanned must be valid strings of UTF-8
+ those for any --exclude and --include options) and all sub-
+ ject lines that are scanned must be valid strings of UTF-8
characters.
-V, --version
Write the version numbers of pcregrep and the PCRE library to
- the standard output and then exit. Anything else on the com-
+ the standard output and then exit. Anything else on the com-
mand line is ignored.
-v, --invert-match
- Invert the sense of the match, so that lines which do not
+ Invert the sense of the match, so that lines which do not
match any of the patterns are the ones that are found.
-w, --word-regex, --word-regexp
Force the patterns to match only whole words. This is equiva-
- lent to having \b at the start and end of the pattern. This
- option applies only to the patterns that are matched against
- the contents of files; it does not apply to patterns speci-
+ lent to having \b at the start and end of the pattern. This
+ option applies only to the patterns that are matched against
+ the contents of files; it does not apply to patterns speci-
fied by any of the --include or --exclude options.
-x, --line-regex, --line-regexp
- Force the patterns to be anchored (each must start matching
- at the beginning of a line) and in addition, require them to
- match entire lines. This is equivalent to having ^ and $
+ Force the patterns to be anchored (each must start matching
+ at the beginning of a line) and in addition, require them to
+ match entire lines. This is equivalent to having ^ and $
characters at the start and end of each alternative branch in
- every pattern. This option applies only to the patterns that
- are matched against the contents of files; it does not apply
- to patterns specified by any of the --include or --exclude
+ every pattern. This option applies only to the patterns that
+ are matched against the contents of files; it does not apply
+ to patterns specified by any of the --include or --exclude
options.
ENVIRONMENT VARIABLES
- The environment variables LC_ALL and LC_CTYPE are examined, in that
- order, for a locale. The first one that is set is used. This can be
- overridden by the --locale option. If no locale is set, the PCRE
+ The environment variables LC_ALL and LC_CTYPE are examined, in that
+ order, for a locale. The first one that is set is used. This can be
+ overridden by the --locale option. If no locale is set, the PCRE
library's default (usually the "C" locale) is used.
NEWLINES
- The -N (--newline) option allows pcregrep to scan files with different
+ The -N (--newline) option allows pcregrep to scan files with different
newline conventions from the default. Any parts of the input files that
- are written to the standard output are copied identically, with what-
- ever newline sequences they have in the input. However, the setting of
- this option does not affect the interpretation of files specified by
+ are written to the standard output are copied identically, with what-
+ ever newline sequences they have in the input. However, the setting of
+ this option does not affect the interpretation of files specified by
the -f, --exclude-from, or --include-from options, which are assumed to
- use the operating system's standard newline sequence, nor does it
- affect the way in which pcregrep writes informational messages to the
+ use the operating system's standard newline sequence, nor does it
+ affect the way in which pcregrep writes informational messages to the
standard error and output streams. For these it uses the string "\n" to
- indicate newlines, relying on the C I/O library to convert this to an
+ indicate newlines, relying on the C I/O library to convert this to an
appropriate sequence.
OPTIONS COMPATIBILITY
- Many of the short and long forms of pcregrep's options are the same as
- in the GNU grep program. Any long option of the form --xxx-regexp (GNU
- terminology) is also available as --xxx-regex (PCRE terminology). How-
- ever, the --file-list, --file-offsets, --include-dir, --line-offsets,
- --locale, --match-limit, -M, --multiline, -N, --newline, --om-separa-
- tor, --recursion-limit, -u, and --utf-8 options are specific to pcre-
- grep, as is the use of the --only-matching option with a capturing
+ Many of the short and long forms of pcregrep's options are the same as
+ in the GNU grep program. Any long option of the form --xxx-regexp (GNU
+ terminology) is also available as --xxx-regex (PCRE terminology). How-
+ ever, the --file-list, --file-offsets, --include-dir, --line-offsets,
+ --locale, --match-limit, -M, --multiline, -N, --newline, --om-separa-
+ tor, --recursion-limit, -u, and --utf-8 options are specific to pcre-
+ grep, as is the use of the --only-matching option with a capturing
parentheses number.
- Although most of the common options work the same way, a few are dif-
- ferent in pcregrep. For example, the --include option's argument is a
- glob for GNU grep, but a regular expression for pcregrep. If both the
- -c and -l options are given, GNU grep lists only file names, without
+ Although most of the common options work the same way, a few are dif-
+ ferent in pcregrep. For example, the --include option's argument is a
+ glob for GNU grep, but a regular expression for pcregrep. If both the
+ -c and -l options are given, GNU grep lists only file names, without
counts, but pcregrep gives the counts.
OPTIONS WITH DATA
There are four different ways in which an option with data can be spec-
- ified. If a short form option is used, the data may follow immedi-
+ ified. If a short form option is used, the data may follow immedi-
ately, or (with one exception) in the next command line item. For exam-
ple:
-f/some/file
-f /some/file
- The exception is the -o option, which may appear with or without data.
- Because of this, if data is present, it must follow immediately in the
+ The exception is the -o option, which may appear with or without data.
+ Because of this, if data is present, it must follow immediately in the
same item, for example -o3.
- If a long form option is used, the data may appear in the same command
- line item, separated by an equals character, or (with two exceptions)
+ If a long form option is used, the data may appear in the same command
+ line item, separated by an equals character, or (with two exceptions)
it may appear in the next command line item. For example:
--file=/some/file
--file /some/file
- Note, however, that if you want to supply a file name beginning with ~
- as data in a shell command, and have the shell expand ~ to a home
+ Note, however, that if you want to supply a file name beginning with ~
+ as data in a shell command, and have the shell expand ~ to a home
directory, you must separate the file name from the option, because the
shell does not treat ~ specially unless it is at the start of an item.
- The exceptions to the above are the --colour (or --color) and --only-
- matching options, for which the data is optional. If one of these
- options does have data, it must be given in the first form, using an
+ The exceptions to the above are the --colour (or --color) and --only-
+ matching options, for which the data is optional. If one of these
+ options does have data, it must be given in the first form, using an
equals character. Otherwise pcregrep will assume that it has no data.
MATCHING ERRORS
- It is possible to supply a regular expression that takes a very long
- time to fail to match certain lines. Such patterns normally involve
- nested indefinite repeats, for example: (a+)*\d when matched against a
- line of a's with no final digit. The PCRE matching function has a
- resource limit that causes it to abort in these circumstances. If this
+ It is possible to supply a regular expression that takes a very long
+ time to fail to match certain lines. Such patterns normally involve
+ nested indefinite repeats, for example: (a+)*\d when matched against a
+ line of a's with no final digit. The PCRE matching function has a
+ resource limit that causes it to abort in these circumstances. If this
happens, pcregrep outputs an error message and the line that caused the
- problem to the standard error stream. If there are more than 20 such
+ problem to the standard error stream. If there are more than 20 such
errors, pcregrep gives up.
- The --match-limit option of pcregrep can be used to set the overall
- resource limit; there is a second option called --recursion-limit that
- sets a limit on the amount of memory (usually stack) that is used (see
+ The --match-limit option of pcregrep can be used to set the overall
+ resource limit; there is a second option called --recursion-limit that
+ sets a limit on the amount of memory (usually stack) that is used (see
the discussion of these options above).
DIAGNOSTICS
Exit status is 0 if any matches were found, 1 if no matches were found,
- and 2 for syntax errors, overlong lines, non-existent or inaccessible
- files (even if matches were found in other files) or too many matching
+ and 2 for syntax errors, overlong lines, non-existent or inaccessible
+ files (even if matches were found in other files) or too many matching
errors. Using the -s option to suppress error messages about inaccessi-
ble files does not affect the return code.
@@ -736,5 +737,5 @@ AUTHOR
REVISION
- Last updated: 13 September 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 03 April 2014
+ Copyright (c) 1997-2014 University of Cambridge.
diff --git a/pcre/doc/pcrepattern.3 b/pcre/doc/pcrepattern.3
index 4c515f83adc..f1c45cda5d2 100644
--- a/pcre/doc/pcrepattern.3
+++ b/pcre/doc/pcrepattern.3
@@ -1,4 +1,4 @@
-.TH PCREPATTERN 3 "03 December 2013" "PCRE 8.34"
+.TH PCREPATTERN 3 "08 January 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE REGULAR EXPRESSION DETAILS"
@@ -1004,7 +1004,9 @@ matches "foobar", the first substring is still set to "foo".
.P
Perl documents that the use of \eK within assertions is "not well defined". In
PCRE, \eK is acted upon when it occurs inside positive assertions, but is
-ignored in negative assertions.
+ignored in negative assertions. Note that when a pattern such as (?=ab\eK)
+matches, the reported start of the match can be greater than the end of the
+match.
.
.
.\" HTML <a name="smallassertions"></a>
@@ -3028,19 +3030,22 @@ match does not always guarantee that a match must be at this starting point.
.P
Note that (*COMMIT) at the start of a pattern is not the same as an anchor,
unless PCRE's start-of-match optimizations are turned off, as shown in this
-\fBpcretest\fP example:
+output from \fBpcretest\fP:
.sp
re> /(*COMMIT)abc/
data> xyzabc
0: abc
- xyzabc\eY
+ data> xyzabc\eY
No match
.sp
-PCRE knows that any match must start with "a", so the optimization skips along
-the subject to "a" before running the first match attempt, which succeeds. When
-the optimization is disabled by the \eY escape in the second subject, the match
-starts at "x" and so the (*COMMIT) causes it to fail without trying any other
-starting points.
+For this pattern, PCRE knows that any match must start with "a", so the
+optimization skips along the subject to "a" before applying the pattern to the
+first set of data. The match attempt then succeeds. In the second set of data,
+the escape sequence \eY is interpreted by the \fBpcretest\fP program. It causes
+the PCRE_NO_START_OPTIMIZE option to be set when \fBpcre_exec()\fP is called.
+This disables the optimization that skips along to the first character. The
+pattern is now applied starting at "x", and so the (*COMMIT) causes the match
+to fail without trying any other starting points.
.sp
(*PRUNE) or (*PRUNE:NAME)
.sp
@@ -3255,6 +3260,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
-Last updated: 03 December 2013
-Copyright (c) 1997-2013 University of Cambridge.
+Last updated: 08 January 2014
+Copyright (c) 1997-2014 University of Cambridge.
.fi
diff --git a/pcre/doc/pcresyntax.3 b/pcre/doc/pcresyntax.3
index 87f0cead743..fd878da4f99 100644
--- a/pcre/doc/pcresyntax.3
+++ b/pcre/doc/pcresyntax.3
@@ -1,4 +1,4 @@
-.TH PCRESYNTAX 3 "12 November 2013" "PCRE 8.34"
+.TH PCRESYNTAX 3 "08 January 2014" "PCRE 8.35"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY"
@@ -309,6 +309,8 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use
.rs
.sp
\eK reset start of match
+.sp
+\eK is honoured in positive assertions, but ignored in negative ones.
.
.
.SH "ALTERNATION"
@@ -354,11 +356,13 @@ but some of them use Unicode properties if PCRE_UCP is set. You can use
(?x) extended (ignore white space)
(?-...) unset option(s)
.sp
-The following are recognized only at the start of a pattern or after one of the
-newline-setting options with similar syntax:
+The following are recognized only at the very start of a pattern or after one
+of the newline or \eR options with similar syntax. More than one of them may
+appear.
.sp
(*LIMIT_MATCH=d) set the match limit to d (decimal number)
(*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
+ (*NO_AUTO_POSSESS) no auto-possessification (PCRE_NO_AUTO_POSSESS)
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
(*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
(*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
@@ -370,6 +374,29 @@ Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of the
limits set by the caller of pcre_exec(), not increase them.
.
.
+.SH "NEWLINE CONVENTION"
+.rs
+.sp
+These are recognized only at the very start of the pattern or after option
+settings with a similar syntax.
+.sp
+ (*CR) carriage return only
+ (*LF) linefeed only
+ (*CRLF) carriage return followed by linefeed
+ (*ANYCRLF) all three of the above
+ (*ANY) any Unicode newline sequence
+.
+.
+.SH "WHAT \eR MATCHES"
+.rs
+.sp
+These are recognized only at the very start of the pattern or after option
+setting with a similar syntax.
+.sp
+ (*BSR_ANYCRLF) CR, LF, or CRLF
+ (*BSR_UNICODE) any Unicode newline sequence
+.
+.
.SH "LOOKAHEAD AND LOOKBEHIND ASSERTIONS"
.rs
.sp
@@ -457,29 +484,6 @@ pattern is not anchored.
(*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
.
.
-.SH "NEWLINE CONVENTIONS"
-.rs
-.sp
-These are recognized only at the very start of the pattern or after a
-(*BSR_...), (*UTF8), (*UTF16), (*UTF32) or (*UCP) option.
-.sp
- (*CR) carriage return only
- (*LF) linefeed only
- (*CRLF) carriage return followed by linefeed
- (*ANYCRLF) all three of the above
- (*ANY) any Unicode newline sequence
-.
-.
-.SH "WHAT \eR MATCHES"
-.rs
-.sp
-These are recognized only at the very start of the pattern or after a
-(*...) option that sets the newline convention or a UTF or UCP mode.
-.sp
- (*BSR_ANYCRLF) CR, LF, or CRLF
- (*BSR_UNICODE) any Unicode newline sequence
-.
-.
.SH "CALLOUTS"
.rs
.sp
@@ -508,6 +512,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
-Last updated: 12 November 2013
-Copyright (c) 1997-2013 University of Cambridge.
+Last updated: 08 January 2014
+Copyright (c) 1997-2014 University of Cambridge.
.fi
diff --git a/pcre/doc/pcretest.1 b/pcre/doc/pcretest.1
index f17c6f24088..92640da8e1b 100644
--- a/pcre/doc/pcretest.1
+++ b/pcre/doc/pcretest.1
@@ -1,4 +1,4 @@
-.TH PCRETEST 1 "12 November 2013" "PCRE 8.34"
+.TH PCRETEST 1 "09 February 2014" "PCRE 8.35"
.SH NAME
pcretest - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -113,6 +113,9 @@ following options output the value and set the exit code as indicated:
newline the default newline setting:
CR, LF, CRLF, ANYCRLF, or ANY
exit code is always 0
+ bsr the default setting for what \eR matches:
+ ANYCRLF or ANY
+ exit code is always 0
.sp
The following options output 1 for true or 0 for false, and set the exit code
to the same value:
@@ -330,6 +333,7 @@ sections.
\fB/N\fP set PCRE_NO_AUTO_CAPTURE
\fB/O\fP set PCRE_NO_AUTO_POSSESS
\fB/P\fP use the POSIX wrapper
+ \fB/Q\fP test external stack check function
\fB/S\fP study the pattern after compilation
\fB/s\fP set PCRE_DOTALL
\fB/T\fP select character tables
@@ -483,7 +487,10 @@ below.
The \fB/I\fP modifier requests that \fBpcretest\fP output information about the
compiled pattern (whether it is anchored, has a fixed first character, and
so on). It does this by calling \fBpcre[16|32]_fullinfo()\fP after compiling a
-pattern. If the pattern is studied, the results of that are also output.
+pattern. If the pattern is studied, the results of that are also output. In
+this output, the word "char" means a non-UTF character, that is, the value of a
+single data item (8-bit, 16-bit, or 32-bit, depending on the library that is
+being tested).
.P
The \fB/K\fP modifier requests \fBpcretest\fP to show names from backtracking
control verbs that are returned from calls to \fBpcre[16|32]_exec()\fP. It causes
@@ -513,6 +520,15 @@ the compiled pattern to be output. This does not include the size of the
successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the
JIT compiled code is also output.
.P
+The \fB/Q\fP modifier is used to test the use of \fBpcre_stack_guard\fP. It
+must be followed by '0' or '1', specifying the return code to be given from an
+external function that is passed to PCRE and used for stack checking during
+compilation (see the
+.\" HREF
+\fBpcreapi\fP
+.\"
+documentation for details).
+.P
The \fB/S\fP modifier causes \fBpcre[16|32]_study()\fP to be called after the
expression has been compiled, and the results used when the expression is
matched. There are a number of qualifying characters that may follow \fB/S\fP.
@@ -1135,6 +1151,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
-Last updated: 12 November 2013
-Copyright (c) 1997-2013 University of Cambridge.
+Last updated: 09 February 2014
+Copyright (c) 1997-2014 University of Cambridge.
.fi
diff --git a/pcre/doc/pcretest.txt b/pcre/doc/pcretest.txt
index f0609939f5c..55de5024431 100644
--- a/pcre/doc/pcretest.txt
+++ b/pcre/doc/pcretest.txt
@@ -99,6 +99,9 @@ COMMAND LINE OPTIONS
newline the default newline setting:
CR, LF, CRLF, ANYCRLF, or ANY
exit code is always 0
+ bsr the default setting for what \R matches:
+ ANYCRLF or ANY
+ exit code is always 0
The following options output 1 for true or 0 for false, and
set the exit code to the same value:
@@ -316,6 +319,7 @@ PATTERN MODIFIERS
/N set PCRE_NO_AUTO_CAPTURE
/O set PCRE_NO_AUTO_POSSESS
/P use the POSIX wrapper
+ /Q test external stack check function
/S study the pattern after compilation
/s set PCRE_DOTALL
/T select character tables
@@ -462,7 +466,9 @@ PATTERN MODIFIERS
compiled pattern (whether it is anchored, has a fixed first character,
and so on). It does this by calling pcre[16|32]_fullinfo() after com-
piling a pattern. If the pattern is studied, the results of that are
- also output.
+ also output. In this output, the word "char" means a non-UTF character,
+ that is, the value of a single data item (8-bit, 16-bit, or 32-bit,
+ depending on the library that is being tested).
The /K modifier requests pcretest to show names from backtracking con-
trol verbs that are returned from calls to pcre[16|32]_exec(). It
@@ -493,26 +499,31 @@ PATTERN MODIFIERS
pattern is successfully studied with the PCRE_STUDY_JIT_COMPILE option,
the size of the JIT compiled code is also output.
- The /S modifier causes pcre[16|32]_study() to be called after the
- expression has been compiled, and the results used when the expression
+ The /Q modifier is used to test the use of pcre_stack_guard. It must be
+ followed by '0' or '1', specifying the return code to be given from an
+ external function that is passed to PCRE and used for stack checking
+ during compilation (see the pcreapi documentation for details).
+
+ The /S modifier causes pcre[16|32]_study() to be called after the
+ expression has been compiled, and the results used when the expression
is matched. There are a number of qualifying characters that may follow
/S. They may appear in any order.
If /S is followed by an exclamation mark, pcre[16|32]_study() is called
- with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a
+ with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a
pcre_extra block, even when studying discovers no useful information.
If /S is followed by a second S character, it suppresses studying, even
- if it was requested externally by the -s command line option. This
- makes it possible to specify that certain patterns are always studied,
+ if it was requested externally by the -s command line option. This
+ makes it possible to specify that certain patterns are always studied,
and others are never studied, independently of -s. This feature is used
in the test files in a few cases where the output is different when the
pattern is studied.
- If the /S modifier is followed by a + character, the call to
- pcre[16|32]_study() is made with all the JIT study options, requesting
- just-in-time optimization support if it is available, for both normal
- and partial matching. If you want to restrict the JIT compiling modes,
+ If the /S modifier is followed by a + character, the call to
+ pcre[16|32]_study() is made with all the JIT study options, requesting
+ just-in-time optimization support if it is available, for both normal
+ and partial matching. If you want to restrict the JIT compiling modes,
you can follow /S+ with a digit in the range 1 to 7:
1 normal match only
@@ -523,40 +534,40 @@ PATTERN MODIFIERS
7 all three modes (default)
If /S++ is used instead of /S+ (with or without a following digit), the
- text "(JIT)" is added to the first output line after a match or no
+ text "(JIT)" is added to the first output line after a match or no
match when JIT-compiled code was actually used.
- Note that there is also an independent /+ modifier; it must not be
+ Note that there is also an independent /+ modifier; it must not be
given immediately after /S or /S+ because this will be misinterpreted.
If JIT studying is successful, the compiled JIT code will automatically
- be used when pcre[16|32]_exec() is run, except when incompatible run-
- time options are specified. For more details, see the pcrejit documen-
- tation. See also the \J escape sequence below for a way of setting the
+ be used when pcre[16|32]_exec() is run, except when incompatible run-
+ time options are specified. For more details, see the pcrejit documen-
+ tation. See also the \J escape sequence below for a way of setting the
size of the JIT stack.
- Finally, if /S is followed by a minus character, JIT compilation is
- suppressed, even if it was requested externally by the -s command line
- option. This makes it possible to specify that JIT is never to be used
+ Finally, if /S is followed by a minus character, JIT compilation is
+ suppressed, even if it was requested externally by the -s command line
+ option. This makes it possible to specify that JIT is never to be used
for certain patterns.
- The /T modifier must be followed by a single digit. It causes a spe-
+ The /T modifier must be followed by a single digit. It causes a spe-
cific set of built-in character tables to be passed to pcre[16|32]_com-
- pile(). It is used in the standard PCRE tests to check behaviour with
+ pile(). It is used in the standard PCRE tests to check behaviour with
different character tables. The digit specifies the tables as follows:
0 the default ASCII tables, as distributed in
pcre_chartables.c.dist
1 a set of tables defining ISO 8859 characters
- In table 1, some characters whose codes are greater than 128 are iden-
+ In table 1, some characters whose codes are greater than 128 are iden-
tified as letters, digits, spaces, etc.
Using the POSIX wrapper API
- The /P modifier causes pcretest to call PCRE via the POSIX wrapper API
- rather than its native API. This supports only the 8-bit library. When
- /P is set, the following modifiers set options for the regcomp() func-
+ The /P modifier causes pcretest to call PCRE via the POSIX wrapper API
+ rather than its native API. This supports only the 8-bit library. When
+ /P is set, the following modifiers set options for the regcomp() func-
tion:
/i REG_ICASE
@@ -567,48 +578,48 @@ PATTERN MODIFIERS
/W REG_UCP ) the POSIX standard
/8 REG_UTF8 )
- The /+ modifier works as described above. All other modifiers are
+ The /+ modifier works as described above. All other modifiers are
ignored.
Locking out certain modifiers
- PCRE can be compiled with or without support for certain features such
- as UTF-8/16/32 or Unicode properties. Accordingly, the standard tests
- are split up into a number of different files that are selected for
- running depending on which features are available. When updating the
+ PCRE can be compiled with or without support for certain features such
+ as UTF-8/16/32 or Unicode properties. Accordingly, the standard tests
+ are split up into a number of different files that are selected for
+ running depending on which features are available. When updating the
tests, it is all too easy to put a new test into the wrong file by mis-
- take; for example, to put a test that requires UTF support into a file
- that is used when it is not available. To help detect such mistakes as
- early as possible, there is a facility for locking out specific modi-
+ take; for example, to put a test that requires UTF support into a file
+ that is used when it is not available. To help detect such mistakes as
+ early as possible, there is a facility for locking out specific modi-
fiers. If an input line for pcretest starts with the string "< forbid "
- the following sequence of characters is taken as a list of forbidden
+ the following sequence of characters is taken as a list of forbidden
modifiers. For example, in the test files that must not use UTF or Uni-
code property support, this line appears:
< forbid 8W
- This locks out the /8 and /W modifiers. An immediate error is given if
- they are subsequently encountered. If the character string contains <
- but not >, all the multi-character modifiers that begin with < are
- locked out. Otherwise, such modifiers must be explicitly listed, for
+ This locks out the /8 and /W modifiers. An immediate error is given if
+ they are subsequently encountered. If the character string contains <
+ but not >, all the multi-character modifiers that begin with < are
+ locked out. Otherwise, such modifiers must be explicitly listed, for
example:
< forbid <JS><cr>
There must be a single space between < and "forbid" for this feature to
- be recognised. If there is not, the line is interpreted either as a
- request to re-load a pre-compiled pattern (see "SAVING AND RELOADING
- COMPILED PATTERNS" below) or, if there is a another < character, as a
+ be recognised. If there is not, the line is interpreted either as a
+ request to re-load a pre-compiled pattern (see "SAVING AND RELOADING
+ COMPILED PATTERNS" below) or, if there is a another < character, as a
pattern that uses < as its delimiter.
DATA LINES
- Before each data line is passed to pcre[16|32]_exec(), leading and
- trailing white space is removed, and it is then scanned for \ escapes.
- Some of these are pretty esoteric features, intended for checking out
- some of the more complicated features of PCRE. If you are just testing
- "ordinary" regular expressions, you probably don't need any of these.
+ Before each data line is passed to pcre[16|32]_exec(), leading and
+ trailing white space is removed, and it is then scanned for \ escapes.
+ Some of these are pretty esoteric features, intended for checking out
+ some of the more complicated features of PCRE. If you are just testing
+ "ordinary" regular expressions, you probably don't need any of these.
The following escapes are recognized:
\a alarm (BEL, \x07)
@@ -669,7 +680,7 @@ DATA LINES
(any number of digits)
\R pass the PCRE_DFA_RESTART option to pcre[16|32]_dfa_exec()
\S output details of memory get/free calls during matching
- \Y pass the PCRE_NO_START_OPTIMIZE option to
+ \Y pass the PCRE_NO_START_OPTIMIZE option to
pcre[16|32]_exec()
or pcre[16|32]_dfa_exec()
\Z pass the PCRE_NOTEOL option to pcre[16|32]_exec()
@@ -678,7 +689,7 @@ DATA LINES
pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
\>dd start the match at offset dd (optional "-"; then
any number of digits); this sets the startoffset
- argument for pcre[16|32]_exec() or
+ argument for pcre[16|32]_exec() or
pcre[16|32]_dfa_exec()
\<cr> pass the PCRE_NEWLINE_CR option to pcre[16|32]_exec()
or pcre[16|32]_dfa_exec()
@@ -691,102 +702,102 @@ DATA LINES
\<any> pass the PCRE_NEWLINE_ANY option to pcre[16|32]_exec()
or pcre[16|32]_dfa_exec()
- The use of \x{hh...} is not dependent on the use of the /8 modifier on
- the pattern. It is recognized always. There may be any number of hexa-
- decimal digits inside the braces; invalid values provoke error mes-
+ The use of \x{hh...} is not dependent on the use of the /8 modifier on
+ the pattern. It is recognized always. There may be any number of hexa-
+ decimal digits inside the braces; invalid values provoke error mes-
sages.
- Note that \xhh specifies one byte rather than one character in UTF-8
- mode; this makes it possible to construct invalid UTF-8 sequences for
- testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
- character in UTF-8 mode, generating more than one byte if the value is
- greater than 127. When testing the 8-bit library not in UTF-8 mode,
+ Note that \xhh specifies one byte rather than one character in UTF-8
+ mode; this makes it possible to construct invalid UTF-8 sequences for
+ testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
+ character in UTF-8 mode, generating more than one byte if the value is
+ greater than 127. When testing the 8-bit library not in UTF-8 mode,
\x{hh} generates one byte for values less than 256, and causes an error
for greater values.
In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it
possible to construct invalid UTF-16 sequences for testing purposes.
- In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This
- makes it possible to construct invalid UTF-32 sequences for testing
+ In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This
+ makes it possible to construct invalid UTF-32 sequences for testing
purposes.
- The escapes that specify line ending sequences are literal strings,
+ The escapes that specify line ending sequences are literal strings,
exactly as shown. No more than one newline setting should be present in
any data line.
- A backslash followed by anything else just escapes the anything else.
- If the very last character is a backslash, it is ignored. This gives a
- way of passing an empty line as data, since a real empty line termi-
+ A backslash followed by anything else just escapes the anything else.
+ If the very last character is a backslash, it is ignored. This gives a
+ way of passing an empty line as data, since a real empty line termi-
nates the data input.
- The \J escape provides a way of setting the maximum stack size that is
- used by the just-in-time optimization code. It is ignored if JIT opti-
- mization is not being used. Providing a stack that is larger than the
+ The \J escape provides a way of setting the maximum stack size that is
+ used by the just-in-time optimization code. It is ignored if JIT opti-
+ mization is not being used. Providing a stack that is larger than the
default 32K is necessary only for very complicated patterns.
If \M is present, pcretest calls pcre[16|32]_exec() several times, with
different values in the match_limit and match_limit_recursion fields of
- the pcre[16|32]_extra data structure, until it finds the minimum num-
+ the pcre[16|32]_extra data structure, until it finds the minimum num-
bers for each parameter that allow pcre[16|32]_exec() to complete with-
- out error. Because this is testing a specific feature of the normal
+ out error. Because this is testing a specific feature of the normal
interpretive pcre[16|32]_exec() execution, the use of any JIT optimiza-
- tion that might have been set up by the /S+ qualifier of -s+ option is
+ tion that might have been set up by the /S+ qualifier of -s+ option is
disabled.
- The match_limit number is a measure of the amount of backtracking that
- takes place, and checking it out can be instructive. For most simple
- matches, the number is quite small, but for patterns with very large
- numbers of matching possibilities, it can become large very quickly
- with increasing length of subject string. The match_limit_recursion
- number is a measure of how much stack (or, if PCRE is compiled with
- NO_RECURSE, how much heap) memory is needed to complete the match
+ The match_limit number is a measure of the amount of backtracking that
+ takes place, and checking it out can be instructive. For most simple
+ matches, the number is quite small, but for patterns with very large
+ numbers of matching possibilities, it can become large very quickly
+ with increasing length of subject string. The match_limit_recursion
+ number is a measure of how much stack (or, if PCRE is compiled with
+ NO_RECURSE, how much heap) memory is needed to complete the match
attempt.
- When \O is used, the value specified may be higher or lower than the
+ When \O is used, the value specified may be higher or lower than the
size set by the -O command line option (or defaulted to 45); \O applies
- only to the call of pcre[16|32]_exec() for the line in which it
+ only to the call of pcre[16|32]_exec() for the line in which it
appears.
- If the /P modifier was present on the pattern, causing the POSIX wrap-
- per API to be used, the only option-setting sequences that have any
- effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and
+ If the /P modifier was present on the pattern, causing the POSIX wrap-
+ per API to be used, the only option-setting sequences that have any
+ effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and
REG_NOTEOL, respectively, to be passed to regexec().
THE ALTERNATIVE MATCHING FUNCTION
- By default, pcretest uses the standard PCRE matching function,
- pcre[16|32]_exec() to match each data line. PCRE also supports an
- alternative matching function, pcre[16|32]_dfa_test(), which operates
- in a different way, and has some restrictions. The differences between
+ By default, pcretest uses the standard PCRE matching function,
+ pcre[16|32]_exec() to match each data line. PCRE also supports an
+ alternative matching function, pcre[16|32]_dfa_test(), which operates
+ in a different way, and has some restrictions. The differences between
the two functions are described in the pcrematching documentation.
- If a data line contains the \D escape sequence, or if the command line
- contains the -dfa option, the alternative matching function is used.
+ If a data line contains the \D escape sequence, or if the command line
+ contains the -dfa option, the alternative matching function is used.
This function finds all possible matches at a given point. If, however,
- the \F escape sequence is present in the data line, it stops after the
+ the \F escape sequence is present in the data line, it stops after the
first match is found. This is always the shortest possible match.
DEFAULT OUTPUT FROM PCRETEST
- This section describes the output when the normal matching function,
+ This section describes the output when the normal matching function,
pcre[16|32]_exec(), is being used.
When a match succeeds, pcretest outputs the list of captured substrings
- that pcre[16|32]_exec() returns, starting with number 0 for the string
- that matched the whole pattern. Otherwise, it outputs "No match" when
- the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the
- partially matching substring when pcre[16|32]_exec() returns
- PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was
- inspected during the partial match; it may include characters before
- the actual match start if a lookbehind assertion, \K, \b, or \B was
- involved.) For any other return, pcretest outputs the PCRE negative
- error number and a short descriptive phrase. If the error is a failed
- UTF string check, the offset of the start of the failing character and
- the reason code are also output, provided that the size of the output
- vector is at least two. Here is an example of an interactive pcretest
+ that pcre[16|32]_exec() returns, starting with number 0 for the string
+ that matched the whole pattern. Otherwise, it outputs "No match" when
+ the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the
+ partially matching substring when pcre[16|32]_exec() returns
+ PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was
+ inspected during the partial match; it may include characters before
+ the actual match start if a lookbehind assertion, \K, \b, or \B was
+ involved.) For any other return, pcretest outputs the PCRE negative
+ error number and a short descriptive phrase. If the error is a failed
+ UTF string check, the offset of the start of the failing character and
+ the reason code are also output, provided that the size of the output
+ vector is at least two. Here is an example of an interactive pcretest
run.
$ pcretest
@@ -800,10 +811,10 @@ DEFAULT OUTPUT FROM PCRETEST
No match
Unset capturing substrings that are not followed by one that is set are
- not returned by pcre[16|32]_exec(), and are not shown by pcretest. In
+ not returned by pcre[16|32]_exec(), and are not shown by pcretest. In
the following example, there are two capturing substrings, but when the
- first data line is matched, the second, unset substring is not shown.
- An "internal" unset substring is shown as "<unset>", as for the second
+ first data line is matched, the second, unset substring is not shown.
+ An "internal" unset substring is shown as "<unset>", as for the second
data line.
re> /(a)|(b)/
@@ -815,11 +826,11 @@ DEFAULT OUTPUT FROM PCRETEST
1: <unset>
2: b
- If the strings contain any non-printing characters, they are output as
- \xhh escapes if the value is less than 256 and UTF mode is not set.
+ If the strings contain any non-printing characters, they are output as
+ \xhh escapes if the value is less than 256 and UTF mode is not set.
Otherwise they are output as \x{hh...} escapes. See below for the defi-
- nition of non-printing characters. If the pattern has the /+ modifier,
- the output for substring 0 is followed by the the rest of the subject
+ nition of non-printing characters. If the pattern has the /+ modifier,
+ the output for substring 0 is followed by the the rest of the subject
string, identified by "0+" like this:
re> /cat/+
@@ -827,7 +838,7 @@ DEFAULT OUTPUT FROM PCRETEST
0: cat
0+ aract
- If the pattern has the /g or /G modifier, the results of successive
+ If the pattern has the /g or /G modifier, the results of successive
matching attempts are output in sequence, like this:
re> /\Bi(\w\w)/g
@@ -839,32 +850,32 @@ DEFAULT OUTPUT FROM PCRETEST
0: ipp
1: pp
- "No match" is output only if the first match attempt fails. Here is an
- example of a failure message (the offset 4 that is specified by \>4 is
+ "No match" is output only if the first match attempt fails. Here is an
+ example of a failure message (the offset 4 that is specified by \>4 is
past the end of the subject string):
re> /xyz/
data> xyz\>4
Error -24 (bad offset value)
- If any of the sequences \C, \G, or \L are present in a data line that
- is successfully matched, the substrings extracted by the convenience
+ If any of the sequences \C, \G, or \L are present in a data line that
+ is successfully matched, the substrings extracted by the convenience
functions are output with C, G, or L after the string number instead of
a colon. This is in addition to the normal full list. The string length
- (that is, the return from the extraction function) is given in paren-
+ (that is, the return from the extraction function) is given in paren-
theses after each string for \C and \G.
Note that whereas patterns can be continued over several lines (a plain
">" prompt is used for continuations), data lines may not. However new-
- lines can be included in data by means of the \n escape (or \r, \r\n,
+ lines can be included in data by means of the \n escape (or \r, \r\n,
etc., depending on the newline sequence setting).
OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
When the alternative matching function, pcre[16|32]_dfa_exec(), is used
- (by means of the \D escape sequence or the -dfa command line option),
- the output consists of a list of all the matches that start at the
+ (by means of the \D escape sequence or the -dfa command line option),
+ the output consists of a list of all the matches that start at the
first point in the subject where there is at least one match. For exam-
ple:
@@ -874,11 +885,11 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
1: tang
2: tan
- (Using the normal matching function on this data finds only "tang".)
- The longest matching string is always given first (and numbered zero).
+ (Using the normal matching function on this data finds only "tang".)
+ The longest matching string is always given first (and numbered zero).
After a PCRE_ERROR_PARTIAL return, the output is "Partial match:", fol-
- lowed by the partially matching substring. (Note that this is the
- entire substring that was inspected during the partial match; it may
+ lowed by the partially matching substring. (Note that this is the
+ entire substring that was inspected during the partial match; it may
include characters before the actual match start if a lookbehind asser-
tion, \K, \b, or \B was involved.)
@@ -894,16 +905,16 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
1: tan
0: tan
- Since the matching function does not support substring capture, the
- escape sequences that are concerned with captured substrings are not
+ Since the matching function does not support substring capture, the
+ escape sequences that are concerned with captured substrings are not
relevant.
RESTARTING AFTER A PARTIAL MATCH
When the alternative matching function has given the PCRE_ERROR_PARTIAL
- return, indicating that the subject partially matched the pattern, you
- can restart the match with additional subject data by means of the \R
+ return, indicating that the subject partially matched the pattern, you
+ can restart the match with additional subject data by means of the \R
escape sequence. For example:
re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
@@ -912,30 +923,30 @@ RESTARTING AFTER A PARTIAL MATCH
data> n05\R\D
0: n05
- For further information about partial matching, see the pcrepartial
+ For further information about partial matching, see the pcrepartial
documentation.
CALLOUTS
- If the pattern contains any callout requests, pcretest's callout func-
- tion is called during matching. This works with both matching func-
+ If the pattern contains any callout requests, pcretest's callout func-
+ tion is called during matching. This works with both matching func-
tions. By default, the called function displays the callout number, the
- start and current positions in the text at the callout time, and the
+ start and current positions in the text at the callout time, and the
next pattern item to be tested. For example:
--->pqrabcdef
0 ^ ^ \d
- This output indicates that callout number 0 occurred for a match
- attempt starting at the fourth character of the subject string, when
+ This output indicates that callout number 0 occurred for a match
+ attempt starting at the fourth character of the subject string, when
the pointer was at the seventh character of the data, and when the next
- pattern item was \d. Just one circumflex is output if the start and
+ pattern item was \d. Just one circumflex is output if the start and
current positions are the same.
Callouts numbered 255 are assumed to be automatic callouts, inserted as
- a result of the /C pattern modifier. In this case, instead of showing
- the callout number, the offset in the pattern, preceded by a plus, is
+ a result of the /C pattern modifier. In this case, instead of showing
+ the callout number, the offset in the pattern, preceded by a plus, is
output. For example:
re> /\d?[A-E]\*/C
@@ -948,7 +959,7 @@ CALLOUTS
0: E*
If a pattern contains (*MARK) items, an additional line is output when-
- ever a change of latest mark is passed to the callout function. For
+ ever a change of latest mark is passed to the callout function. For
example:
re> /a(*MARK:X)bc/C
@@ -962,104 +973,104 @@ CALLOUTS
+12 ^ ^
0: abc
- The mark changes between matching "a" and "b", but stays the same for
- the rest of the match, so nothing more is output. If, as a result of
- backtracking, the mark reverts to being unset, the text "<unset>" is
+ The mark changes between matching "a" and "b", but stays the same for
+ the rest of the match, so nothing more is output. If, as a result of
+ backtracking, the mark reverts to being unset, the text "<unset>" is
output.
- The callout function in pcretest returns zero (carry on matching) by
- default, but you can use a \C item in a data line (as described above)
+ The callout function in pcretest returns zero (carry on matching) by
+ default, but you can use a \C item in a data line (as described above)
to change this and other parameters of the callout.
- Inserting callouts can be helpful when using pcretest to check compli-
- cated regular expressions. For further information about callouts, see
+ Inserting callouts can be helpful when using pcretest to check compli-
+ cated regular expressions. For further information about callouts, see
the pcrecallout documentation.
NON-PRINTING CHARACTERS
- When pcretest is outputting text in the compiled version of a pattern,
- bytes other than 32-126 are always treated as non-printing characters
+ When pcretest is outputting text in the compiled version of a pattern,
+ bytes other than 32-126 are always treated as non-printing characters
are are therefore shown as hex escapes.
- When pcretest is outputting text that is a matched part of a subject
- string, it behaves in the same way, unless a different locale has been
- set for the pattern (using the /L modifier). In this case, the
+ When pcretest is outputting text that is a matched part of a subject
+ string, it behaves in the same way, unless a different locale has been
+ set for the pattern (using the /L modifier). In this case, the
isprint() function to distinguish printing and non-printing characters.
SAVING AND RELOADING COMPILED PATTERNS
- The facilities described in this section are not available when the
- POSIX interface to PCRE is being used, that is, when the /P pattern
+ The facilities described in this section are not available when the
+ POSIX interface to PCRE is being used, that is, when the /P pattern
modifier is specified.
When the POSIX interface is not in use, you can cause pcretest to write
- a compiled pattern to a file, by following the modifiers with > and a
+ a compiled pattern to a file, by following the modifiers with > and a
file name. For example:
/pattern/im >/some/file
- See the pcreprecompile documentation for a discussion about saving and
- re-using compiled patterns. Note that if the pattern was successfully
+ See the pcreprecompile documentation for a discussion about saving and
+ re-using compiled patterns. Note that if the pattern was successfully
studied with JIT optimization, the JIT data cannot be saved.
- The data that is written is binary. The first eight bytes are the
- length of the compiled pattern data followed by the length of the
- optional study data, each written as four bytes in big-endian order
- (most significant byte first). If there is no study data (either the
+ The data that is written is binary. The first eight bytes are the
+ length of the compiled pattern data followed by the length of the
+ optional study data, each written as four bytes in big-endian order
+ (most significant byte first). If there is no study data (either the
pattern was not studied, or studying did not return any data), the sec-
- ond length is zero. The lengths are followed by an exact copy of the
- compiled pattern. If there is additional study data, this (excluding
- any JIT data) follows immediately after the compiled pattern. After
+ ond length is zero. The lengths are followed by an exact copy of the
+ compiled pattern. If there is additional study data, this (excluding
+ any JIT data) follows immediately after the compiled pattern. After
writing the file, pcretest expects to read a new pattern.
- A saved pattern can be reloaded into pcretest by specifying < and a
- file name instead of a pattern. There must be no space between < and
- the file name, which must not contain a < character, as otherwise
- pcretest will interpret the line as a pattern delimited by < charac-
+ A saved pattern can be reloaded into pcretest by specifying < and a
+ file name instead of a pattern. There must be no space between < and
+ the file name, which must not contain a < character, as otherwise
+ pcretest will interpret the line as a pattern delimited by < charac-
ters. For example:
re> </some/file
Compiled pattern loaded from /some/file
No study data
- If the pattern was previously studied with the JIT optimization, the
- JIT information cannot be saved and restored, and so is lost. When the
- pattern has been loaded, pcretest proceeds to read data lines in the
+ If the pattern was previously studied with the JIT optimization, the
+ JIT information cannot be saved and restored, and so is lost. When the
+ pattern has been loaded, pcretest proceeds to read data lines in the
usual way.
- You can copy a file written by pcretest to a different host and reload
- it there, even if the new host has opposite endianness to the one on
- which the pattern was compiled. For example, you can compile on an i86
- machine and run on a SPARC machine. When a pattern is reloaded on a
+ You can copy a file written by pcretest to a different host and reload
+ it there, even if the new host has opposite endianness to the one on
+ which the pattern was compiled. For example, you can compile on an i86
+ machine and run on a SPARC machine. When a pattern is reloaded on a
host with different endianness, the confirmation message is changed to:
Compiled pattern (byte-inverted) loaded from /some/file
The test suite contains some saved pre-compiled patterns with different
- endianness. These are reloaded using "<!" instead of just "<". This
+ endianness. These are reloaded using "<!" instead of just "<". This
suppresses the "(byte-inverted)" text so that the output is the same on
- all hosts. It also forces debugging output once the pattern has been
+ all hosts. It also forces debugging output once the pattern has been
reloaded.
- File names for saving and reloading can be absolute or relative, but
- note that the shell facility of expanding a file name that starts with
+ File names for saving and reloading can be absolute or relative, but
+ note that the shell facility of expanding a file name that starts with
a tilde (~) is not available.
- The ability to save and reload files in pcretest is intended for test-
- ing and experimentation. It is not intended for production use because
- only a single pattern can be written to a file. Furthermore, there is
- no facility for supplying custom character tables for use with a
- reloaded pattern. If the original pattern was compiled with custom
- tables, an attempt to match a subject string using a reloaded pattern
- is likely to cause pcretest to crash. Finally, if you attempt to load
+ The ability to save and reload files in pcretest is intended for test-
+ ing and experimentation. It is not intended for production use because
+ only a single pattern can be written to a file. Furthermore, there is
+ no facility for supplying custom character tables for use with a
+ reloaded pattern. If the original pattern was compiled with custom
+ tables, an attempt to match a subject string using a reloaded pattern
+ is likely to cause pcretest to crash. Finally, if you attempt to load
a file that is not in the correct format, the result is undefined.
SEE ALSO
- pcre(3), pcre16(3), pcre32(3), pcreapi(3), pcrecallout(3), pcrejit,
+ pcre(3), pcre16(3), pcre32(3), pcreapi(3), pcrecallout(3), pcrejit,
pcrematching(3), pcrepartial(d), pcrepattern(3), pcreprecompile(3).
@@ -1072,5 +1083,5 @@ AUTHOR
REVISION
- Last updated: 12 November 2013
- Copyright (c) 1997-2013 University of Cambridge.
+ Last updated: 09 February 2014
+ Copyright (c) 1997-2014 University of Cambridge.
diff --git a/pcre/maria-patches/pcre_stack_guard.diff b/pcre/maria-patches/pcre_stack_guard.diff
deleted file mode 100644
index 8cf4b7dbb34..00000000000
--- a/pcre/maria-patches/pcre_stack_guard.diff
+++ /dev/null
@@ -1,57 +0,0 @@
-=== modified file 'pcre/pcre.h.in'
---- pcre/pcre.h.in 2013-09-26 14:02:17 +0000
-+++ pcre/pcre.h.in 2013-10-02 07:58:29 +0000
-@@ -486,6 +486,7 @@ PCRE_EXP_DECL void (*pcre_free)(void *)
- PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
- PCRE_EXP_DECL void (*pcre_stack_free)(void *);
- PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
-+PCRE_EXP_DECL int (*pcre_stack_guard)(void);
-
- PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
- PCRE_EXP_DECL void (*pcre16_free)(void *);
-@@ -504,6 +505,7 @@ PCRE_EXP_DECL void pcre_free(void *);
- PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
- PCRE_EXP_DECL void pcre_stack_free(void *);
- PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
-+PCRE_EXP_DECL int pcre_stack_guard(void);
-
- PCRE_EXP_DECL void *pcre16_malloc(size_t);
- PCRE_EXP_DECL void pcre16_free(void *);
-
-=== modified file 'pcre/pcre_compile.c'
---- pcre/pcre_compile.c 2013-09-26 14:02:17 +0000
-+++ pcre/pcre_compile.c 2013-10-02 07:58:29 +0000
-@@ -7107,6 +7107,12 @@ unsigned int orig_bracount;
- unsigned int max_bracount;
- branch_chain bc;
-
-+if (pcre_stack_guard && pcre_stack_guard())
-+{
-+ *errorcodeptr= ERR23;
-+ return FALSE;
-+}
-+
- bc.outer = bcptr;
- bc.current_branch = code;
-
-
-=== modified file 'pcre/pcre_globals.c'
---- pcre/pcre_globals.c 2013-09-26 14:02:17 +0000
-+++ pcre/pcre_globals.c 2013-10-02 07:58:29 +0000
-@@ -72,6 +72,7 @@ PCRE_EXP_DATA_DEFN void (*PUBL(free))(v
- PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc;
- PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
- PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-+PCRE_EXP_DATA_DEFN int (*PUBL(stack_guard))(void) = NULL;
-
- #elif !defined VPCOMPAT
- PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc;
-@@ -79,6 +80,7 @@ PCRE_EXP_DATA_DEFN void (*PUBL(free))(v
- PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc;
- PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free;
- PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-+PCRE_EXP_DATA_DEFN int (*PUBL(stack_guard))(void) = NULL;
- #endif
-
- /* End of pcre_globals.c */
-
diff --git a/pcre/pcre.h.in b/pcre/pcre.h.in
index 45cd875dd56..667a45ed575 100644
--- a/pcre/pcre.h.in
+++ b/pcre/pcre.h.in
@@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, to be #included by
applications that call the PCRE functions.
- Copyright (c) 1997-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -498,12 +498,14 @@ PCRE_EXP_DECL void (*pcre16_free)(void *);
PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
+PCRE_EXP_DECL int (*pcre16_stack_guard)(void);
PCRE_EXP_DECL void *(*pcre32_malloc)(size_t);
PCRE_EXP_DECL void (*pcre32_free)(void *);
PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre32_stack_free)(void *);
PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *);
+PCRE_EXP_DECL int (*pcre32_stack_guard)(void);
#else /* VPCOMPAT */
PCRE_EXP_DECL void *pcre_malloc(size_t);
PCRE_EXP_DECL void pcre_free(void *);
@@ -517,12 +519,14 @@ PCRE_EXP_DECL void pcre16_free(void *);
PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
PCRE_EXP_DECL void pcre16_stack_free(void *);
PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
+PCRE_EXP_DECL int pcre16_stack_guard(void);
PCRE_EXP_DECL void *pcre32_malloc(size_t);
PCRE_EXP_DECL void pcre32_free(void *);
PCRE_EXP_DECL void *pcre32_stack_malloc(size_t);
PCRE_EXP_DECL void pcre32_stack_free(void *);
PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *);
+PCRE_EXP_DECL int pcre32_stack_guard(void);
#endif /* VPCOMPAT */
/* User defined callback which provides a stack just before the match starts. */
diff --git a/pcre/pcre_byte_order.c b/pcre/pcre_byte_order.c
index 01cbca36ffe..cf5f12b04ea 100644
--- a/pcre/pcre_byte_order.c
+++ b/pcre/pcre_byte_order.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-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -311,9 +311,9 @@ while(TRUE)
ptr++;
}
/* Control should never reach here in 16/32 bit mode. */
-#endif /* !COMPILE_PCRE8 */
-
+#else /* In 8-bit mode, the pattern does not need to be processed. */
return 0;
+#endif /* !COMPILE_PCRE8 */
}
/* End of pcre_byte_order.c */
diff --git a/pcre/pcre_chartables.c b/pcre/pcre_chartables.c
deleted file mode 100644
index 1e20ec29d05..00000000000
--- a/pcre/pcre_chartables.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This file contains character tables that are used when no external tables
-are passed to PCRE by the application that calls it. The tables are used only
-for characters whose code values are less than 256.
-
-This is a default version of the tables that assumes ASCII encoding. A program
-called dftables (which is distributed with PCRE) can be used to build
-alternative versions of this file. This is necessary if you are running in an
-EBCDIC environment, or if you want to default to a different encoding, for
-example ISO-8859-1. When dftables is run, it creates these tables in the
-current locale. If PCRE is configured with --enable-rebuild-chartables, this
-happens automatically.
-
-The following #includes are present because without them gcc 4.x may remove the
-array definition from the final binary if PCRE is built into a static library
-and dead code stripping is activated. This leads to link errors. Pulling in the
-header ensures that the array gets flagged as "someone outside this compilation
-unit might reference this" and so it will always be supplied to the linker. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-const pcre_uint8 PRIV(default_tables)[] = {
-
-/* This table is a lower casing table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table is a case flipping table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table contains bit maps for various character classes. Each map is 32
-bytes long and the bits run from the least significant end of each byte. The
-classes that have their own maps are: space, xdigit, digit, upper, lower, word,
-graph, print, punct, and cntrl. Other classes are built from combinations. */
-
- 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
- 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-/* This table identifies various classes of character by individual bits:
- 0x01 white space character
- 0x02 letter
- 0x04 decimal digit
- 0x08 hexadecimal digit
- 0x10 alphanumeric or '_'
- 0x80 regular expression metacharacter or binary zero
-*/
-
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
- 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-/* End of pcre_chartables.c */
diff --git a/pcre/pcre_compile.c b/pcre/pcre_compile.c
index cdc7f95304a..8a5b7233479 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-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -547,6 +547,8 @@ static const char error_texts[] =
"parentheses are too deeply nested\0"
"invalid range in character class\0"
"group name must start with a non-digit\0"
+ /* 85 */
+ "parentheses are too deeply nested (stack check)\0"
;
/* Table to identify digits and hex digits. This is used when compiling
@@ -3070,8 +3072,11 @@ const pcre_uint32 *chr_ptr;
const pcre_uint32 *ochr_ptr;
const pcre_uint32 *list_ptr;
const pcre_uchar *next_code;
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+const pcre_uchar *xclass_flags;
+#endif
const pcre_uint8 *class_bitset;
-const pcre_uint32 *set1, *set2, *set_end;
+const pcre_uint8 *set1, *set2, *set_end;
pcre_uint32 chr;
BOOL accepted, invert_bits;
@@ -3202,12 +3207,12 @@ for(;;)
if (base_list[0] == OP_CLASS)
#endif
{
- set1 = (pcre_uint32 *)(base_end - base_list[2]);
+ set1 = (pcre_uint8 *)(base_end - base_list[2]);
list_ptr = list;
}
else
{
- set1 = (pcre_uint32 *)(code - list[2]);
+ set1 = (pcre_uint8 *)(code - list[2]);
list_ptr = base_list;
}
@@ -3216,41 +3221,53 @@ for(;;)
{
case OP_CLASS:
case OP_NCLASS:
- set2 = (pcre_uint32 *)
+ set2 = (pcre_uint8 *)
((list_ptr == list ? code : base_end) - list_ptr[2]);
break;
- /* OP_XCLASS cannot be supported here, because its bitset
- is not necessarily complete. E.g: [a-\0x{200}] is stored
- as a character range, and the appropriate bits are not set. */
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE;
+ if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE;
+ if ((*xclass_flags & XCL_MAP) == 0)
+ {
+ /* No bits are set for characters < 256. */
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+ set2 = (pcre_uint8 *)(xclass_flags + 1);
+ break;
+#endif
case OP_NOT_DIGIT:
- invert_bits = TRUE;
- /* Fall through */
+ invert_bits = TRUE;
+ /* Fall through */
case OP_DIGIT:
- set2 = (pcre_uint32 *)(cd->cbits + cbit_digit);
- break;
+ set2 = (pcre_uint8 *)(cd->cbits + cbit_digit);
+ break;
case OP_NOT_WHITESPACE:
- invert_bits = TRUE;
- /* Fall through */
+ invert_bits = TRUE;
+ /* Fall through */
case OP_WHITESPACE:
- set2 = (pcre_uint32 *)(cd->cbits + cbit_space);
- break;
+ set2 = (pcre_uint8 *)(cd->cbits + cbit_space);
+ break;
case OP_NOT_WORDCHAR:
- invert_bits = TRUE;
- /* Fall through */
+ invert_bits = TRUE;
+ /* Fall through */
case OP_WORDCHAR:
- set2 = (pcre_uint32 *)(cd->cbits + cbit_word);
- break;
+ set2 = (pcre_uint8 *)(cd->cbits + cbit_word);
+ break;
default:
return FALSE;
}
- /* Compare 4 bytes to improve speed. */
- set_end = set1 + (32 / 4);
+ /* Because the sets are unaligned, we need
+ to perform byte comparison here. */
+ set_end = set1 + 32;
if (invert_bits)
{
do
@@ -3551,7 +3568,9 @@ for(;;)
if (list[1] == 0) return TRUE;
}
-return FALSE;
+/* Control never reaches here. There used to be a fail-save return FALSE; here,
+but some compilers complain about an unreachable statement. */
+
}
@@ -3623,7 +3642,7 @@ for (;;)
break;
case OP_MINUPTO:
- *code += OP_MINUPTO - OP_UPTO;
+ *code += OP_POSUPTO - OP_MINUPTO;
break;
}
}
@@ -4062,12 +4081,16 @@ for (c = *cptr; c <= d; c++)
if (c > d) return -1; /* Reached end of range */
+/* Found a character that has a single other case. Search for the end of the
+range, which is either the end of the input range, or a character that has zero
+or more than one other cases. */
+
*ocptr = othercase;
next = othercase + 1;
for (++c; c <= d; c++)
{
- if (UCD_OTHERCASE(c) != next) break;
+ if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break;
next++;
}
@@ -4105,6 +4128,7 @@ add_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options,
compile_data *cd, pcre_uint32 start, pcre_uint32 end)
{
pcre_uint32 c;
+pcre_uint32 classbits_end = (end <= 0xff ? end : 0xff);
int n8 = 0;
/* If caseless matching is required, scan the range and process alternate
@@ -4148,7 +4172,7 @@ if ((options & PCRE_CASELESS) != 0)
/* Not UTF-mode, or no UCP */
- for (c = start; c <= end && c < 256; c++)
+ for (c = start; c <= classbits_end; c++)
{
SETBIT(classbits, cd->fcc[c]);
n8++;
@@ -4173,22 +4197,21 @@ in all cases. */
#endif /* COMPILE_PCRE[8|16] */
-/* If all characters are less than 256, use the bit map. Otherwise use extra
-data. */
+/* Use the bitmap for characters < 256. Otherwise use extra data.*/
-if (end < 0x100)
+for (c = start; c <= classbits_end; c++)
{
- for (c = start; c <= end; c++)
- {
- n8++;
- SETBIT(classbits, c);
- }
+ /* Regardless of start, c will always be <= 255. */
+ SETBIT(classbits, c);
+ n8++;
}
-else
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+if (start <= 0xff) start = 0xff + 1;
+
+if (end >= start)
{
pcre_uchar *uchardata = *uchardptr;
-
#ifdef SUPPORT_UTF
if ((options & PCRE_UTF8) != 0) /* All UTFs use the same flag bit */
{
@@ -4228,6 +4251,7 @@ else
*uchardptr = uchardata; /* Updata extra data pointer */
}
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
return n8; /* Number of 8-bit characters */
}
@@ -4449,6 +4473,9 @@ for (;; ptr++)
BOOL reset_bracount;
int class_has_8bitchar;
int class_one_char;
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ BOOL xclass_has_prop;
+#endif
int newoptions;
int recno;
int refsign;
@@ -4703,12 +4730,6 @@ for (;; ptr++)
goto FAILED;
}
goto NORMAL_CHAR;
-
- /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
- used for "start of word" and "end of word". As these are otherwise illegal
- sequences, we don't break anything by recognizing them. They are replaced
- by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are
- erroneous and are handled by the normal code below. */
/* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
used for "start of word" and "end of word". As these are otherwise illegal
@@ -4789,13 +4810,26 @@ for (;; ptr++)
should_flip_negation = FALSE;
+ /* Extended class (xclass) will be used when characters > 255
+ might match. */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ xclass = FALSE;
+ class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */
+ class_uchardata_base = class_uchardata; /* Save the start */
+#endif
+
/* For optimization purposes, we track some properties of the class:
class_has_8bitchar will be non-zero if the class contains at least one <
256 character; class_one_char will be 1 if the class contains just one
- character. */
+ character; xclass_has_prop will be TRUE if unicode property checks
+ are present in the class. */
class_has_8bitchar = 0;
class_one_char = 0;
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ xclass_has_prop = FALSE;
+#endif
/* Initialize the 32-char bit map to all zeros. We build the map in a
temporary bit of memory, in case the class contains fewer than two
@@ -4804,12 +4838,6 @@ for (;; ptr++)
memset(classbits, 0, 32 * sizeof(pcre_uint8));
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- xclass = FALSE;
- class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */
- class_uchardata_base = class_uchardata; /* Save the start */
-#endif
-
/* Process characters until ] is reached. By writing this as a "do" it
means that an initial ] is taken as a data character. At the start of the
loop, c contains the first byte of the character. */
@@ -4933,6 +4961,7 @@ for (;; ptr++)
*class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
*class_uchardata++ = ptype;
*class_uchardata++ = 0;
+ xclass_has_prop = TRUE;
ptr = tempptr + 1;
continue;
@@ -5115,6 +5144,7 @@ for (;; ptr++)
XCL_PROP : XCL_NOTPROP;
*class_uchardata++ = ptype;
*class_uchardata++ = pdata;
+ xclass_has_prop = TRUE;
class_has_8bitchar--; /* Undo! */
continue;
}
@@ -5409,6 +5439,7 @@ for (;; ptr++)
*code++ = OP_XCLASS;
code += LINK_SIZE;
*code = negate_class? XCL_NOT:0;
+ if (xclass_has_prop) *code |= XCL_HASPROP;
/* If the map is required, move up the extra data to make room for it;
otherwise just move the code pointer to the end of the extra data. */
@@ -5418,6 +5449,8 @@ for (;; ptr++)
*code++ |= XCL_MAP;
memmove(code + (32 / sizeof(pcre_uchar)), code,
IN_UCHARS(class_uchardata - code));
+ if (negate_class && !xclass_has_prop)
+ for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
memcpy(code, classbits, 32);
code = class_uchardata + (32 / sizeof(pcre_uchar));
}
@@ -6586,7 +6619,10 @@ for (;; ptr++)
code[1+LINK_SIZE] = OP_CREF;
skipbytes = 1+IMM2_SIZE;
- refsign = -1;
+ refsign = -1; /* => not a number */
+ namelen = -1; /* => not a name; must set to avoid warning */
+ name = NULL; /* Always set to avoid warning */
+ recno = 0; /* Always set to avoid warning */
/* Check for a test for recursion in a named group. */
@@ -6623,7 +6659,6 @@ for (;; ptr++)
if (refsign >= 0)
{
- recno = 0;
while (IS_DIGIT(*ptr))
{
recno = recno * 10 + (int)(*ptr - CHAR_0);
@@ -8000,12 +8035,16 @@ unsigned int orig_bracount;
unsigned int max_bracount;
branch_chain bc;
-if (pcre_stack_guard && pcre_stack_guard())
-{
- *errorcodeptr= ERR23;
+/* If set, call the external function that checks for stack availability. */
+
+if (PUBL(stack_guard) != NULL && PUBL(stack_guard)())
+ {
+ *errorcodeptr= ERR85;
return FALSE;
-}
-
+ }
+
+/* Miscellaneous initialization */
+
bc.outer = bcptr;
bc.current_branch = code;
diff --git a/pcre/pcre_dfa_exec.c b/pcre/pcre_dfa_exec.c
index 4cbcf9106c4..fb0c7e805dc 100644
--- a/pcre/pcre_dfa_exec.c
+++ b/pcre/pcre_dfa_exec.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language (but see
below for why this module is different).
Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -1473,7 +1473,7 @@ for (;;)
goto ANYNL01;
case CHAR_CR:
- if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
+ if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
/* Fall through */
ANYNL01:
@@ -1742,7 +1742,7 @@ for (;;)
goto ANYNL02;
case CHAR_CR:
- if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
+ if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
/* Fall through */
ANYNL02:
@@ -2012,7 +2012,7 @@ for (;;)
goto ANYNL03;
case CHAR_CR:
- if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
+ if (ptr + 1 < end_subject && UCHAR21TEST(ptr + 1) == CHAR_LF) ncount = 1;
/* Fall through */
ANYNL03:
@@ -2210,7 +2210,7 @@ for (;;)
if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
reset_could_continue = TRUE;
}
- else if (RAWUCHARTEST(ptr + 1) == CHAR_LF)
+ else if (UCHAR21TEST(ptr + 1) == CHAR_LF)
{
ADD_NEW_DATA(-(state_offset + 1), 0, 1);
}
@@ -3466,7 +3466,7 @@ for (;;)
if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
{
- /* Advance to a known first char. */
+ /* Advance to a known first pcre_uchar (i.e. data item) */
if (has_first_char)
{
@@ -3474,12 +3474,12 @@ for (;;)
{
pcre_uchar csc;
while (current_subject < end_subject &&
- (csc = RAWUCHARTEST(current_subject)) != first_char && csc != first_char2)
+ (csc = UCHAR21TEST(current_subject)) != first_char && csc != first_char2)
current_subject++;
}
else
while (current_subject < end_subject &&
- RAWUCHARTEST(current_subject) != first_char)
+ UCHAR21TEST(current_subject) != first_char)
current_subject++;
}
@@ -3509,36 +3509,26 @@ for (;;)
ANYCRLF, and we are now at a LF, advance the match position by one
more character. */
- if (RAWUCHARTEST(current_subject - 1) == CHAR_CR &&
+ if (UCHAR21TEST(current_subject - 1) == CHAR_CR &&
(md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
current_subject < end_subject &&
- RAWUCHARTEST(current_subject) == CHAR_NL)
+ UCHAR21TEST(current_subject) == CHAR_NL)
current_subject++;
}
}
- /* Or to a non-unique first char after study */
+ /* Advance to a non-unique first pcre_uchar after study */
else if (start_bits != NULL)
{
while (current_subject < end_subject)
{
- register pcre_uint32 c = RAWUCHARTEST(current_subject);
+ register pcre_uint32 c = UCHAR21TEST(current_subject);
#ifndef COMPILE_PCRE8
if (c > 255) c = 255;
#endif
- if ((start_bits[c/8] & (1 << (c&7))) == 0)
- {
- current_subject++;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- /* In non 8-bit mode, the iteration will stop for
- characters > 255 at the beginning or not stop at all. */
- if (utf)
- ACROSSCHAR(current_subject < end_subject, *current_subject,
- current_subject++);
-#endif
- }
- else break;
+ if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
+ current_subject++;
}
}
}
@@ -3557,19 +3547,20 @@ for (;;)
/* If the pattern was studied, a minimum subject length may be set. This
is a lower bound; no actual string of that length may actually match the
pattern. Although the value is, strictly, in characters, we treat it as
- bytes to avoid spending too much time in this optimization. */
+ in pcre_uchar units to avoid spending too much time in this optimization.
+ */
if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
(pcre_uint32)(end_subject - current_subject) < study->minlength)
return PCRE_ERROR_NOMATCH;
- /* If req_char is set, we know that that character must appear in the
- subject for the match to succeed. If the first character is set, req_char
- must be later in the subject; otherwise the test starts at the match
- point. This optimization can save a huge amount of work in patterns with
- nested unlimited repeats that aren't going to match. Writing separate
- code for cased/caseless versions makes it go faster, as does using an
- autoincrement and backing off on a match.
+ /* If req_char is set, we know that that pcre_uchar must appear in the
+ subject for the match to succeed. If the first pcre_uchar is set,
+ req_char must be later in the subject; otherwise the test starts at the
+ match point. This optimization can save a huge amount of work in patterns
+ with nested unlimited repeats that aren't going to match. Writing
+ separate code for cased/caseless versions makes it go faster, as does
+ using an autoincrement and backing off on a match.
HOWEVER: when the subject string is very, very long, searching to its end
can take a long time, and give bad performance on quite ordinary
@@ -3589,7 +3580,7 @@ for (;;)
{
while (p < end_subject)
{
- register pcre_uint32 pp = RAWUCHARINCTEST(p);
+ register pcre_uint32 pp = UCHAR21INCTEST(p);
if (pp == req_char || pp == req_char2) { p--; break; }
}
}
@@ -3597,18 +3588,18 @@ for (;;)
{
while (p < end_subject)
{
- if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
+ if (UCHAR21INCTEST(p) == req_char) { p--; break; }
}
}
- /* If we can't find the required character, break the matching loop,
+ /* If we can't find the required pcre_uchar, break the matching loop,
which will cause a return or PCRE_ERROR_NOMATCH. */
if (p >= end_subject) break;
- /* If we have found the required character, save the point where we
+ /* If we have found the required pcre_uchar, save the point where we
found it, so that we don't search again next time round the loop if
- the start hasn't passed this character yet. */
+ the start hasn't passed this point yet. */
req_char_ptr = p;
}
@@ -3665,9 +3656,9 @@ for (;;)
not contain any explicit matches for \r or \n, and the newline option is CRLF
or ANY or ANYCRLF, advance the match position by one more character. */
- if (RAWUCHARTEST(current_subject - 1) == CHAR_CR &&
+ if (UCHAR21TEST(current_subject - 1) == CHAR_CR &&
current_subject < end_subject &&
- RAWUCHARTEST(current_subject) == CHAR_NL &&
+ UCHAR21TEST(current_subject) == CHAR_NL &&
(re->flags & PCRE_HASCRORLF) == 0 &&
(md->nltype == NLTYPE_ANY ||
md->nltype == NLTYPE_ANYCRLF ||
diff --git a/pcre/pcre_exec.c b/pcre/pcre_exec.c
index a3f0c1923f2..5dec99234a9 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-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -134,7 +134,7 @@ pcre_uint32 c;
BOOL utf = md->utf;
if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
while (length-- > 0)
- if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c);
+ if (isprint(c = UCHAR21INCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c);
}
#endif
@@ -237,8 +237,8 @@ if (caseless)
{
pcre_uint32 cc, cp;
if (eptr >= md->end_subject) return -2; /* Partial match */
- cc = RAWUCHARTEST(eptr);
- cp = RAWUCHARTEST(p);
+ cc = UCHAR21TEST(eptr);
+ cp = UCHAR21TEST(p);
if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1;
p++;
eptr++;
@@ -254,7 +254,7 @@ else
while (length-- > 0)
{
if (eptr >= md->end_subject) return -2; /* Partial match */
- if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1;
+ if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1;
}
}
@@ -2103,7 +2103,7 @@ for (;;)
eptr + 1 >= md->end_subject &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
- RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
+ UCHAR21TEST(eptr) == NLBLOCK->nl[0])
{
md->hitend = TRUE;
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
@@ -2147,7 +2147,7 @@ for (;;)
eptr + 1 >= md->end_subject &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
- RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
+ UCHAR21TEST(eptr) == NLBLOCK->nl[0])
{
md->hitend = TRUE;
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
@@ -2290,7 +2290,7 @@ for (;;)
eptr + 1 >= md->end_subject &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
- RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
+ UCHAR21TEST(eptr) == NLBLOCK->nl[0])
{
md->hitend = TRUE;
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
@@ -2444,7 +2444,7 @@ for (;;)
{
SCHECK_PARTIAL();
}
- else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++;
+ else if (UCHAR21TEST(eptr) == CHAR_LF) eptr++;
break;
case CHAR_LF:
@@ -2691,16 +2691,22 @@ for (;;)
pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
ecode += 1 + 2*IMM2_SIZE;
+ /* Setting the default length first and initializing 'offset' avoids
+ compiler warnings in the REF_REPEAT code. */
+
+ length = (md->jscript_compat)? 0 : -1;
+ offset = 0;
+
while (count-- > 0)
{
offset = GET2(slot, 0) << 1;
- if (offset < offset_top && md->offset_vector[offset] >= 0) break;
+ if (offset < offset_top && md->offset_vector[offset] >= 0)
+ {
+ length = md->offset_vector[offset+1] - md->offset_vector[offset];
+ break;
+ }
slot += md->name_entry_size;
}
- if (count < 0)
- length = (md->jscript_compat)? 0 : -1;
- else
- length = md->offset_vector[offset+1] - md->offset_vector[offset];
}
goto REF_REPEAT;
@@ -3212,7 +3218,7 @@ for (;;)
CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
RRETURN(MATCH_NOMATCH);
}
- while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH);
+ while (length-- > 0) if (*ecode++ != UCHAR21INC(eptr)) RRETURN(MATCH_NOMATCH);
}
else
#endif
@@ -3252,7 +3258,7 @@ for (;;)
if (fc < 128)
{
- pcre_uint32 cc = RAWUCHAR(eptr);
+ pcre_uint32 cc = UCHAR21(eptr);
if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
ecode++;
eptr++;
@@ -3521,7 +3527,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHARTEST(eptr);
+ cc = UCHAR21TEST(eptr);
if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
eptr++;
}
@@ -3539,7 +3545,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHARTEST(eptr);
+ cc = UCHAR21TEST(eptr);
if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
eptr++;
}
@@ -3556,7 +3562,7 @@ for (;;)
SCHECK_PARTIAL();
break;
}
- cc = RAWUCHARTEST(eptr);
+ cc = UCHAR21TEST(eptr);
if (fc != cc && foc != cc) break;
eptr++;
}
@@ -3583,7 +3589,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
+ if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH);
}
if (min == max) continue;
@@ -3600,7 +3606,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
+ if (fc != UCHAR21INCTEST(eptr)) RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
}
@@ -3614,7 +3620,7 @@ for (;;)
SCHECK_PARTIAL();
break;
}
- if (fc != RAWUCHARTEST(eptr)) break;
+ if (fc != UCHAR21TEST(eptr)) break;
eptr++;
}
if (possessive) continue; /* No backtracking */
@@ -4369,7 +4375,7 @@ for (;;)
eptr + 1 >= md->end_subject &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
- RAWUCHAR(eptr) == NLBLOCK->nl[0])
+ UCHAR21(eptr) == NLBLOCK->nl[0])
{
md->hitend = TRUE;
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
@@ -4411,7 +4417,7 @@ for (;;)
default: RRETURN(MATCH_NOMATCH);
case CHAR_CR:
- if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
+ if (eptr < md->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++;
break;
case CHAR_LF:
@@ -4521,7 +4527,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHAR(eptr);
+ cc = UCHAR21(eptr);
if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@@ -4538,7 +4544,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHAR(eptr);
+ cc = UCHAR21(eptr);
if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@@ -4555,7 +4561,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHAR(eptr);
+ cc = UCHAR21(eptr);
if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@@ -4572,7 +4578,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHAR(eptr);
+ cc = UCHAR21(eptr);
if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@@ -4589,7 +4595,7 @@ for (;;)
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
- cc = RAWUCHAR(eptr);
+ cc = UCHAR21(eptr);
if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
RRETURN(MATCH_NOMATCH);
eptr++;
@@ -5150,7 +5156,7 @@ for (;;)
{
default: RRETURN(MATCH_NOMATCH);
case CHAR_CR:
- if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
+ if (eptr < md->end_subject && UCHAR21(eptr) == CHAR_LF) eptr++;
break;
case CHAR_LF:
@@ -5689,7 +5695,7 @@ for (;;)
eptr + 1 >= md->end_subject &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
- RAWUCHAR(eptr) == NLBLOCK->nl[0])
+ UCHAR21(eptr) == NLBLOCK->nl[0])
{
md->hitend = TRUE;
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
@@ -5715,7 +5721,7 @@ for (;;)
eptr + 1 >= md->end_subject &&
NLBLOCK->nltype == NLTYPE_FIXED &&
NLBLOCK->nllen == 2 &&
- RAWUCHAR(eptr) == NLBLOCK->nl[0])
+ UCHAR21(eptr) == NLBLOCK->nl[0])
{
md->hitend = TRUE;
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
@@ -5772,7 +5778,7 @@ for (;;)
if (c == CHAR_CR)
{
if (++eptr >= md->end_subject) break;
- if (RAWUCHAR(eptr) == CHAR_LF) eptr++;
+ if (UCHAR21(eptr) == CHAR_LF) eptr++;
}
else
{
@@ -5935,8 +5941,8 @@ for (;;)
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
BACKCHAR(eptr);
- if (ctype == OP_ANYNL && eptr > pp && RAWUCHAR(eptr) == CHAR_NL &&
- RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
+ if (ctype == OP_ANYNL && eptr > pp && UCHAR21(eptr) == CHAR_NL &&
+ UCHAR21(eptr - 1) == CHAR_CR) eptr--;
}
}
else
@@ -6783,10 +6789,10 @@ for(;;)
if (first_char != first_char2)
while (start_match < end_subject &&
- (smc = RAWUCHARTEST(start_match)) != first_char && smc != first_char2)
+ (smc = UCHAR21TEST(start_match)) != first_char && smc != first_char2)
start_match++;
else
- while (start_match < end_subject && RAWUCHARTEST(start_match) != first_char)
+ while (start_match < end_subject && UCHAR21TEST(start_match) != first_char)
start_match++;
}
@@ -6818,7 +6824,7 @@ for(;;)
if (start_match[-1] == CHAR_CR &&
(md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
start_match < end_subject &&
- RAWUCHARTEST(start_match) == CHAR_NL)
+ UCHAR21TEST(start_match) == CHAR_NL)
start_match++;
}
}
@@ -6829,22 +6835,12 @@ for(;;)
{
while (start_match < end_subject)
{
- register pcre_uint32 c = RAWUCHARTEST(start_match);
+ register pcre_uint32 c = UCHAR21TEST(start_match);
#ifndef COMPILE_PCRE8
if (c > 255) c = 255;
#endif
- if ((start_bits[c/8] & (1 << (c&7))) == 0)
- {
- start_match++;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- /* In non 8-bit mode, the iteration will stop for
- characters > 255 at the beginning or not stop at all. */
- if (utf)
- ACROSSCHAR(start_match < end_subject, *start_match,
- start_match++);
-#endif
- }
- else break;
+ if ((start_bits[c/8] & (1 << (c&7))) != 0) break;
+ start_match++;
}
}
} /* Starting optimizations */
@@ -6897,7 +6893,7 @@ for(;;)
{
while (p < end_subject)
{
- register pcre_uint32 pp = RAWUCHARINCTEST(p);
+ register pcre_uint32 pp = UCHAR21INCTEST(p);
if (pp == req_char || pp == req_char2) { p--; break; }
}
}
@@ -6905,7 +6901,7 @@ for(;;)
{
while (p < end_subject)
{
- if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
+ if (UCHAR21INCTEST(p) == req_char) { p--; break; }
}
}
diff --git a/pcre/pcre_globals.c b/pcre/pcre_globals.c
index 3f878144a27..0f106aa9013 100644
--- a/pcre/pcre_globals.c
+++ b/pcre/pcre_globals.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-2012 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
diff --git a/pcre/pcre_internal.h b/pcre/pcre_internal.h
index 0b9798c5541..6e915a0e453 100644
--- a/pcre/pcre_internal.h
+++ b/pcre/pcre_internal.h
@@ -7,7 +7,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -316,8 +316,8 @@ start/end of string field names are. */
&(NLBLOCK->nllen), utf)) \
: \
((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
- RAWUCHARTEST(p) == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || RAWUCHARTEST(p+1) == NLBLOCK->nl[1]) \
+ UCHAR21TEST(p) == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || UCHAR21TEST(p+1) == NLBLOCK->nl[1]) \
) \
)
@@ -330,8 +330,8 @@ start/end of string field names are. */
&(NLBLOCK->nllen), utf)) \
: \
((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
- RAWUCHARTEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || RAWUCHARTEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \
+ UCHAR21TEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || UCHAR21TEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \
) \
)
@@ -582,12 +582,27 @@ changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */
#define MAX_MARK ((1u << 8) - 1)
#endif
+/* There is a proposed future special "UTF-21" mode, in which only the lowest
+21 bits of a 32-bit character are interpreted as UTF, with the remaining 11
+high-order bits available to the application for other uses. In preparation for
+the future implementation of this mode, there are macros that load a data item
+and, if in this special mode, mask it to 21 bits. These macros all have names
+starting with UCHAR21. In all other modes, including the normal 32-bit
+library, the macros all have the same simple definitions. When the new mode is
+implemented, it is expected that these definitions will be varied appropriately
+using #ifdef when compiling the library that supports the special mode. */
+
+#define UCHAR21(eptr) (*(eptr))
+#define UCHAR21TEST(eptr) (*(eptr))
+#define UCHAR21INC(eptr) (*(eptr)++)
+#define UCHAR21INCTEST(eptr) (*(eptr)++)
+
/* When UTF encoding is being used, a character is no longer just a single
-byte. The macros for character handling generate simple sequences when used in
-character-mode, and more complicated ones for UTF characters. GETCHARLENTEST
-and other macros are not used when UTF is not supported, so they are not
-defined. To make sure they can never even appear when UTF support is omitted,
-we don't even define them. */
+byte in 8-bit mode or a single short in 16-bit mode. The macros for character
+handling generate simple sequences when used in the basic mode, and more
+complicated ones for UTF characters. GETCHARLENTEST and other macros are not
+used when UTF is not supported. To make sure they can never even appear when
+UTF support is omitted, we don't even define them. */
#ifndef SUPPORT_UTF
@@ -600,10 +615,6 @@ we don't even define them. */
#define GETCHARINC(c, eptr) c = *eptr++;
#define GETCHARINCTEST(c, eptr) c = *eptr++;
#define GETCHARLEN(c, eptr, len) c = *eptr;
-#define RAWUCHAR(eptr) (*(eptr))
-#define RAWUCHARINC(eptr) (*(eptr)++)
-#define RAWUCHARTEST(eptr) (*(eptr))
-#define RAWUCHARINCTEST(eptr) (*(eptr)++)
/* #define GETCHARLENTEST(c, eptr, len) */
/* #define BACKCHAR(eptr) */
/* #define FORWARDCHAR(eptr) */
@@ -776,30 +787,6 @@ do not know if we are in UTF-8 mode. */
c = *eptr; \
if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);
-/* Returns the next uchar, not advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHAR(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHARINC(eptr) \
- (*((eptr)++))
-
-/* Returns the next uchar, testing for UTF mode, and not advancing the
-pointer. */
-
-#define RAWUCHARTEST(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, testing for UTF mode, advancing the
-pointer. */
-
-#define RAWUCHARINCTEST(eptr) \
- (*((eptr)++))
-
/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-8 mode - we don't put a test within the macro
because almost all calls are already within a block of UTF-8 only code. */
@@ -895,30 +882,6 @@ we do not know if we are in UTF-16 mode. */
c = *eptr; \
if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
-/* Returns the next uchar, not advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHAR(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHARINC(eptr) \
- (*((eptr)++))
-
-/* Returns the next uchar, testing for UTF mode, and not advancing the
-pointer. */
-
-#define RAWUCHARTEST(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, testing for UTF mode, advancing the
-pointer. */
-
-#define RAWUCHARINCTEST(eptr) \
- (*((eptr)++))
-
/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-16 mode - we don't put a test within the
macro because almost all calls are already within a block of UTF-16 only
@@ -980,30 +943,6 @@ This is called when we do not know if we are in UTF-32 mode. */
#define GETCHARLENTEST(c, eptr, len) \
GETCHARTEST(c, eptr)
-/* Returns the next uchar, not advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHAR(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHARINC(eptr) \
- (*((eptr)++))
-
-/* Returns the next uchar, testing for UTF mode, and not advancing the
-pointer. */
-
-#define RAWUCHARTEST(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, testing for UTF mode, advancing the
-pointer. */
-
-#define RAWUCHARINCTEST(eptr) \
- (*((eptr)++))
-
/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-32 mode - we don't put a test within the
macro because almost all calls are already within a block of UTF-32 only
@@ -1874,8 +1813,9 @@ table. */
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
contain characters with values greater than 255. */
-#define XCL_NOT 0x01 /* Flag: this is a negative class */
-#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
+#define XCL_NOT 0x01 /* Flag: this is a negative class */
+#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
+#define XCL_HASPROP 0x04 /* Flag: property checks are present. */
#define XCL_END 0 /* Marks end of individual items */
#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
@@ -2341,7 +2281,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79,
- ERR80, ERR81, ERR82, ERR83, ERR84, ERRCOUNT };
+ ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERRCOUNT };
/* JIT compiling modes. The function list is indexed by them. */
diff --git a/pcre/pcre_jit_compile.c b/pcre/pcre_jit_compile.c
index 63b32c51670..e67071ef791 100644
--- a/pcre/pcre_jit_compile.c
+++ b/pcre/pcre_jit_compile.c
@@ -179,11 +179,12 @@ typedef struct jit_arguments {
typedef struct executable_functions {
void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
+ sljit_uw *read_only_data[JIT_NUMBER_OF_COMPILE_MODES];
+ sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
PUBL(jit_callback) callback;
void *userdata;
pcre_uint32 top_bracket;
pcre_uint32 limit_match;
- sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
} executable_functions;
typedef struct jump_list {
@@ -197,6 +198,12 @@ typedef struct stub_list {
struct stub_list *next;
} stub_list;
+typedef struct label_addr_list {
+ struct sljit_label *label;
+ sljit_uw *addr;
+ struct label_addr_list *next;
+} label_addr_list;
+
enum frame_types {
no_frame = -1,
no_stack = -2
@@ -306,7 +313,7 @@ typedef struct then_trap_backtrack {
int framesize;
} then_trap_backtrack;
-#define MAX_RANGE_SIZE 6
+#define MAX_RANGE_SIZE 4
typedef struct compiler_common {
/* The sljit ceneric compiler. */
@@ -315,6 +322,12 @@ typedef struct compiler_common {
pcre_uchar *start;
/* Maps private data offset to each opcode. */
sljit_si *private_data_ptrs;
+ /* This read-only data is available during runtime. */
+ sljit_uw *read_only_data;
+ /* The total size of the read-only data. */
+ sljit_uw read_only_data_size;
+ /* The next free entry of the read_only_data. */
+ sljit_uw *read_only_data_ptr;
/* Tells whether the capturing bracket is optimized. */
pcre_uint8 *optimized_cbracket;
/* Tells whether the starting offset is a target of then. */
@@ -349,6 +362,8 @@ typedef struct compiler_common {
sljit_sw lcc;
/* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
int mode;
+ /* TRUE, when minlength is greater than 0. */
+ BOOL might_be_empty;
/* \K is found in the pattern. */
BOOL has_set_som;
/* (*SKIP:arg) is found in the pattern. */
@@ -363,13 +378,16 @@ typedef struct compiler_common {
BOOL positive_assert;
/* Newline control. */
int nltype;
+ pcre_uint32 nlmax;
+ pcre_uint32 nlmin;
int newline;
int bsr_nltype;
+ pcre_uint32 bsr_nlmax;
+ pcre_uint32 bsr_nlmin;
/* Dollar endonly. */
int endonly;
/* Tables. */
sljit_sw ctypes;
- int digits[2 + MAX_RANGE_SIZE];
/* Named capturing brackets. */
pcre_uchar *name_table;
sljit_sw name_count;
@@ -380,7 +398,9 @@ typedef struct compiler_common {
struct sljit_label *quit_label;
struct sljit_label *forced_quit_label;
struct sljit_label *accept_label;
+ struct sljit_label *ff_newline_shortcut;
stub_list *stubs;
+ label_addr_list *label_addrs;
recurse_entry *entries;
recurse_entry *currententry;
jump_list *partialmatch;
@@ -404,10 +424,9 @@ typedef struct compiler_common {
#ifdef SUPPORT_UCP
BOOL use_ucp;
#endif
-#ifndef COMPILE_PCRE32
- jump_list *utfreadchar;
-#endif
#ifdef COMPILE_PCRE8
+ jump_list *utfreadchar;
+ jump_list *utfreadchar16;
jump_list *utfreadtype8;
#endif
#endif /* SUPPORT_UTF */
@@ -524,6 +543,8 @@ the start pointers when the end of the capturing group has not yet reached. */
#define GET_LOCAL_BASE(dst, dstw, offset) \
sljit_get_local_base(compiler, (dst), (dstw), (offset))
+#define READ_CHAR_MAX 0x7fffffff
+
static pcre_uchar* bracketend(pcre_uchar* cc)
{
SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
@@ -533,6 +554,25 @@ cc += 1 + LINK_SIZE;
return cc;
}
+static int no_alternatives(pcre_uchar* cc)
+{
+int count = 0;
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+do
+ {
+ cc += GET(cc, 1);
+ count++;
+ }
+while (*cc == OP_ALT);
+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
+return count;
+}
+
+static int ones_in_half_byte[16] = {
+ /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
+ /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
+};
+
/* Functions whose might need modification for all new supported opcodes:
next_opcode
check_opcode_types
@@ -752,6 +792,7 @@ while (cc < ccend)
{
case OP_SET_SOM:
common->has_set_som = TRUE;
+ common->might_be_empty = TRUE;
cc += 1;
break;
@@ -761,6 +802,16 @@ while (cc < ccend)
cc += 1 + IMM2_SIZE;
break;
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_SBRA:
+ case OP_SCBRA:
+ count = no_alternatives(cc);
+ if (count > 4)
+ common->read_only_data_size += count * sizeof(sljit_uw);
+ cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0);
+ break;
+
case OP_CBRAPOS:
case OP_SCBRAPOS:
common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
@@ -2019,6 +2070,21 @@ while (list_item)
common->stubs = NULL;
}
+static void add_label_addr(compiler_common *common)
+{
+DEFINE_COMPILER;
+label_addr_list *label_addr;
+
+label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
+if (label_addr == NULL)
+ return;
+label_addr->label = LABEL();
+label_addr->addr = common->read_only_data_ptr;
+label_addr->next = common->label_addrs;
+common->label_addrs = label_addr;
+common->read_only_data_ptr++;
+}
+
static SLJIT_INLINE void count_match(compiler_common *common)
{
DEFINE_COMPILER;
@@ -2457,107 +2523,290 @@ else
JUMPHERE(jump);
}
-static void read_char(compiler_common *common)
+static void peek_char(compiler_common *common, pcre_uint32 max)
{
-/* Reads the character into TMP1, updates STR_PTR.
+/* Reads the character into TMP1, keeps STR_PTR.
Does not check STR_END. TMP2 Destroyed. */
DEFINE_COMPILER;
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
struct sljit_jump *jump;
#endif
+SLJIT_UNUSED_ARG(max);
+
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (common->utf)
{
-#if defined COMPILE_PCRE8
+ if (max < 128) return;
+
jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
-#elif defined COMPILE_PCRE16
- jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
-#endif /* COMPILE_PCRE[8|16] */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
JUMPHERE(jump);
}
#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ if (max < 0xd800) return;
+
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ /* TMP2 contains the high surrogate. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+
+static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass)
+{
+/* Tells whether the character codes below 128 are enough
+to determine a match. */
+const pcre_uint8 value = nclass ? 0xff : 0;
+const pcre_uint8* end = bitset + 32;
+
+bitset += 16;
+do
+ {
+ if (*bitset++ != value)
+ return FALSE;
+ }
+while (bitset < end);
+return TRUE;
+}
+
+static void read_char7_type(compiler_common *common, BOOL full_read)
+{
+/* Reads the precise character type of a character into TMP1, if the character
+is less than 128. Otherwise it returns with zero. Does not check STR_END. The
+full_read argument tells whether characters above max are accepted or not. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+SLJIT_ASSERT(common->utf);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+
+if (full_read)
+ {
+ jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
}
-static void peek_char(compiler_common *common)
+#endif /* SUPPORT_UTF && COMPILE_PCRE8 */
+
+static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr)
{
-/* Reads the character into TMP1, keeps STR_PTR.
-Does not check STR_END. TMP2 Destroyed. */
+/* Reads the precise value of a character into TMP1, if the character is
+between min and max (c >= min && c <= max). Otherwise it returns with a value
+outside the range. Does not check STR_END. */
DEFINE_COMPILER;
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
struct sljit_jump *jump;
#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+struct sljit_jump *jump2;
+#endif
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+SLJIT_UNUSED_ARG(update_str_ptr);
+SLJIT_UNUSED_ARG(min);
+SLJIT_UNUSED_ARG(max);
+SLJIT_ASSERT(min <= max);
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (common->utf)
{
-#if defined COMPILE_PCRE8
+ if (max < 128 && !update_str_ptr) return;
+
jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
-#elif defined COMPILE_PCRE16
- jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
-#endif /* COMPILE_PCRE[8|16] */
- add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ if (min >= 0x10000)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
+ if (update_str_ptr)
+ OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+ if (!update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump2);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
+ }
+ else if (min >= 0x800 && max <= 0xffff)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
+ if (update_str_ptr)
+ OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ if (!update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump2);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
+ }
+ else if (max >= 0x800)
+ add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ else if (max < 128)
+ {
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ }
+ else
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (!update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ else
+ OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
+ }
JUMPHERE(jump);
}
-#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
+#endif
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ if (max >= 0x10000)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ /* TMP2 contains the high surrogate. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+ JUMPHERE(jump);
+ return;
+ }
+
+ if (max < 0xd800 && !update_str_ptr) return;
+
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ if (update_str_ptr)
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ if (max >= 0xd800)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+static SLJIT_INLINE void read_char(compiler_common *common)
+{
+read_char_range(common, 0, READ_CHAR_MAX, TRUE);
}
-static void read_char8_type(compiler_common *common)
+static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
{
/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
DEFINE_COMPILER;
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
struct sljit_jump *jump;
#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+struct sljit_jump *jump2;
+#endif
-#ifdef SUPPORT_UTF
+SLJIT_UNUSED_ARG(update_str_ptr);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (common->utf)
{
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if defined COMPILE_PCRE8
/* This can be an extra read in some situations, but hopefully
it is needed in most cases. */
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
- add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
- JUMPHERE(jump);
-#elif defined COMPILE_PCRE16
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
- JUMPHERE(jump);
- /* Skip low surrogate if necessary. */
- OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-#elif defined COMPILE_PCRE32
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
- jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ if (!update_str_ptr)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+ jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ JUMPHERE(jump2);
+ }
+ else
+ add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
JUMPHERE(jump);
-#endif /* COMPILE_PCRE[8|16|32] */
return;
}
-#endif /* SUPPORT_UTF */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
+#endif /* SUPPORT_UTF && COMPILE_PCRE8 */
+
+#if !defined COMPILE_PCRE8
/* The ctypes array contains only 256 values. */
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
#endif
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
+#if !defined COMPILE_PCRE8
JUMPHERE(jump);
#endif
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf && update_str_ptr)
+ {
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ JUMPHERE(jump);
+ }
+#endif /* SUPPORT_UTF && COMPILE_PCRE16 */
}
static void skip_char_back(compiler_common *common)
@@ -2595,28 +2844,35 @@ if (common->utf)
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
}
-static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
+static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
{
/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
DEFINE_COMPILER;
+struct sljit_jump *jump;
if (nltype == NLTYPE_ANY)
{
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
- add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
}
else if (nltype == NLTYPE_ANYCRLF)
{
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
- add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ if (jumpifmatch)
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ JUMPHERE(jump);
+ }
}
else
{
SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
- add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
}
}
@@ -2626,58 +2882,84 @@ else
static void do_utfreadchar(compiler_common *common)
{
/* Fast decoding a UTF-8 character. TMP1 contains the first byte
-of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
+of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
DEFINE_COMPILER;
struct sljit_jump *jump;
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+
/* Searching for the first zero. */
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
jump = JUMP(SLJIT_C_NOT_ZERO);
/* Two byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-JUMPHERE(jump);
-OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
jump = JUMP(SLJIT_C_NOT_ZERO);
/* Three byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-JUMPHERE(jump);
/* Four byte sequence. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
+JUMPHERE(jump);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void do_utfreadchar16(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character. TMP1 contains the first byte
+of the character (>= 0xc0). Return value in TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+
+/* Searching for the first zero. */
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO);
+/* This code runs only in 8 bit mode. No need to shift the value. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
+/* Three byte sequence. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
}
@@ -2697,53 +2979,27 @@ jump = JUMP(SLJIT_C_NOT_ZERO);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
+/* The upper 5 bits are known at this point. */
+compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
-compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
JUMPHERE(compare);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-JUMPHERE(jump);
/* We only have types for characters less than 256. */
-OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-}
-
-#elif defined COMPILE_PCRE16
-
-static void do_utfreadchar(compiler_common *common)
-{
-/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
-of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
-DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
-jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
-/* Do nothing, only return. */
-sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
-
JUMPHERE(jump);
-/* Combine two 16 bit characters. */
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
-OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
-OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
}
-#endif /* COMPILE_PCRE[8|16] */
+#endif /* COMPILE_PCRE8 */
#endif /* SUPPORT_UTF */
@@ -2818,7 +3074,7 @@ if (firstline)
mainloop = LABEL();
/* Continual stores does not cause data dependency. */
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
- read_char(common);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
check_newlinechar(common, common->nltype, &newline, TRUE);
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
JUMPHERE(end);
@@ -2894,37 +3150,66 @@ if (newlinecheck)
return mainloop;
}
-#define MAX_N_CHARS 3
+#define MAX_N_CHARS 16
+#define MAX_N_BYTES 8
-static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
+static SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes)
{
-DEFINE_COMPILER;
-struct sljit_label *start;
-struct sljit_jump *quit;
-pcre_uint32 chars[MAX_N_CHARS * 2];
-pcre_uchar *cc = common->start + 1 + LINK_SIZE;
-int location = 0;
-pcre_int32 len, c, bit, caseless;
-int must_stop;
+pcre_uint8 len = bytes[0];
+int i;
-/* We do not support alternatives now. */
-if (*(common->start + GET(common->start, 1)) == OP_ALT)
- return FALSE;
+if (len == 255)
+ return;
+
+if (len == 0)
+ {
+ bytes[0] = 1;
+ bytes[1] = byte;
+ return;
+ }
+
+for (i = len; i > 0; i--)
+ if (bytes[i] == byte)
+ return;
+if (len >= MAX_N_BYTES - 1)
+ {
+ bytes[0] = 255;
+ return;
+ }
+
+len++;
+bytes[len] = byte;
+bytes[0] = len;
+}
+
+static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)
+{
+/* Recursive function, which scans prefix literals. */
+BOOL last, any, caseless;
+int len, repeat, len_save, consumed = 0;
+pcre_uint32 chr, mask;
+pcre_uchar *alternative, *cc_save, *oc;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+pcre_uchar othercase[8];
+#elif defined SUPPORT_UTF && defined COMPILE_PCRE16
+pcre_uchar othercase[2];
+#else
+pcre_uchar othercase[1];
+#endif
+
+repeat = 1;
while (TRUE)
{
- caseless = 0;
- must_stop = 1;
- switch(*cc)
+ last = TRUE;
+ any = FALSE;
+ caseless = FALSE;
+ switch (*cc)
{
- case OP_CHAR:
- must_stop = 0;
- cc++;
- break;
-
case OP_CHARI:
- caseless = 1;
- must_stop = 0;
+ caseless = TRUE;
+ case OP_CHAR:
+ last = FALSE;
cc++;
break;
@@ -2943,125 +3228,546 @@ while (TRUE)
cc++;
continue;
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ cc = bracketend(cc);
+ continue;
+
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ caseless = TRUE;
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
cc++;
break;
+ case OP_EXACTI:
+ caseless = TRUE;
case OP_EXACT:
+ repeat = GET2(cc, 1);
+ last = FALSE;
cc += 1 + IMM2_SIZE;
break;
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- caseless = 1;
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ caseless = TRUE;
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ len = 1;
cc++;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
+#endif
+ max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);
+ if (max_chars == 0)
+ return consumed;
+ last = FALSE;
break;
- case OP_EXACTI:
- caseless = 1;
+ case OP_KET:
+ cc += 1 + LINK_SIZE;
+ continue;
+
+ case OP_ALT:
+ cc += GET(cc, 1);
+ continue;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ alternative = cc + GET(cc, 1);
+ while (*alternative == OP_ALT)
+ {
+ max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);
+ if (max_chars == 0)
+ return consumed;
+ alternative += GET(alternative, 1);
+ }
+
+ if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
+ cc += IMM2_SIZE;
+ cc += 1 + LINK_SIZE;
+ continue;
+
+ case OP_CLASS:
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && !is_char7_bitset((const pcre_uint8 *)(cc + 1), FALSE)) return consumed;
+#endif
+ any = TRUE;
+ cc += 1 + 32 / sizeof(pcre_uchar);
+ break;
+
+ case OP_NCLASS:
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc += 1 + 32 / sizeof(pcre_uchar);
+ break;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc += GET(cc, 1);
+ break;
+#endif
+
+ case OP_DIGIT:
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
+ return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+ case OP_WHITESPACE:
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_space, FALSE))
+ return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+ case OP_WORDCHAR:
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_word, FALSE))
+ return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+ case OP_NOT:
+ case OP_NOTI:
+ cc++;
+ /* Fall through. */
+ case OP_NOT_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc++;
+ break;
+
+#ifdef SUPPORT_UCP
+ case OP_NOTPROP:
+ case OP_PROP:
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ cc += 1 + 2;
+ break;
+#endif
+
+ case OP_TYPEEXACT:
+ repeat = GET2(cc, 1);
cc += 1 + IMM2_SIZE;
+ continue;
+
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (common->utf) return consumed;
+#endif
+ any = TRUE;
+ repeat = GET2(cc, 1);
+ cc += 1 + IMM2_SIZE + 1;
break;
default:
- must_stop = 2;
- break;
+ return consumed;
}
- if (must_stop == 2)
- break;
+ if (any)
+ {
+#if defined COMPILE_PCRE8
+ mask = 0xff;
+#elif defined COMPILE_PCRE16
+ mask = 0xffff;
+#elif defined COMPILE_PCRE32
+ mask = 0xffffffff;
+#else
+ SLJIT_ASSERT_STOP();
+#endif
+
+ do
+ {
+ chars[0] = mask;
+ chars[1] = mask;
+ bytes[0] = 255;
+
+ consumed++;
+ if (--max_chars == 0)
+ return consumed;
+ chars += 2;
+ bytes += MAX_N_BYTES;
+ }
+ while (--repeat > 0);
+
+ repeat = 1;
+ continue;
+ }
len = 1;
#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
+ if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
#endif
if (caseless && char_has_othercase(common, cc))
{
- caseless = char_get_othercase_bit(common, cc);
- if (caseless == 0)
- return FALSE;
-#ifdef COMPILE_PCRE8
- caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
-#else
- if ((caseless & 0x100) != 0)
- caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHAR(chr, cc);
+ if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
+ return consumed;
+ }
else
- caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
#endif
+ {
+ chr = *cc;
+ othercase[0] = TABLE_GET(chr, common->fcc, chr);
+ }
}
else
- caseless = 0;
+ caseless = FALSE;
- while (len > 0 && location < MAX_N_CHARS * 2)
+ len_save = len;
+ cc_save = cc;
+ while (TRUE)
{
- c = *cc;
- bit = 0;
- if (len == (caseless & 0xff))
+ oc = othercase;
+ do
{
- bit = caseless >> 8;
- c |= bit;
+ chr = *cc;
+#ifdef COMPILE_PCRE32
+ if (SLJIT_UNLIKELY(chr == NOTACHAR))
+ return consumed;
+#endif
+ add_prefix_byte((pcre_uint8)chr, bytes);
+
+ mask = 0;
+ if (caseless)
+ {
+ add_prefix_byte((pcre_uint8)*oc, bytes);
+ mask = *cc ^ *oc;
+ chr |= mask;
+ }
+
+#ifdef COMPILE_PCRE32
+ if (chars[0] == NOTACHAR && chars[1] == 0)
+#else
+ if (chars[0] == NOTACHAR)
+#endif
+ {
+ chars[0] = chr;
+ chars[1] = mask;
+ }
+ else
+ {
+ mask |= chars[0] ^ chr;
+ chr |= mask;
+ chars[0] = chr;
+ chars[1] |= mask;
+ }
+
+ len--;
+ consumed++;
+ if (--max_chars == 0)
+ return consumed;
+ chars += 2;
+ bytes += MAX_N_BYTES;
+ cc++;
+ oc++;
}
+ while (len > 0);
- chars[location] = c;
- chars[location + 1] = bit;
+ if (--repeat == 0)
+ break;
- len--;
- location += 2;
- cc++;
+ len = len_save;
+ cc = cc_save;
+ }
+
+ repeat = 1;
+ if (last)
+ return consumed;
+ }
+}
+
+static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *quit;
+pcre_uint32 chars[MAX_N_CHARS * 2];
+pcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES];
+pcre_uint8 ones[MAX_N_CHARS];
+int offsets[3];
+pcre_uint32 mask;
+pcre_uint8 *byte_set, *byte_set_end;
+int i, max, from;
+int range_right = -1, range_len = 3 - 1;
+sljit_ub *update_table = NULL;
+BOOL in_range;
+
+/* This is even TRUE, if both are NULL. */
+SLJIT_ASSERT(common->read_only_data_ptr == common->read_only_data);
+
+for (i = 0; i < MAX_N_CHARS; i++)
+ {
+ chars[i << 1] = NOTACHAR;
+ chars[(i << 1) + 1] = 0;
+ bytes[i * MAX_N_BYTES] = 0;
+ }
+
+max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);
+
+if (max <= 1)
+ return FALSE;
+
+for (i = 0; i < max; i++)
+ {
+ mask = chars[(i << 1) + 1];
+ ones[i] = ones_in_half_byte[mask & 0xf];
+ mask >>= 4;
+ while (mask != 0)
+ {
+ ones[i] += ones_in_half_byte[mask & 0xf];
+ mask >>= 4;
+ }
+ }
+
+in_range = FALSE;
+from = 0; /* Prevent compiler "uninitialized" warning */
+for (i = 0; i <= max; i++)
+ {
+ if (in_range && (i - from) > range_len && (bytes[(i - 1) * MAX_N_BYTES] <= 4))
+ {
+ range_len = i - from;
+ range_right = i - 1;
+ }
+
+ if (i < max && bytes[i * MAX_N_BYTES] < 255)
+ {
+ if (!in_range)
+ {
+ in_range = TRUE;
+ from = i;
+ }
+ }
+ else if (in_range)
+ in_range = FALSE;
+ }
+
+if (range_right >= 0)
+ {
+ /* Since no data is consumed (see the assert in the beginning
+ of this function), this space can be reallocated. */
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
+
+ common->read_only_data_size += 256;
+ common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size);
+ if (common->read_only_data == NULL)
+ return TRUE;
+
+ update_table = (sljit_ub *)common->read_only_data;
+ common->read_only_data_ptr = (sljit_uw *)(update_table + 256);
+ memset(update_table, IN_UCHARS(range_len), 256);
+
+ for (i = 0; i < range_len; i++)
+ {
+ byte_set = bytes + ((range_right - i) * MAX_N_BYTES);
+ SLJIT_ASSERT(byte_set[0] > 0 && byte_set[0] < 255);
+ byte_set_end = byte_set + byte_set[0];
+ byte_set++;
+ while (byte_set <= byte_set_end)
+ {
+ if (update_table[*byte_set] > IN_UCHARS(i))
+ update_table[*byte_set] = IN_UCHARS(i);
+ byte_set++;
+ }
}
+ }
- if (location >= MAX_N_CHARS * 2 || must_stop != 0)
+offsets[0] = -1;
+/* Scan forward. */
+for (i = 0; i < max; i++)
+ if (ones[i] <= 2) {
+ offsets[0] = i;
break;
}
-/* At least two characters are required. */
-if (location < 2 * 2)
+if (offsets[0] < 0 && range_right < 0)
+ return FALSE;
+
+if (offsets[0] >= 0)
+ {
+ /* Scan backward. */
+ offsets[1] = -1;
+ for (i = max - 1; i > offsets[0]; i--)
+ if (ones[i] <= 2 && i != range_right)
+ {
+ offsets[1] = i;
+ break;
+ }
+
+ /* This case is handled better by fast_forward_first_char. */
+ if (offsets[1] == -1 && offsets[0] == 0 && range_right < 0)
return FALSE;
+ offsets[2] = -1;
+ /* We only search for a middle character if there is no range check. */
+ if (offsets[1] >= 0 && range_right == -1)
+ {
+ /* Scan from middle. */
+ for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
+ if (ones[i] <= 2)
+ {
+ offsets[2] = i;
+ break;
+ }
+
+ if (offsets[2] == -1)
+ {
+ for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)
+ if (ones[i] <= 2)
+ {
+ offsets[2] = i;
+ break;
+ }
+ }
+ }
+
+ SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));
+ SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
+
+ chars[0] = chars[offsets[0] << 1];
+ chars[1] = chars[(offsets[0] << 1) + 1];
+ if (offsets[2] >= 0)
+ {
+ chars[2] = chars[offsets[2] << 1];
+ chars[3] = chars[(offsets[2] << 1) + 1];
+ }
+ if (offsets[1] >= 0)
+ {
+ chars[4] = chars[offsets[1] << 1];
+ chars[5] = chars[(offsets[1] << 1) + 1];
+ }
+ }
+
+max -= 1;
if (firstline)
{
SLJIT_ASSERT(common->first_line_end != 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
+ OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+ quit = CMP(SLJIT_C_LESS_EQUAL, STR_END, 0, TMP1, 0);
+ OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
+ JUMPHERE(quit);
}
else
- OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
+ OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+if (range_right >= 0)
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
+#endif
start = LABEL();
quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
-OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
-if (chars[1] != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
-CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
-if (location > 2 * 2)
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
-if (chars[3] != 0)
- OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
-CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
-if (location > 2 * 2)
- {
- if (chars[5] != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
- CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
+SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0);
+
+if (range_right >= 0)
+ {
+#if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
+#else
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
+#endif
+
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
+#else
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
+ }
+
+if (offsets[0] >= 0)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));
+ if (offsets[1] >= 0)
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ if (chars[1] != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
+ if (offsets[2] >= 0)
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1));
+
+ if (offsets[1] >= 0)
+ {
+ if (chars[5] != 0)
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);
+ }
+
+ if (offsets[2] >= 0)
+ {
+ if (chars[3] != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);
+ }
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
}
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
JUMPHERE(quit);
if (firstline)
+ {
+ if (range_right >= 0)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+ if (range_right >= 0)
+ {
+ quit = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(quit);
+ }
+ }
else
- OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
+ OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
return TRUE;
}
#undef MAX_N_CHARS
+#undef MAX_N_BYTES
static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
{
@@ -3167,7 +3873,7 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
JUMPHERE(lastchar);
if (firstline)
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
return;
}
@@ -3177,7 +3883,9 @@ firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
skip_char_back(common);
loop = LABEL();
-read_char(common);
+common->ff_newline_shortcut = loop;
+
+read_char_range(common, common->nlmin, common->nlmax, TRUE);
lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
@@ -3206,24 +3914,19 @@ if (firstline)
OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
}
-static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
+static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
-static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
+static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline)
{
DEFINE_COMPILER;
struct sljit_label *start;
struct sljit_jump *quit;
struct sljit_jump *found = NULL;
jump_list *matches = NULL;
-pcre_uint8 inverted_start_bits[32];
-int i;
#ifndef COMPILE_PCRE8
struct sljit_jump *jump;
#endif
-for (i = 0; i < 32; ++i)
- inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
-
if (firstline)
{
SLJIT_ASSERT(common->first_line_end != 0);
@@ -3239,7 +3942,7 @@ if (common->utf)
OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
#endif
-if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
+if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
{
#ifndef COMPILE_PCRE8
jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
@@ -3248,7 +3951,7 @@ if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] &
#endif
OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
found = JUMP(SLJIT_C_NOT_ZERO);
@@ -3451,7 +4154,7 @@ JUMPHERE(skipread);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
check_str_end(common, &skipread_list);
-peek_char(common);
+peek_char(common, READ_CHAR_MAX);
/* Testing char type. This is a code duplication. */
#ifdef SUPPORT_UCP
@@ -3497,110 +4200,15 @@ OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_R
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
}
-/*
- range format:
-
- ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
- ranges[1] = first bit (0 or 1)
- ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
-*/
-
-static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
+static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
{
DEFINE_COMPILER;
-struct sljit_jump *jump;
-
-if (ranges[0] < 0)
- return FALSE;
-
-switch(ranges[0])
- {
- case 1:
- if (readch)
- read_char(common);
- add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
- return TRUE;
-
- case 2:
- if (readch)
- read_char(common);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
- add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
- return TRUE;
-
- case 4:
- if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
- {
- if (readch)
- read_char(common);
- if (ranges[1] != 0)
- {
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
- }
- else
- {
- jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
- add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
- JUMPHERE(jump);
- }
- return TRUE;
- }
- if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
- {
- if (readch)
- read_char(common);
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
- add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
- return TRUE;
- }
- return FALSE;
-
- default:
- return FALSE;
- }
-}
-
-static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
-{
-int i, bit, length;
-const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
-
-bit = ctypes[0] & flag;
-ranges[0] = -1;
-ranges[1] = bit != 0 ? 1 : 0;
-length = 0;
-
-for (i = 1; i < 256; i++)
- if ((ctypes[i] & flag) != bit)
- {
- if (length >= MAX_RANGE_SIZE)
- return;
- ranges[2 + length] = i;
- length++;
- bit ^= flag;
- }
-
-if (bit != 0)
- {
- if (length >= MAX_RANGE_SIZE)
- return;
- ranges[2 + length] = 256;
- length++;
- }
-ranges[0] = length;
-}
-
-static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
-{
-int ranges[2 + MAX_RANGE_SIZE];
+int ranges[MAX_RANGE_SIZE];
pcre_uint8 bit, cbit, all;
int i, byte, length = 0;
bit = bits[0] & 0x1;
-ranges[1] = bit;
-/* Can be 0 or 255. */
+/* All bits will be zero or one (since bit is zero or one). */
all = -bit;
for (i = 0; i < 256; )
@@ -3615,7 +4223,7 @@ for (i = 0; i < 256; )
{
if (length >= MAX_RANGE_SIZE)
return FALSE;
- ranges[2 + length] = i;
+ ranges[length] = i;
length++;
bit = cbit;
all = -cbit;
@@ -3628,12 +4236,117 @@ if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
{
if (length >= MAX_RANGE_SIZE)
return FALSE;
- ranges[2 + length] = 256;
+ ranges[length] = 256;
length++;
}
-ranges[0] = length;
-return check_ranges(common, ranges, backtracks, FALSE);
+if (length < 0 || length > 4)
+ return FALSE;
+
+bit = bits[0] & 0x1;
+if (invert) bit ^= 0x1;
+
+/* No character is accepted. */
+if (length == 0 && bit == 0)
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+
+switch(length)
+ {
+ case 0:
+ /* When bit != 0, all characters are accepted. */
+ return TRUE;
+
+ case 1:
+ add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+ return TRUE;
+
+ case 2:
+ if (ranges[0] + 1 != ranges[1])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+ return TRUE;
+
+ case 3:
+ if (bit != 0)
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
+ if (ranges[0] + 1 != ranges[1])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+ return TRUE;
+ }
+
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
+ if (ranges[1] + 1 != ranges[2])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
+ return TRUE;
+
+ case 4:
+ if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
+ && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
+ && is_powerof2(ranges[2] - ranges[0]))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
+ if (ranges[2] + 1 != ranges[3])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
+ return TRUE;
+ }
+
+ if (bit != 0)
+ {
+ i = 0;
+ if (ranges[0] + 1 != ranges[1])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ i = ranges[0];
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
+
+ if (ranges[2] + 1 != ranges[3])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
+ return TRUE;
+ }
+
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
+ if (ranges[1] + 1 != ranges[2])
+ {
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
+ return TRUE;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return FALSE;
+ }
}
static void check_anynewline(compiler_common *common)
@@ -4000,20 +4713,20 @@ return cc;
#define SET_TYPE_OFFSET(value) \
if ((value) != typeoffset) \
{ \
- if ((value) > typeoffset) \
- OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
- else \
+ if ((value) < typeoffset) \
OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
+ else \
+ OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
} \
typeoffset = (value);
#define SET_CHAR_OFFSET(value) \
if ((value) != charoffset) \
{ \
- if ((value) > charoffset) \
- OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
+ if ((value) < charoffset) \
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
else \
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
} \
charoffset = (value);
@@ -4021,84 +4734,53 @@ static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc,
{
DEFINE_COMPILER;
jump_list *found = NULL;
-jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
-pcre_int32 c, charoffset;
+jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
+sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
struct sljit_jump *jump = NULL;
pcre_uchar *ccbegin;
int compares, invertcmp, numberofcmps;
+#if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
+BOOL utf = common->utf;
+#endif
#ifdef SUPPORT_UCP
BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
BOOL charsaved = FALSE;
int typereg = TMP1, scriptreg = TMP1;
const pcre_uint32 *other_cases;
-pcre_int32 typeoffset;
+sljit_uw typeoffset;
#endif
-/* Although SUPPORT_UTF must be defined, we are
- not necessary in utf mode even in 8 bit mode. */
-detect_partial_match(common, backtracks);
-read_char(common);
-
-if ((*cc++ & XCL_MAP) != 0)
+/* Scanning the necessary info. */
+cc++;
+ccbegin = cc;
+compares = 0;
+if (cc[-1] & XCL_MAP)
{
- OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
-#ifndef COMPILE_PCRE8
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#elif defined SUPPORT_UTF
- if (common->utf)
- jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
-#endif
-
- if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
- {
- OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
- OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
- OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
- OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
- add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
- }
-
-#ifndef COMPILE_PCRE8
- JUMPHERE(jump);
-#elif defined SUPPORT_UTF
- if (common->utf)
- JUMPHERE(jump);
-#endif
- OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-#ifdef SUPPORT_UCP
- charsaved = TRUE;
-#endif
+ min = 0;
cc += 32 / sizeof(pcre_uchar);
}
-/* Scanning the necessary info. */
-ccbegin = cc;
-compares = 0;
while (*cc != XCL_END)
{
compares++;
if (*cc == XCL_SINGLE)
{
- cc += 2;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ if (c > max) max = c;
+ if (c < min) min = c;
#ifdef SUPPORT_UCP
needschar = TRUE;
#endif
}
else if (*cc == XCL_RANGE)
{
- cc += 2;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- cc++;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
+ cc ++;
+ GETCHARINCTEST(c, cc);
+ if (c < min) min = c;
+ GETCHARINCTEST(c, cc);
+ if (c > max) max = c;
#ifdef SUPPORT_UCP
needschar = TRUE;
#endif
@@ -4108,6 +4790,22 @@ while (*cc != XCL_END)
{
SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
cc++;
+ if (*cc == PT_CLIST)
+ {
+ other_cases = PRIV(ucd_caseless_sets) + cc[1];
+ while (*other_cases != NOTACHAR)
+ {
+ if (*other_cases > max) max = *other_cases;
+ if (*other_cases < min) min = *other_cases;
+ other_cases++;
+ }
+ }
+ else
+ {
+ max = READ_CHAR_MAX;
+ min = 0;
+ }
+
switch(*cc)
{
case PT_ANY:
@@ -4148,6 +4846,64 @@ while (*cc != XCL_END)
#endif
}
+/* We are not necessary in utf mode even in 8 bit mode. */
+cc = ccbegin;
+detect_partial_match(common, backtracks);
+read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
+
+if ((cc[-1] & XCL_HASPROP) == 0)
+ {
+ if ((cc[-1] & XCL_MAP) != 0)
+ {
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found))
+ {
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));
+ }
+
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(jump);
+
+ cc += 32 / sizeof(pcre_uchar);
+ }
+ else
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
+ add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, max - min));
+ }
+ }
+else if ((cc[-1] & XCL_MAP) != 0)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#ifdef SUPPORT_UCP
+ charsaved = TRUE;
+#endif
+ if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
+ {
+#ifdef COMPILE_PCRE8
+ SLJIT_ASSERT(common->utf);
+#endif
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
+
+ JUMPHERE(jump);
+ }
+
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ cc += 32 / sizeof(pcre_uchar);
+ }
+
#ifdef SUPPORT_UCP
/* Simple register allocation. TMP1 is preferred if possible. */
if (needstype || needsscript)
@@ -4189,7 +4945,6 @@ if (needstype || needsscript)
#endif
/* Generating code. */
-cc = ccbegin;
charoffset = 0;
numberofcmps = 0;
#ifdef SUPPORT_UCP
@@ -4205,70 +4960,50 @@ while (*cc != XCL_END)
if (*cc == XCL_SINGLE)
{
cc ++;
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHARINC(c, cc);
- }
- else
-#endif
- c = *cc++;
+ GETCHARINCTEST(c, cc);
if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
{
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
numberofcmps++;
}
else if (numberofcmps > 0)
{
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
numberofcmps = 0;
}
else
{
- jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
numberofcmps = 0;
}
}
else if (*cc == XCL_RANGE)
{
cc ++;
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHARINC(c, cc);
- }
- else
-#endif
- c = *cc++;
+ GETCHARINCTEST(c, cc);
SET_CHAR_OFFSET(c);
-#ifdef SUPPORT_UTF
- if (common->utf)
- {
- GETCHARINC(c, cc);
- }
- else
-#endif
- c = *cc++;
+ GETCHARINCTEST(c, cc);
+
if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
{
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
numberofcmps++;
}
else if (numberofcmps > 0)
{
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
numberofcmps = 0;
}
else
{
- jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
numberofcmps = 0;
}
}
@@ -4334,7 +5069,7 @@ while (*cc != XCL_END)
break;
case PT_WORD:
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
/* Fall through. */
@@ -4382,35 +5117,35 @@ while (*cc != XCL_END)
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
other_cases += 3;
}
else
{
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
}
while (*other_cases != NOTACHAR)
{
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
}
jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
break;
case PT_UCNC:
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
SET_CHAR_OFFSET(0xa0);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
SET_CHAR_OFFSET(0);
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
@@ -4509,7 +5244,7 @@ struct sljit_label *label;
#ifdef SUPPORT_UCP
pcre_uchar propdata[5];
#endif
-#endif
+#endif /* SUPPORT_UTF */
switch(type)
{
@@ -4534,26 +5269,27 @@ switch(type)
case OP_NOT_DIGIT:
case OP_DIGIT:
/* Digits are usually 0-9, so it is worth to optimize them. */
- if (common->digits[0] == -2)
- get_ctype_ranges(common, ctype_digit, common->digits);
detect_partial_match(common, backtracks);
- /* Flip the starting bit in the negative case. */
- if (type == OP_NOT_DIGIT)
- common->digits[1] ^= 1;
- if (!check_ranges(common, common->digits, backtracks, TRUE))
- {
- read_char8_type(common);
- OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
- add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
- }
- if (type == OP_NOT_DIGIT)
- common->digits[1] ^= 1;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))
+ read_char7_type(common, type == OP_NOT_DIGIT);
+ else
+#endif
+ read_char8_type(common, type == OP_NOT_DIGIT);
+ /* Flip the starting bit in the negative case. */
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
+ add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
return cc;
case OP_NOT_WHITESPACE:
case OP_WHITESPACE:
detect_partial_match(common, backtracks);
- read_char8_type(common);
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))
+ read_char7_type(common, type == OP_NOT_WHITESPACE);
+ else
+#endif
+ read_char8_type(common, type == OP_NOT_WHITESPACE);
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
return cc;
@@ -4561,14 +5297,19 @@ switch(type)
case OP_NOT_WORDCHAR:
case OP_WORDCHAR:
detect_partial_match(common, backtracks);
- read_char8_type(common);
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))
+ read_char7_type(common, type == OP_NOT_WORDCHAR);
+ else
+#endif
+ read_char8_type(common, type == OP_NOT_WORDCHAR);
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
return cc;
case OP_ANY:
detect_partial_match(common, backtracks);
- read_char(common);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
if (common->nltype == NLTYPE_FIXED && common->newline > 255)
{
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
@@ -4624,7 +5365,7 @@ switch(type)
#ifdef SUPPORT_UCP
case OP_NOTPROP:
case OP_PROP:
- propdata[0] = 0;
+ propdata[0] = XCL_HASPROP;
propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
propdata[2] = cc[0];
propdata[3] = cc[1];
@@ -4636,7 +5377,7 @@ switch(type)
case OP_ANYNL:
detect_partial_match(common, backtracks);
- read_char(common);
+ read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
/* We don't need to handle soft partial matching case. */
end_list = NULL;
@@ -4658,7 +5399,7 @@ switch(type)
case OP_NOT_HSPACE:
case OP_HSPACE:
detect_partial_match(common, backtracks);
- read_char(common);
+ read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
return cc;
@@ -4666,7 +5407,7 @@ switch(type)
case OP_NOT_VSPACE:
case OP_VSPACE:
detect_partial_match(common, backtracks);
- read_char(common);
+ read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
return cc;
@@ -4765,7 +5506,7 @@ switch(type)
else
{
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
- read_char(common);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
@@ -4813,7 +5554,7 @@ switch(type)
else
{
skip_char_back(common);
- read_char(common);
+ read_char_range(common, common->nlmin, common->nlmax, TRUE);
check_newlinechar(common, common->nltype, backtracks, FALSE);
}
JUMPHERE(jump[0]);
@@ -4864,7 +5605,7 @@ switch(type)
}
else
{
- peek_char(common);
+ peek_char(common, common->nlmax);
check_newlinechar(common, common->nltype, backtracks, FALSE);
}
JUMPHERE(jump[0]);
@@ -4888,8 +5629,8 @@ switch(type)
#endif
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
}
+
detect_partial_match(common, backtracks);
- read_char(common);
#ifdef SUPPORT_UTF
if (common->utf)
{
@@ -4898,12 +5639,15 @@ switch(type)
else
#endif
c = *cc;
+
if (type == OP_CHAR || !char_has_othercase(common, cc))
{
+ read_char_range(common, c, c, FALSE);
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
return cc + length;
}
oc = char_othercase(common, c);
+ read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
bit = c ^ oc;
if (is_powerof2(bit))
{
@@ -4911,11 +5655,9 @@ switch(type)
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
return cc + length;
}
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
- add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
+ jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
+ JUMPHERE(jump[0]);
return cc + length;
case OP_NOT:
@@ -4950,21 +5692,21 @@ switch(type)
#endif /* COMPILE_PCRE8 */
{
GETCHARLEN(c, cc, length);
- read_char(common);
}
}
else
#endif /* SUPPORT_UTF */
- {
- read_char(common);
c = *cc;
- }
if (type == OP_NOT || !char_has_othercase(common, cc))
+ {
+ read_char_range(common, c, c, TRUE);
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ }
else
{
oc = char_othercase(common, c);
+ read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
bit = c ^ oc;
if (is_powerof2(bit))
{
@@ -4982,36 +5724,49 @@ switch(type)
case OP_CLASS:
case OP_NCLASS:
detect_partial_match(common, backtracks);
- read_char(common);
- if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;
+ read_char_range(common, 0, bit, type == OP_NCLASS);
+#else
+ read_char_range(common, 0, 255, type == OP_NCLASS);
+#endif
+
+ if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))
return cc + 32 / sizeof(pcre_uchar);
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
jump[0] = NULL;
-#ifdef COMPILE_PCRE8
- /* This check only affects 8 bit mode. In other modes, we
- always need to compare the value with 255. */
if (common->utf)
-#endif /* COMPILE_PCRE8 */
{
- jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit);
if (type == OP_CLASS)
{
add_jump(compiler, backtracks, jump[0]);
jump[0] = NULL;
}
}
-#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+#elif !defined COMPILE_PCRE8
+ jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (type == OP_CLASS)
+ {
+ add_jump(compiler, backtracks, jump[0]);
+ jump[0] = NULL;
+ }
+#endif /* SUPPORT_UTF && COMPILE_PCRE8 */
+
OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
+
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
if (jump[0] != NULL)
JUMPHERE(jump[0]);
-#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+#endif
+
return cc + 32 / sizeof(pcre_uchar);
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
@@ -7345,7 +8100,7 @@ if (*cc == OP_FAIL)
return cc + 1;
}
-if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
+if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
{
/* No need to check notempty conditions. */
if (common->accept_label == NULL)
@@ -8047,21 +8802,21 @@ if (bra == OP_BRAZERO)
static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
DEFINE_COMPILER;
-int opcode, stacksize, count;
+int opcode, stacksize, alt_count, alt_max;
int offset = 0;
int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
pcre_uchar *cc = current->cc;
pcre_uchar *ccbegin;
pcre_uchar *ccprev;
-jump_list *jumplist = NULL;
-jump_list *jumplistitem = NULL;
pcre_uchar bra = OP_BRA;
pcre_uchar ket;
assert_backtrack *assert;
BOOL has_alternatives;
BOOL needs_control_head = FALSE;
struct sljit_jump *brazero = NULL;
+struct sljit_jump *alt1 = NULL;
+struct sljit_jump *alt2 = NULL;
struct sljit_jump *once = NULL;
struct sljit_jump *cond = NULL;
struct sljit_label *rmin_label = NULL;
@@ -8099,6 +8854,8 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN
if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
opcode = OP_ONCE;
+alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
+
/* Decoding the needs_control_head in framesize. */
if (opcode == OP_ONCE)
{
@@ -8212,44 +8969,27 @@ else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
free_stack(common, 1);
- jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
- if (SLJIT_UNLIKELY(!jumplistitem))
- return;
- jumplist = jumplistitem;
- jumplistitem->next = NULL;
- jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
+ alt_max = 2;
+ alt1 = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
}
}
-else if (*cc == OP_ALT)
+else if (has_alternatives)
{
- /* Build a jump list. Get the last successfully matched branch index. */
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
free_stack(common, 1);
- count = 1;
- do
- {
- /* Append as the last item. */
- if (jumplist != NULL)
- {
- jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
- jumplistitem = jumplistitem->next;
- }
- else
- {
- jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
- jumplist = jumplistitem;
- }
- if (SLJIT_UNLIKELY(!jumplistitem))
- return;
-
- jumplistitem->next = NULL;
- jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
- cc += GET(cc, 1);
+ if (alt_max > 4)
+ {
+ /* Table jump if alt_max is greater than 4. */
+ sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)common->read_only_data_ptr);
+ add_label_addr(common);
+ }
+ else
+ {
+ if (alt_max == 4)
+ alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
+ alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
}
- while (*cc == OP_ALT);
-
- cc = ccbegin + GET(ccbegin, 1);
}
COMPILE_BACKTRACKINGPATH(current->top);
@@ -8284,7 +9024,7 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
if (has_alternatives)
{
- count = 1;
+ alt_count = sizeof(sljit_uw);
do
{
current->top = NULL;
@@ -8360,7 +9100,7 @@ if (has_alternatives)
stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
if (opcode != OP_ONCE)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
{
@@ -8373,9 +9113,24 @@ if (has_alternatives)
if (opcode != OP_ONCE)
{
- SLJIT_ASSERT(jumplist);
- JUMPHERE(jumplist->jump);
- jumplist = jumplist->next;
+ if (alt_max > 4)
+ add_label_addr(common);
+ else
+ {
+ if (alt_count != 2 * sizeof(sljit_uw))
+ {
+ JUMPHERE(alt1);
+ if (alt_max == 3 && alt_count == sizeof(sljit_uw))
+ alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
+ }
+ else
+ {
+ JUMPHERE(alt2);
+ if (alt_max == 4)
+ alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
+ }
+ }
+ alt_count += sizeof(sljit_uw);
}
COMPILE_BACKTRACKINGPATH(current->top);
@@ -8384,7 +9139,6 @@ if (has_alternatives)
SLJIT_ASSERT(!current->nextbacktracks);
}
while (*cc == OP_ALT);
- SLJIT_ASSERT(!jumplist);
if (cond != NULL)
{
@@ -8985,16 +9739,18 @@ pcre_uchar *ccend;
executable_functions *functions;
void *executable_func;
sljit_uw executable_size;
+sljit_uw total_length;
+label_addr_list *label_addr;
struct sljit_label *mainloop_label = NULL;
struct sljit_label *continue_match_label;
-struct sljit_label *empty_match_found_label;
-struct sljit_label *empty_match_backtrack_label;
+struct sljit_label *empty_match_found_label = NULL;
+struct sljit_label *empty_match_backtrack_label = NULL;
struct sljit_label *reset_match_label;
+struct sljit_label *quit_label;
struct sljit_jump *jump;
struct sljit_jump *minlength_check_failed = NULL;
struct sljit_jump *reqbyte_notfound = NULL;
-struct sljit_jump *empty_match;
-struct sljit_label *quit_label;
+struct sljit_jump *empty_match = NULL;
SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
study = extra->study_data;
@@ -9007,9 +9763,13 @@ memset(common, 0, sizeof(compiler_common));
rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
common->start = rootbacktrack.cc;
+common->read_only_data = NULL;
+common->read_only_data_size = 0;
+common->read_only_data_ptr = NULL;
common->fcc = tables + fcc_offset;
common->lcc = (sljit_sw)(tables + lcc_offset);
common->mode = mode;
+common->might_be_empty = study->minlength == 0;
common->nltype = NLTYPE_FIXED;
switch(re->options & PCRE_NEWLINE_BITS)
{
@@ -9030,6 +9790,8 @@ switch(re->options & PCRE_NEWLINE_BITS)
case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
default: return;
}
+common->nlmax = READ_CHAR_MAX;
+common->nlmin = 0;
if ((re->options & PCRE_BSR_ANYCRLF) != 0)
common->bsr_nltype = NLTYPE_ANYCRLF;
else if ((re->options & PCRE_BSR_UNICODE) != 0)
@@ -9042,9 +9804,10 @@ else
common->bsr_nltype = NLTYPE_ANY;
#endif
}
+common->bsr_nlmax = READ_CHAR_MAX;
+common->bsr_nlmin = 0;
common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
common->ctypes = (sljit_sw)(tables + ctypes_offset);
-common->digits[0] = -2;
common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
common->name_count = re->name_count;
common->name_entry_size = re->name_entry_size;
@@ -9055,8 +9818,31 @@ common->utf = (re->options & PCRE_UTF8) != 0;
#ifdef SUPPORT_UCP
common->use_ucp = (re->options & PCRE_UCP) != 0;
#endif
+if (common->utf)
+ {
+ if (common->nltype == NLTYPE_ANY)
+ common->nlmax = 0x2029;
+ else if (common->nltype == NLTYPE_ANYCRLF)
+ common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
+ else
+ {
+ /* We only care about the first newline character. */
+ common->nlmax = common->newline & 0xff;
+ }
+
+ if (common->nltype == NLTYPE_FIXED)
+ common->nlmin = common->newline & 0xff;
+ else
+ common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
+
+ if (common->bsr_nltype == NLTYPE_ANY)
+ common->bsr_nlmax = 0x2029;
+ else
+ common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
+ common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
+ }
#endif /* SUPPORT_UTF */
-ccend = bracketend(rootbacktrack.cc);
+ccend = bracketend(common->start);
/* Calculate the local space size on the stack. */
common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
@@ -9069,12 +9855,12 @@ memset(common->optimized_cbracket, 0, re->top_bracket + 1);
memset(common->optimized_cbracket, 1, re->top_bracket + 1);
#endif
-SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
+SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
common->capture_last_ptr = common->ovector_start;
common->ovector_start += sizeof(sljit_sw);
#endif
-if (!check_opcode_types(common, rootbacktrack.cc, ccend))
+if (!check_opcode_types(common, common->start, ccend))
{
SLJIT_FREE(common->optimized_cbracket);
return;
@@ -9137,13 +9923,14 @@ if (common->capture_last_ptr != 0)
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
-common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));
+total_length = ccend - common->start;
+common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)));
if (!common->private_data_ptrs)
{
SLJIT_FREE(common->optimized_cbracket);
return;
}
-memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
+memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si));
private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
set_private_data_ptrs(common, &private_data_size, ccend);
@@ -9156,15 +9943,21 @@ if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
if (common->has_then)
{
- common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
- if (!common->then_offsets)
+ common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length);
+ memset(common->then_offsets, 0, total_length);
+ set_then_offsets(common, common->start, NULL);
+ }
+
+if (common->read_only_data_size > 0)
+ {
+ common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size);
+ if (common->read_only_data == NULL)
{
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
return;
}
- memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
- set_then_offsets(common, rootbacktrack.cc, NULL);
+ common->read_only_data_ptr = common->read_only_data;
}
compiler = sljit_create_compiler();
@@ -9172,8 +9965,8 @@ if (!compiler)
{
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
- if (common->has_then)
- SLJIT_FREE(common->then_offsets);
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
return;
}
common->compiler = compiler;
@@ -9212,13 +10005,22 @@ if ((re->options & PCRE_ANCHORED) == 0)
if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
{
if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
- { /* Do nothing */ }
+ {
+ /* If read_only_data is reallocated, we might have an allocation failure. */
+ if (common->read_only_data_size > 0 && common->read_only_data == NULL)
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->optimized_cbracket);
+ SLJIT_FREE(common->private_data_ptrs);
+ return;
+ }
+ }
else if ((re->flags & PCRE_FIRSTSET) != 0)
fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
else if ((re->flags & PCRE_STARTLINE) != 0)
fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
- fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
+ fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
}
}
else
@@ -9259,19 +10061,22 @@ if (mode == JIT_PARTIAL_SOFT_COMPILE)
else if (mode == JIT_PARTIAL_HARD_COMPILE)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
-compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
+compile_matchingpath(common, common->start, ccend, &rootbacktrack);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
{
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
- if (common->has_then)
- SLJIT_FREE(common->then_offsets);
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
return;
}
-empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
-empty_match_found_label = LABEL();
+if (common->might_be_empty)
+ {
+ empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ empty_match_found_label = LABEL();
+ }
common->accept_label = LABEL();
if (common->accept != NULL)
@@ -9295,15 +10100,16 @@ if (mode != JIT_COMPILE)
return_with_partial_match(common, common->quit_label);
}
-empty_match_backtrack_label = LABEL();
+if (common->might_be_empty)
+ empty_match_backtrack_label = LABEL();
compile_backtrackingpath(common, rootbacktrack.top);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
{
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
- if (common->has_then)
- SLJIT_FREE(common->then_offsets);
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
return;
}
@@ -9331,10 +10137,19 @@ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
if ((re->options & PCRE_ANCHORED) == 0)
{
- if ((re->options & PCRE_FIRSTLINE) == 0)
- CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
+ if (common->ff_newline_shortcut != NULL)
+ {
+ if ((re->options & PCRE_FIRSTLINE) == 0)
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
+ /* There cannot be more newlines here. */
+ }
else
- CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
+ {
+ if ((re->options & PCRE_FIRSTLINE) == 0)
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
+ }
}
/* No more remaining characters. */
@@ -9349,15 +10164,18 @@ JUMPTO(SLJIT_JUMP, common->quit_label);
flush_stubs(common);
-JUMPHERE(empty_match);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
-CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
-OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
-CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
-JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
+if (common->might_be_empty)
+ {
+ JUMPHERE(empty_match);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+ CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
+ JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
+ }
common->currententry = common->entries;
common->local_exit = TRUE;
@@ -9371,8 +10189,8 @@ while (common->currententry != NULL)
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
- if (common->has_then)
- SLJIT_FREE(common->then_offsets);
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
return;
}
flush_stubs(common);
@@ -9456,14 +10274,17 @@ if (common->reset_match != NULL)
JUMPTO(SLJIT_JUMP, reset_match_label);
}
#ifdef SUPPORT_UTF
-#ifndef COMPILE_PCRE32
+#ifdef COMPILE_PCRE8
if (common->utfreadchar != NULL)
{
set_jumps(common->utfreadchar, LABEL());
do_utfreadchar(common);
}
-#endif /* !COMPILE_PCRE32 */
-#ifdef COMPILE_PCRE8
+if (common->utfreadchar16 != NULL)
+ {
+ set_jumps(common->utfreadchar16, LABEL());
+ do_utfreadchar16(common);
+ }
if (common->utfreadtype8 != NULL)
{
set_jumps(common->utfreadtype8, LABEL());
@@ -9479,16 +10300,25 @@ if (common->getucd != NULL)
}
#endif
+SLJIT_ASSERT(common->read_only_data + (common->read_only_data_size >> SLJIT_WORD_SHIFT) == common->read_only_data_ptr);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
-if (common->has_then)
- SLJIT_FREE(common->then_offsets);
executable_func = sljit_generate_code(compiler);
executable_size = sljit_get_generated_code_size(compiler);
+label_addr = common->label_addrs;
+while (label_addr != NULL)
+ {
+ *label_addr->addr = sljit_get_label_addr(label_addr->label);
+ label_addr = label_addr->next;
+ }
sljit_free_compiler(compiler);
if (executable_func == NULL)
+ {
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
return;
+ }
/* Reuse the function descriptor if possible. */
if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
@@ -9508,8 +10338,10 @@ else
if (functions == NULL)
{
/* This case is highly unlikely since we just recently
- freed a lot of memory. Although not impossible. */
+ freed a lot of memory. Not impossible though. */
sljit_free_code(executable_func);
+ if (common->read_only_data)
+ SLJIT_FREE(common->read_only_data);
return;
}
memset(functions, 0, sizeof(executable_functions));
@@ -9520,6 +10352,7 @@ else
}
functions->executable_funcs[mode] = executable_func;
+functions->read_only_data[mode] = common->read_only_data;
functions->executable_sizes[mode] = executable_size;
}
@@ -9706,6 +10539,8 @@ for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
{
if (functions->executable_funcs[i] != NULL)
sljit_free_code(functions->executable_funcs[i]);
+ if (functions->read_only_data[i] != NULL)
+ SLJIT_FREE(functions->read_only_data[i]);
}
SLJIT_FREE(functions);
}
diff --git a/pcre/pcre_jit_test.c b/pcre/pcre_jit_test.c
index cabd2560c57..a40913ef0a5 100644
--- a/pcre/pcre_jit_test.c
+++ b/pcre/pcre_jit_test.c
@@ -75,9 +75,14 @@ POSSIBILITY OF SUCH DAMAGE.
\xe1\xbf\xb8 = 0x1ff8 = 8184
\xf0\x90\x90\x80 = 0x10400 = 66560
\xf0\x90\x90\xa8 = 0x10428 = 66600
+ \xc7\x84 = 0x1c4 = 452
+ \xc7\x85 = 0x1c5 = 453
+ \xc7\x86 = 0x1c6 = 454
+
Mark property:
\xcc\x8d = 0x30d = 781
Special:
+ \xc2\x80 = 0x80 = 128 (lowest 2 byte character)
\xdf\xbf = 0x7ff = 2047 (highest 2 byte character)
\xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character)
\xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character)
@@ -326,6 +331,22 @@ static struct regression_test_case regression_test_cases[] = {
{ MUA, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" },
{ MUA, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" },
{ MUA, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" },
+ { MUA, 0, "x[bcef]+", "xaxdxecbfg" },
+ { MUA, 0, "x[bcdghij]+", "xaxexfxdgbjk" },
+ { MUA, 0, "x[^befg]+", "xbxexacdhg" },
+ { MUA, 0, "x[^bcdl]+", "xlxbxaekmd" },
+ { MUA, 0, "x[^bcdghi]+", "xbxdxgxaefji" },
+ { MUA, 0, "x[B-Fb-f]+", "xaxAxgxbfBFG" },
+ { CMUA, 0, "\\x{e9}+", "#\xf0\x90\x90\xa8\xc3\xa8\xc3\xa9\xc3\x89\xc3\x88" },
+ { CMUA, 0, "[^\\x{e9}]+", "\xc3\xa9#\xf0\x90\x90\xa8\xc3\xa8\xc3\x88\xc3\x89" },
+ { MUA, 0, "[\\x02\\x7e]+", "\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x02\x7e\x7f" },
+ { MUA, 0, "[^\\x02\\x7e]+", "\x02\xc3\x81\xe1\xbf\xb8\xf0\x90\x90\xa8\x01\x7f\x7e" },
+ { MUA, 0, "[\\x{81}-\\x{7fe}]+", "#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xc2\x81\xdf\xbe\xdf\xbf" },
+ { MUA, 0, "[^\\x{81}-\\x{7fe}]+", "\xc2\x81#\xe1\xbf\xb8\xf0\x90\x90\xa8\xc2\x80\xdf\xbf\xdf\xbe" },
+ { MUA, 0, "[\\x{801}-\\x{fffe}]+", "#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xe0\xa0\x81\xef\xbf\xbe\xef\xbf\xbf" },
+ { MUA, 0, "[^\\x{801}-\\x{fffe}]+", "\xe0\xa0\x81#\xc3\xa9\xf0\x90\x90\x80\xe0\xa0\x80\xef\xbf\xbf\xef\xbf\xbe" },
+ { MUA, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" },
+ { MUA, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" },
/* Unicode properties. */
{ MUAP, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" },
@@ -371,6 +392,10 @@ static struct regression_test_case regression_test_cases[] = {
{ PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },
{ PCRE_MULTILINE | PCRE_NEWLINE_CR, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },
{ PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{1,3}[^#]", "\r\n##...." },
+ { MUA | PCRE_NO_UTF8_CHECK, 1, "^.a", "\n\x80\nxa" },
+ { MUA, 1, "^", "\r\n" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 1 | F_NOMATCH, "^", "\r\n" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 1, "^", "\r\na" },
/* Any character except newline or any newline. */
{ PCRE_NEWLINE_CRLF, 0, ".", "\r" },
@@ -629,6 +654,7 @@ static struct regression_test_case regression_test_cases[] = {
{ PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" },
{ PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 1, ".", "\r\n" },
{ PCRE_FIRSTLINE | PCRE_NEWLINE_LF | PCRE_DOTALL, 0 | F_NOMATCH, "ab.", "ab" },
+ { MUA | PCRE_FIRSTLINE, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" },
/* Recurse. */
{ MUA, 0, "(a)(?1)", "aa" },
@@ -959,7 +985,7 @@ static int convert_utf8_to_utf16(const char *input, PCRE_UCHAR16 *output, int *o
if (offsetmap)
*offsetmap++ = (int)(iptr - (unsigned char*)input);
- if (!(*iptr & 0x80))
+ if (*iptr < 0xc0)
c = *iptr++;
else if (!(*iptr & 0x20)) {
c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);
@@ -1031,7 +1057,7 @@ static int convert_utf8_to_utf32(const char *input, PCRE_UCHAR32 *output, int *o
if (offsetmap)
*offsetmap++ = (int)(iptr - (unsigned char*)input);
- if (!(*iptr & 0x80))
+ if (*iptr < 0xc0)
c = *iptr++;
else if (!(*iptr & 0x20)) {
c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);
@@ -1092,7 +1118,7 @@ static int regression_tests(void)
const char *error;
char *cpu_info;
int i, err_offs;
- int is_successful, is_ascii_pattern, is_ascii_input;
+ int is_successful, is_ascii;
int total = 0;
int successful = 0;
int successful_row = 0;
@@ -1173,13 +1199,9 @@ static int regression_tests(void)
while (current->pattern) {
/* printf("\nPattern: %s :\n", current->pattern); */
total++;
- if (current->start_offset & F_PROPERTY) {
- is_ascii_pattern = 0;
- is_ascii_input = 0;
- } else {
- is_ascii_pattern = check_ascii(current->pattern);
- is_ascii_input = check_ascii(current->input);
- }
+ is_ascii = 0;
+ if (!(current->start_offset & F_PROPERTY))
+ is_ascii = check_ascii(current->pattern) && check_ascii(current->input);
if (current->flags & PCRE_PARTIAL_SOFT)
study_mode = PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE;
@@ -1211,7 +1233,7 @@ static int regression_tests(void)
re8 = NULL;
}
extra8->flags |= PCRE_EXTRA_MARK;
- } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO8))
+ } else if (((utf && ucp) || is_ascii) && !(current->start_offset & F_NO8))
printf("\n8 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error);
#endif
#ifdef SUPPORT_PCRE16
@@ -1242,7 +1264,7 @@ static int regression_tests(void)
re16 = NULL;
}
extra16->flags |= PCRE_EXTRA_MARK;
- } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO16))
+ } else if (((utf && ucp) || is_ascii) && !(current->start_offset & F_NO16))
printf("\n16 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error);
#endif
#ifdef SUPPORT_PCRE32
@@ -1273,7 +1295,7 @@ static int regression_tests(void)
re32 = NULL;
}
extra32->flags |= PCRE_EXTRA_MARK;
- } else if (((utf && ucp) || is_ascii_pattern) && !(current->start_offset & F_NO32))
+ } else if (((utf && ucp) || is_ascii) && !(current->start_offset & F_NO32))
printf("\n32 bit: Cannot compile pattern \"%s\": %s\n", current->pattern, error);
#endif
@@ -1305,10 +1327,10 @@ static int regression_tests(void)
if ((counter & 0x1) != 0) {
setstack8(extra8);
return_value8[0] = pcre_exec(re8, extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_1, 32);
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector8_1, 32);
} else
return_value8[0] = pcre_jit_exec(re8, extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_1, 32, getstack8());
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector8_1, 32, getstack8());
memset(&dummy_extra8, 0, sizeof(pcre_extra));
dummy_extra8.flags = PCRE_EXTRA_MARK;
if (current->start_offset & F_STUDY) {
@@ -1317,7 +1339,7 @@ static int regression_tests(void)
}
dummy_extra8.mark = &mark8_2;
return_value8[1] = pcre_exec(re8, &dummy_extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_2, 32);
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector8_2, 32);
}
#endif
@@ -1339,10 +1361,10 @@ static int regression_tests(void)
if ((counter & 0x1) != 0) {
setstack16(extra16);
return_value16[0] = pcre16_exec(re16, extra16, regtest_buf16, length16, current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_1, 32);
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector16_1, 32);
} else
return_value16[0] = pcre16_jit_exec(re16, extra16, regtest_buf16, length16, current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_1, 32, getstack16());
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector16_1, 32, getstack16());
memset(&dummy_extra16, 0, sizeof(pcre16_extra));
dummy_extra16.flags = PCRE_EXTRA_MARK;
if (current->start_offset & F_STUDY) {
@@ -1351,7 +1373,7 @@ static int regression_tests(void)
}
dummy_extra16.mark = &mark16_2;
return_value16[1] = pcre16_exec(re16, &dummy_extra16, regtest_buf16, length16, current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_2, 32);
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector16_2, 32);
}
#endif
@@ -1373,10 +1395,10 @@ static int regression_tests(void)
if ((counter & 0x1) != 0) {
setstack32(extra32);
return_value32[0] = pcre32_exec(re32, extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_1, 32);
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector32_1, 32);
} else
return_value32[0] = pcre32_jit_exec(re32, extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_1, 32, getstack32());
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector32_1, 32, getstack32());
memset(&dummy_extra32, 0, sizeof(pcre32_extra));
dummy_extra32.flags = PCRE_EXTRA_MARK;
if (current->start_offset & F_STUDY) {
@@ -1385,7 +1407,7 @@ static int regression_tests(void)
}
dummy_extra32.mark = &mark32_2;
return_value32[1] = pcre32_exec(re32, &dummy_extra32, regtest_buf32, length32, current->start_offset & OFFSET_MASK,
- current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector32_2, 32);
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | PCRE_NO_UTF8_CHECK), ovector32_2, 32);
}
#endif
@@ -1581,7 +1603,7 @@ static int regression_tests(void)
if (is_successful) {
#ifdef SUPPORT_PCRE8
- if (!(current->start_offset & F_NO8) && ((utf && ucp) || is_ascii_input)) {
+ if (!(current->start_offset & F_NO8) && ((utf && ucp) || is_ascii)) {
if (return_value8[0] < 0 && !(current->start_offset & F_NOMATCH)) {
printf("8 bit: Test should match: [%d] '%s' @ '%s'\n",
total, current->pattern, current->input);
@@ -1596,7 +1618,7 @@ static int regression_tests(void)
}
#endif
#ifdef SUPPORT_PCRE16
- if (!(current->start_offset & F_NO16) && ((utf && ucp) || is_ascii_input)) {
+ if (!(current->start_offset & F_NO16) && ((utf && ucp) || is_ascii)) {
if (return_value16[0] < 0 && !(current->start_offset & F_NOMATCH)) {
printf("16 bit: Test should match: [%d] '%s' @ '%s'\n",
total, current->pattern, current->input);
@@ -1611,7 +1633,7 @@ static int regression_tests(void)
}
#endif
#ifdef SUPPORT_PCRE32
- if (!(current->start_offset & F_NO32) && ((utf && ucp) || is_ascii_input)) {
+ if (!(current->start_offset & F_NO32) && ((utf && ucp) || is_ascii)) {
if (return_value32[0] < 0 && !(current->start_offset & F_NOMATCH)) {
printf("32 bit: Test should match: [%d] '%s' @ '%s'\n",
total, current->pattern, current->input);
diff --git a/pcre/pcre_printint.c b/pcre/pcre_printint.c
index e4ef152d071..60dcb55efbf 100644
--- a/pcre/pcre_printint.c
+++ b/pcre/pcre_printint.c
@@ -644,7 +644,9 @@ for(;;)
int i;
unsigned int min, max;
BOOL printmap;
+ BOOL invertmap = FALSE;
pcre_uint8 *map;
+ pcre_uint8 inverted_map[32];
fprintf(f, " [");
@@ -653,7 +655,12 @@ for(;;)
extra = GET(code, 1);
ccode = code + LINK_SIZE + 1;
printmap = (*ccode & XCL_MAP) != 0;
- if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
+ if ((*ccode & XCL_NOT) != 0)
+ {
+ invertmap = (*ccode & XCL_HASPROP) == 0;
+ fprintf(f, "^");
+ }
+ ccode++;
}
else
{
@@ -666,6 +673,12 @@ for(;;)
if (printmap)
{
map = (pcre_uint8 *)ccode;
+ if (invertmap)
+ {
+ for (i = 0; i < 32; i++) inverted_map[i] = ~map[i];
+ map = inverted_map;
+ }
+
for (i = 0; i < 256; i++)
{
if ((map[i/8] & (1 << (i&7))) != 0)
diff --git a/pcre/pcre_string_utils.c b/pcre/pcre_string_utils.c
index 10b53d5bcb4..25eacc85073 100644
--- a/pcre/pcre_string_utils.c
+++ b/pcre/pcre_string_utils.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-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -91,8 +91,8 @@ pcre_uchar c2;
while (*str1 != '\0' || *str2 != '\0')
{
- c1 = RAWUCHARINC(str1);
- c2 = RAWUCHARINC(str2);
+ c1 = UCHAR21INC(str1);
+ c2 = UCHAR21INC(str2);
if (c1 != c2)
return ((c1 > c2) << 1) - 1;
}
@@ -131,7 +131,7 @@ pcre_uchar c2;
while (*str1 != '\0' || *ustr2 != '\0')
{
- c1 = RAWUCHARINC(str1);
+ c1 = UCHAR21INC(str1);
c2 = (pcre_uchar)*ustr2++;
if (c1 != c2)
return ((c1 > c2) << 1) - 1;
diff --git a/pcre/pcre_stringpiece.h b/pcre/pcre_stringpiece.h
deleted file mode 100644
index 4ea32f62261..00000000000
--- a/pcre/pcre_stringpiece.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-//
-// A string like object that points into another piece of memory.
-// Useful for providing an interface that allows clients to easily
-// pass in either a "const char*" or a "string".
-//
-// Arghh! I wish C++ literals were automatically of type "string".
-
-#ifndef _PCRE_STRINGPIECE_H
-#define _PCRE_STRINGPIECE_H
-
-#include <cstring>
-#include <string>
-#include <iosfwd> // for ostream forward-declaration
-
-#if 0
-#define HAVE_TYPE_TRAITS
-#include <type_traits.h>
-#elif 0
-#define HAVE_TYPE_TRAITS
-#include <bits/type_traits.h>
-#endif
-
-#include <pcre.h>
-
-using std::memcmp;
-using std::strlen;
-using std::string;
-
-namespace pcrecpp {
-
-class PCRECPP_EXP_DEFN StringPiece {
- private:
- const char* ptr_;
- int length_;
-
- public:
- // We provide non-explicit singleton constructors so users can pass
- // in a "const char*" or a "string" wherever a "StringPiece" is
- // expected.
- StringPiece()
- : ptr_(NULL), length_(0) { }
- StringPiece(const char* str)
- : ptr_(str), length_(static_cast<int>(strlen(ptr_))) { }
- StringPiece(const unsigned char* str)
- : ptr_(reinterpret_cast<const char*>(str)),
- length_(static_cast<int>(strlen(ptr_))) { }
- StringPiece(const string& str)
- : ptr_(str.data()), length_(static_cast<int>(str.size())) { }
- StringPiece(const char* offset, int len)
- : ptr_(offset), length_(len) { }
-
- // data() may return a pointer to a buffer with embedded NULs, and the
- // returned buffer may or may not be null terminated. Therefore it is
- // typically a mistake to pass data() to a routine that expects a NUL
- // terminated string. Use "as_string().c_str()" if you really need to do
- // this. Or better yet, change your routine so it does not rely on NUL
- // termination.
- const char* data() const { return ptr_; }
- int size() const { return length_; }
- bool empty() const { return length_ == 0; }
-
- void clear() { ptr_ = NULL; length_ = 0; }
- void set(const char* buffer, int len) { ptr_ = buffer; length_ = len; }
- void set(const char* str) {
- ptr_ = str;
- length_ = static_cast<int>(strlen(str));
- }
- void set(const void* buffer, int len) {
- ptr_ = reinterpret_cast<const char*>(buffer);
- length_ = len;
- }
-
- char operator[](int i) const { return ptr_[i]; }
-
- void remove_prefix(int n) {
- ptr_ += n;
- length_ -= n;
- }
-
- void remove_suffix(int n) {
- length_ -= n;
- }
-
- bool operator==(const StringPiece& x) const {
- return ((length_ == x.length_) &&
- (memcmp(ptr_, x.ptr_, length_) == 0));
- }
- bool operator!=(const StringPiece& x) const {
- return !(*this == x);
- }
-
-#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \
- bool operator cmp (const StringPiece& x) const { \
- int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \
- return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \
- }
- STRINGPIECE_BINARY_PREDICATE(<, <);
- STRINGPIECE_BINARY_PREDICATE(<=, <);
- STRINGPIECE_BINARY_PREDICATE(>=, >);
- STRINGPIECE_BINARY_PREDICATE(>, >);
-#undef STRINGPIECE_BINARY_PREDICATE
-
- int compare(const StringPiece& x) const {
- int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_);
- if (r == 0) {
- if (length_ < x.length_) r = -1;
- else if (length_ > x.length_) r = +1;
- }
- return r;
- }
-
- string as_string() const {
- return string(data(), size());
- }
-
- void CopyToString(string* target) const {
- target->assign(ptr_, length_);
- }
-
- // Does "this" start with "x"
- bool starts_with(const StringPiece& x) const {
- return ((length_ >= x.length_) && (memcmp(ptr_, x.ptr_, x.length_) == 0));
- }
-};
-
-} // namespace pcrecpp
-
-// ------------------------------------------------------------------
-// Functions used to create STL containers that use StringPiece
-// Remember that a StringPiece's lifetime had better be less than
-// that of the underlying string or char*. If it is not, then you
-// cannot safely store a StringPiece into an STL container
-// ------------------------------------------------------------------
-
-#ifdef HAVE_TYPE_TRAITS
-// This makes vector<StringPiece> really fast for some STL implementations
-template<> struct __type_traits<pcrecpp::StringPiece> {
- typedef __true_type has_trivial_default_constructor;
- typedef __true_type has_trivial_copy_constructor;
- typedef __true_type has_trivial_assignment_operator;
- typedef __true_type has_trivial_destructor;
- typedef __true_type is_POD_type;
-};
-#endif
-
-// allow StringPiece to be logged
-std::ostream& operator<<(std::ostream& o, const pcrecpp::StringPiece& piece);
-
-#endif /* _PCRE_STRINGPIECE_H */
diff --git a/pcre/pcre_study.c b/pcre/pcre_study.c
index c2aff517a5d..ab9510e20ec 100644
--- a/pcre/pcre_study.c
+++ b/pcre/pcre_study.c
@@ -879,9 +879,6 @@ do
case OP_SOM:
case OP_THEN:
case OP_THEN_ARG:
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
-#endif
return SSB_FAIL;
/* We can ignore word boundary tests. */
@@ -1257,6 +1254,16 @@ do
with a value >= 0xc4 is a potentially valid starter because it starts a
character with a value > 255. */
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0)
+ return SSB_FAIL;
+ /* All bits are set. */
+ if ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0 && (tcode[1 + LINK_SIZE] & XCL_NOT) != 0)
+ return SSB_FAIL;
+#endif
+ /* Fall through */
+
case OP_NCLASS:
#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (utf)
@@ -1273,8 +1280,21 @@ do
case OP_CLASS:
{
pcre_uint8 *map;
- tcode++;
- map = (pcre_uint8 *)tcode;
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ map = NULL;
+ if (*tcode == OP_XCLASS)
+ {
+ if ((tcode[1 + LINK_SIZE] & XCL_MAP) != 0)
+ map = (pcre_uint8 *)(tcode + 1 + LINK_SIZE + 1);
+ tcode += GET(tcode, 1);
+ }
+ else
+#endif
+ {
+ tcode++;
+ map = (pcre_uint8 *)tcode;
+ tcode += 32 / sizeof(pcre_uchar);
+ }
/* In UTF-8 mode, the bits in a bit map correspond to character
values, not to byte values. However, the bit map we are constructing is
@@ -1282,31 +1302,35 @@ do
value is > 127. In fact, there are only two possible starting bytes for
characters in the range 128 - 255. */
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- if (utf)
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ if (map != NULL)
+#endif
{
- for (c = 0; c < 16; c++) start_bits[c] |= map[c];
- for (c = 128; c < 256; c++)
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
{
- if ((map[c/8] && (1 << (c&7))) != 0)
+ for (c = 0; c < 16; c++) start_bits[c] |= map[c];
+ for (c = 128; c < 256; c++)
{
- int d = (c >> 6) | 0xc0; /* Set bit for this starter */
- start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
- c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
+ if ((map[c/8] && (1 << (c&7))) != 0)
+ {
+ int d = (c >> 6) | 0xc0; /* Set bit for this starter */
+ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
+ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
+ }
}
}
- }
- else
+ else
#endif
- {
- /* In non-UTF-8 mode, the two bit maps are completely compatible. */
- for (c = 0; c < 32; c++) start_bits[c] |= map[c];
+ {
+ /* In non-UTF-8 mode, the two bit maps are completely compatible. */
+ for (c = 0; c < 32; c++) start_bits[c] |= map[c];
+ }
}
/* Advance past the bit map, and act on what follows. For a zero
minimum repeat, continue; otherwise stop processing. */
- tcode += 32 / sizeof(pcre_uchar);
switch (*tcode)
{
case OP_CRSTAR:
diff --git a/pcre/pcre_xclass.c b/pcre/pcre_xclass.c
index ad153be7851..c2b61f0f920 100644
--- a/pcre/pcre_xclass.c
+++ b/pcre/pcre_xclass.c
@@ -81,6 +81,11 @@ additional data. */
if (c < 256)
{
+ if ((*data & XCL_HASPROP) == 0)
+ {
+ if ((*data & XCL_MAP) == 0) return negated;
+ return (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0;
+ }
if ((*data & XCL_MAP) != 0 &&
(((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0)
return !negated; /* char found */
diff --git a/pcre/pcrecpparg.h b/pcre/pcrecpparg.h
deleted file mode 100644
index b4f9c3f4989..00000000000
--- a/pcre/pcrecpparg.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: Sanjay Ghemawat
-
-#ifndef _PCRECPPARG_H
-#define _PCRECPPARG_H
-
-#include <stdlib.h> // for NULL
-#include <string>
-
-#include <pcre.h>
-
-namespace pcrecpp {
-
-class StringPiece;
-
-// Hex/Octal/Binary?
-
-// Special class for parsing into objects that define a ParseFrom() method
-template <class T>
-class _RE_MatchObject {
- public:
- static inline bool Parse(const char* str, int n, void* dest) {
- if (dest == NULL) return true;
- T* object = reinterpret_cast<T*>(dest);
- return object->ParseFrom(str, n);
- }
-};
-
-class PCRECPP_EXP_DEFN Arg {
- public:
- // Empty constructor so we can declare arrays of Arg
- Arg();
-
- // Constructor specially designed for NULL arguments
- Arg(void*);
-
- typedef bool (*Parser)(const char* str, int n, void* dest);
-
-// Type-specific parsers
-#define PCRE_MAKE_PARSER(type,name) \
- Arg(type* p) : arg_(p), parser_(name) { } \
- Arg(type* p, Parser parser) : arg_(p), parser_(parser) { }
-
-
- PCRE_MAKE_PARSER(char, parse_char);
- PCRE_MAKE_PARSER(unsigned char, parse_uchar);
- PCRE_MAKE_PARSER(short, parse_short);
- PCRE_MAKE_PARSER(unsigned short, parse_ushort);
- PCRE_MAKE_PARSER(int, parse_int);
- PCRE_MAKE_PARSER(unsigned int, parse_uint);
- PCRE_MAKE_PARSER(long, parse_long);
- PCRE_MAKE_PARSER(unsigned long, parse_ulong);
-#if 1
- PCRE_MAKE_PARSER(long long, parse_longlong);
-#endif
-#if 1
- PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong);
-#endif
- PCRE_MAKE_PARSER(float, parse_float);
- PCRE_MAKE_PARSER(double, parse_double);
- PCRE_MAKE_PARSER(std::string, parse_string);
- PCRE_MAKE_PARSER(StringPiece, parse_stringpiece);
-
-#undef PCRE_MAKE_PARSER
-
- // Generic constructor
- template <class T> Arg(T*, Parser parser);
- // Generic constructor template
- template <class T> Arg(T* p)
- : arg_(p), parser_(_RE_MatchObject<T>::Parse) {
- }
-
- // Parse the data
- bool Parse(const char* str, int n) const;
-
- private:
- void* arg_;
- Parser parser_;
-
- static bool parse_null (const char* str, int n, void* dest);
- static bool parse_char (const char* str, int n, void* dest);
- static bool parse_uchar (const char* str, int n, void* dest);
- static bool parse_float (const char* str, int n, void* dest);
- static bool parse_double (const char* str, int n, void* dest);
- static bool parse_string (const char* str, int n, void* dest);
- static bool parse_stringpiece (const char* str, int n, void* dest);
-
-#define PCRE_DECLARE_INTEGER_PARSER(name) \
- private: \
- static bool parse_ ## name(const char* str, int n, void* dest); \
- static bool parse_ ## name ## _radix( \
- const char* str, int n, void* dest, int radix); \
- public: \
- static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \
- static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \
- static bool parse_ ## name ## _cradix(const char* str, int n, void* dest)
-
- PCRE_DECLARE_INTEGER_PARSER(short);
- PCRE_DECLARE_INTEGER_PARSER(ushort);
- PCRE_DECLARE_INTEGER_PARSER(int);
- PCRE_DECLARE_INTEGER_PARSER(uint);
- PCRE_DECLARE_INTEGER_PARSER(long);
- PCRE_DECLARE_INTEGER_PARSER(ulong);
- PCRE_DECLARE_INTEGER_PARSER(longlong);
- PCRE_DECLARE_INTEGER_PARSER(ulonglong);
-
-#undef PCRE_DECLARE_INTEGER_PARSER
-};
-
-inline Arg::Arg() : arg_(NULL), parser_(parse_null) { }
-inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
-
-inline bool Arg::Parse(const char* str, int n) const {
- return (*parser_)(str, n, arg_);
-}
-
-// This part of the parser, appropriate only for ints, deals with bases
-#define MAKE_INTEGER_PARSER(type, name) \
- inline Arg Hex(type* ptr) { \
- return Arg(ptr, Arg::parse_ ## name ## _hex); } \
- inline Arg Octal(type* ptr) { \
- return Arg(ptr, Arg::parse_ ## name ## _octal); } \
- inline Arg CRadix(type* ptr) { \
- return Arg(ptr, Arg::parse_ ## name ## _cradix); }
-
-MAKE_INTEGER_PARSER(short, short) /* */
-MAKE_INTEGER_PARSER(unsigned short, ushort) /* */
-MAKE_INTEGER_PARSER(int, int) /* Don't use semicolons */
-MAKE_INTEGER_PARSER(unsigned int, uint) /* after these statement */
-MAKE_INTEGER_PARSER(long, long) /* because they can cause */
-MAKE_INTEGER_PARSER(unsigned long, ulong) /* compiler warnings if */
-#if 1 /* the checking level is */
-MAKE_INTEGER_PARSER(long long, longlong) /* turned up high enough. */
-#endif /* */
-#if 1 /* */
-MAKE_INTEGER_PARSER(unsigned long long, ulonglong) /* */
-#endif
-
-#undef PCRE_IS_SET
-#undef PCRE_SET_OR_CLEAR
-#undef MAKE_INTEGER_PARSER
-
-} // namespace pcrecpp
-
-
-#endif /* _PCRECPPARG_H */
diff --git a/pcre/pcregrep.c b/pcre/pcregrep.c
index f6b6ec39608..3e8d05dc8ad 100644
--- a/pcre/pcregrep.c
+++ b/pcre/pcregrep.c
@@ -12,7 +12,7 @@ distribution because other apparatus is needed to compile pcregrep for z/OS.
The header can be found in the special z/OS distribution, which is available
from www.zaconsultants.net or from www.cbttape.org.
- Copyright (c) 1997-2013 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -1298,7 +1298,7 @@ switch(endlinetype)
while (p > startptr && p[-1] != '\n') p--;
if (p <= startptr + 1 || p[-2] == '\r') return p;
}
- return p; /* But control should never get here */
+ /* Control can never get here */
case EL_ANY:
case EL_ANYCRLF:
diff --git a/pcre/pcreposix.c b/pcre/pcreposix.c
index 7cf4a4a657b..ed506197a53 100644
--- a/pcre/pcreposix.c
+++ b/pcre/pcreposix.c
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
+ Copyright (c) 1997-2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -170,7 +170,9 @@ static const int eint[] = {
REG_BADPAT, /* missing opening brace after \o */
REG_BADPAT, /* parentheses too deeply nested */
REG_BADPAT, /* invalid range in character class */
- REG_BADPAT /* group name must start with a non-digit */
+ REG_BADPAT, /* group name must start with a non-digit */
+ /* 85 */
+ REG_BADPAT /* parentheses too deeply nested (stack check) */
};
/* Table of texts corresponding to POSIX error codes */
diff --git a/pcre/pcretest.c b/pcre/pcretest.c
index 8452d2bab6f..b8dc3c67032 100644
--- a/pcre/pcretest.c
+++ b/pcre/pcretest.c
@@ -233,6 +233,9 @@ argument, the casting might be incorrectly applied. */
#define SET_PCRE_CALLOUT8(callout) \
pcre_callout = callout
+#define SET_PCRE_STACK_GUARD8(stack_guard) \
+ pcre_stack_guard = stack_guard
+
#define PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) \
pcre_assign_jit_stack(extra, callback, userdata)
@@ -317,6 +320,9 @@ argument, the casting might be incorrectly applied. */
#define SET_PCRE_CALLOUT16(callout) \
pcre16_callout = (int (*)(pcre16_callout_block *))callout
+#define SET_PCRE_STACK_GUARD16(stack_guard) \
+ pcre16_stack_guard = (int (*)(void))stack_guard
+
#define PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata) \
pcre16_assign_jit_stack((pcre16_extra *)extra, \
(pcre16_jit_callback)callback, userdata)
@@ -406,6 +412,9 @@ argument, the casting might be incorrectly applied. */
#define SET_PCRE_CALLOUT32(callout) \
pcre32_callout = (int (*)(pcre32_callout_block *))callout
+#define SET_PCRE_STACK_GUARD32(stack_guard) \
+ pcre32_stack_guard = (int (*)(void))stack_guard
+
#define PCRE_ASSIGN_JIT_STACK32(extra, callback, userdata) \
pcre32_assign_jit_stack((pcre32_extra *)extra, \
(pcre32_jit_callback)callback, userdata)
@@ -533,6 +542,14 @@ cases separately. */
else \
SET_PCRE_CALLOUT8(callout)
+#define SET_PCRE_STACK_GUARD(stack_guard) \
+ if (pcre_mode == PCRE32_MODE) \
+ SET_PCRE_STACK_GUARD32(stack_guard); \
+ else if (pcre_mode == PCRE16_MODE) \
+ SET_PCRE_STACK_GUARD16(stack_guard); \
+ else \
+ SET_PCRE_STACK_GUARD8(stack_guard)
+
#define STRLEN(p) (pcre_mode == PCRE32_MODE ? STRLEN32(p) : pcre_mode == PCRE16_MODE ? STRLEN16(p) : STRLEN8(p))
#define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \
@@ -756,6 +773,12 @@ the three different cases. */
else \
G(SET_PCRE_CALLOUT,BITTWO)(callout)
+#define SET_PCRE_STACK_GUARD(stack_guard) \
+ if (pcre_mode == G(G(PCRE,BITONE),_MODE)) \
+ G(SET_PCRE_STACK_GUARD,BITONE)(stack_guard); \
+ else \
+ G(SET_PCRE_STACK_GUARD,BITTWO)(stack_guard)
+
#define STRLEN(p) ((pcre_mode == G(G(PCRE,BITONE),_MODE)) ? \
G(STRLEN,BITONE)(p) : G(STRLEN,BITTWO)(p))
@@ -897,6 +920,7 @@ the three different cases. */
#define PCHARSV PCHARSV8
#define READ_CAPTURE_NAME READ_CAPTURE_NAME8
#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT8
+#define SET_PCRE_STACK_GUARD SET_PCRE_STACK_GUARD8
#define STRLEN STRLEN8
#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK8
#define PCRE_COMPILE PCRE_COMPILE8
@@ -927,6 +951,7 @@ the three different cases. */
#define PCHARSV PCHARSV16
#define READ_CAPTURE_NAME READ_CAPTURE_NAME16
#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT16
+#define SET_PCRE_STACK_GUARD SET_PCRE_STACK_GUARD16
#define STRLEN STRLEN16
#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK16
#define PCRE_COMPILE PCRE_COMPILE16
@@ -957,6 +982,7 @@ the three different cases. */
#define PCHARSV PCHARSV32
#define READ_CAPTURE_NAME READ_CAPTURE_NAME32
#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT32
+#define SET_PCRE_STACK_GUARD SET_PCRE_STACK_GUARD32
#define STRLEN STRLEN32
#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK32
#define PCRE_COMPILE PCRE_COMPILE32
@@ -1015,6 +1041,7 @@ static int first_callout;
static int jit_was_used;
static int locale_set = 0;
static int show_malloc;
+static int stack_guard_return;
static int use_utf;
static const unsigned char *last_callout_mark = NULL;
@@ -2201,6 +2228,18 @@ return p;
/*************************************************
+* Stack guard function *
+*************************************************/
+
+/* Called from PCRE when set in pcre_stack_guard. We give an error (non-zero)
+return when a count overflows. */
+
+static int stack_guard(void)
+{
+return stack_guard_return;
+}
+
+/*************************************************
* Callout function *
*************************************************/
@@ -2883,8 +2922,8 @@ printf(" -32 use the 32-bit library\n");
#endif
printf(" -b show compiled code\n");
printf(" -C show PCRE compile-time options and exit\n");
-printf(" -C arg show a specific compile-time option\n");
-printf(" and exit with its value. The arg can be:\n");
+printf(" -C arg show a specific compile-time option and exit\n");
+printf(" with its value if numeric (else 0). The arg can be:\n");
printf(" linksize internal link size [2, 3, 4]\n");
printf(" pcre8 8 bit library support enabled [0, 1]\n");
printf(" pcre16 16 bit library support enabled [0, 1]\n");
@@ -2892,7 +2931,8 @@ printf(" pcre32 32 bit library support enabled [0, 1]\n");
printf(" utf Unicode Transformation Format supported [0, 1]\n");
printf(" ucp Unicode Properties supported [0, 1]\n");
printf(" jit Just-in-time compiler supported [0, 1]\n");
-printf(" newline Newline type [CR, LF, CRLF, ANYCRLF, ANY, ???]\n");
+printf(" newline Newline type [CR, LF, CRLF, ANYCRLF, ANY]\n");
+printf(" bsr \\R type [ANYCRLF, ANY]\n");
printf(" -d debug: show compiled code and information (-b and -i)\n");
#if !defined NODFA
printf(" -dfa force DFA matching for all subjects\n");
@@ -3231,6 +3271,11 @@ while (argc > 1 && argv[op][0] == '-')
(void)PCRE_CONFIG(PCRE_CONFIG_NEWLINE, &rc);
print_newline_config(rc, TRUE);
}
+ else if (strcmp(argv[op + 1], "bsr") == 0)
+ {
+ (void)PCRE_CONFIG(PCRE_CONFIG_BSR, &rc);
+ printf("%s\n", rc? "ANYCRLF" : "ANY");
+ }
else if (strcmp(argv[op + 1], "ebcdic") == 0)
{
#ifdef EBCDIC
@@ -3439,6 +3484,7 @@ while (!done)
use_utf = 0;
debug_lengths = 1;
+ SET_PCRE_STACK_GUARD(NULL);
if (extend_inputline(infile, buffer, " re> ") == NULL) break;
if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);
@@ -3739,6 +3785,21 @@ while (!done)
case 'P': do_posix = 1; break;
#endif
+ case 'Q':
+ switch (*pp)
+ {
+ case '0':
+ case '1':
+ stack_guard_return = *pp++ - '0';
+ break;
+
+ default:
+ fprintf(outfile, "** Missing 0 or 1 after /Q\n");
+ goto SKIP_DATA;
+ }
+ SET_PCRE_STACK_GUARD(stack_guard);
+ break;
+
case 'S':
do_study = 1;
for (;;)
@@ -4282,12 +4343,12 @@ while (!done)
if (new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits) == 0)
{
if (start_bits == NULL)
- fprintf(outfile, "No set of starting bytes\n");
+ fprintf(outfile, "No starting char list\n");
else
{
int i;
int c = 24;
- fprintf(outfile, "Starting byte set: ");
+ fprintf(outfile, "Starting chars: ");
for (i = 0; i < 256; i++)
{
if ((start_bits[i/8] & (1<<(i&7))) != 0)
@@ -5192,7 +5253,8 @@ while (!done)
if (count * 2 > use_size_offsets) count = use_size_offsets/2;
}
- /* Output the captured substrings */
+ /* Output the captured substrings. Note that, for the matched string,
+ the use of \K in an assertion can make the start later than the end. */
for (i = 0; i < count * 2; i += 2)
{
@@ -5208,11 +5270,25 @@ while (!done)
}
else
{
+ int start = use_offsets[i];
+ int end = use_offsets[i+1];
+
+ if (start > end)
+ {
+ start = use_offsets[i+1];
+ end = use_offsets[i];
+ fprintf(outfile, "Start of matched string is beyond its end - "
+ "displaying from end to start.\n");
+ }
+
fprintf(outfile, "%2d: ", i/2);
- PCHARSV(bptr, use_offsets[i],
- use_offsets[i+1] - use_offsets[i], outfile);
+ PCHARSV(bptr, start, end - start, outfile);
if (verify_jit && jit_was_used) fprintf(outfile, " (JIT)");
fprintf(outfile, "\n");
+
+ /* Note: don't use the start/end variables here because we want to
+ show the text from what is reported as the end. */
+
if (do_showcaprest || (i == 0 && do_showrest))
{
fprintf(outfile, "%2d+ ", i/2);
diff --git a/pcre/testdata/saved16BE-1 b/pcre/testdata/saved16BE-1
index e6edddc6e0b..5d2bd1be528 100644
--- a/pcre/testdata/saved16BE-1
+++ b/pcre/testdata/saved16BE-1
Binary files differ
diff --git a/pcre/testdata/saved16LE-1 b/pcre/testdata/saved16LE-1
index 5035ec07215..822ccd7012a 100644
--- a/pcre/testdata/saved16LE-1
+++ b/pcre/testdata/saved16LE-1
Binary files differ
diff --git a/pcre/testdata/saved32BE-1 b/pcre/testdata/saved32BE-1
index b4c2ffe42cc..609d97cdeba 100644
--- a/pcre/testdata/saved32BE-1
+++ b/pcre/testdata/saved32BE-1
Binary files differ
diff --git a/pcre/testdata/saved32LE-1 b/pcre/testdata/saved32LE-1
index 49392b89a10..901dfb63487 100644
--- a/pcre/testdata/saved32LE-1
+++ b/pcre/testdata/saved32LE-1
Binary files differ
diff --git a/pcre/testdata/testinput18 b/pcre/testdata/testinput18
index abff34e73a5..2dfb54cdfd4 100644
--- a/pcre/testdata/testinput18
+++ b/pcre/testdata/testinput18
@@ -207,7 +207,7 @@ correctly, but that messes up comparisons). --/
CDBABC
\x{2000}ABC
-/\R*A/SI8
+/\R*A/SI8<bsr_unicode>
CDBABC
\x{2028}A
diff --git a/pcre/testdata/testinput2 b/pcre/testdata/testinput2
index 00924ee98fa..da6e61499cd 100644
--- a/pcre/testdata/testinput2
+++ b/pcre/testdata/testinput2
@@ -907,6 +907,9 @@
/\U/I
+/a{1,3}b/U
+ ab
+
/[/I
/[a-/I
@@ -4045,4 +4048,18 @@ backtracking verbs. --/
/[a[:<:]] should give error/
+/(?=ab\K)/+
+ abcd
+
+/abcd/f<lf>
+ xx\nxabcd
+
+/ -- Test stack check external calls --/
+
+/(((((a)))))/Q0
+
+/(((((a)))))/Q1
+
+/(((((a)))))/Q
+
/-- End of testinput2 --/
diff --git a/pcre/testdata/testinput25 b/pcre/testdata/testinput25
index ce9d9e19a40..067ca12fdc0 100644
--- a/pcre/testdata/testinput25
+++ b/pcre/testdata/testinput25
@@ -1,6 +1,6 @@
/-- Tests for the 32-bit library only */
-< forbid 8w
+< forbid 8W
/-- Check maximum character size --/
diff --git a/pcre/testdata/testinput3 b/pcre/testdata/testinput3
index 1d2e855386a..fcd46255c93 100644
--- a/pcre/testdata/testinput3
+++ b/pcre/testdata/testinput3
@@ -1,7 +1,10 @@
-/-- This set of tests checks local-specific features, using the fr_FR locale.
- It is not Perl-compatible. There is different version called wintestinput3
- f or use on Windows, where the locale is called "french". --/
-
+/-- This set of tests checks local-specific features, using the "fr_FR" locale.
+ It is not Perl-compatible. When run via RunTest, the locale is edited to
+ be whichever of "fr_FR", "french", or "fr" is found to exist. There is
+ different version of this file called wintestinput3 for use on Windows,
+ where the locale is called "french" and the tests are run using
+ RunTest.bat. --/
+
< forbid 8W
/^[\w]+/
diff --git a/pcre/testdata/testinput4 b/pcre/testdata/testinput4
index 983f7a119b5..0110267bd80 100644
--- a/pcre/testdata/testinput4
+++ b/pcre/testdata/testinput4
@@ -716,4 +716,10 @@
/^a+[a\x{200}]/8
aa
+/^.\B.\B./8
+ \x{10123}\x{10124}\x{10125}
+
+/^#[^\x{ffff}]#[^\x{ffff}]#[^\x{ffff}]#/8
+ #\x{10000}#\x{100}#\x{10ffff}#
+
/-- End of testinput4 --/
diff --git a/pcre/testdata/testinput5 b/pcre/testdata/testinput5
index 9e9a22a1a1f..e36b09d6377 100644
--- a/pcre/testdata/testinput5
+++ b/pcre/testdata/testinput5
@@ -788,4 +788,6 @@
/^a+[a\x{200}]/8BZ
aa
+/[b-d\x{200}-\x{250}]*[ae-h]?#[\x{200}-\x{250}]{0,8}[\x00-\xff]*#[\x{200}-\x{250}]+[a-z]/8BZ
+
/-- End of testinput5 --/
diff --git a/pcre/testdata/testinput6 b/pcre/testdata/testinput6
index 1e450be04d3..7a6a53f1473 100644
--- a/pcre/testdata/testinput6
+++ b/pcre/testdata/testinput6
@@ -1484,4 +1484,13 @@
\x{a1}\x{a7}
\x{37e}
+/[RST]+/8iW
+ Ss\x{17f}
+
+/[R-T]+/8iW
+ Ss\x{17f}
+
+/[q-u]+/8iW
+ Ss\x{17f}
+
/-- End of testinput6 --/
diff --git a/pcre/testdata/testinput7 b/pcre/testdata/testinput7
index 9d145436350..6bd05864411 100644
--- a/pcre/testdata/testinput7
+++ b/pcre/testdata/testinput7
@@ -829,4 +829,10 @@ of case for anything other than the ASCII letters. --/
/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ
+/[RST]+/8iWBZ
+
+/[R-T]+/8iWBZ
+
+/[Q-U]+/8iWBZ
+
/-- End of testinput7 --/
diff --git a/pcre/testdata/testoutput12 b/pcre/testdata/testoutput12
index a76e2aef880..67ad2c8aecf 100644
--- a/pcre/testdata/testoutput12
+++ b/pcre/testdata/testoutput12
@@ -8,7 +8,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
JIT study was successful
/(?(?C1)(?=a)a)/S+I
@@ -27,7 +27,7 @@ No options
No first char
No need char
Subject length lower bound = -1
-No set of starting bytes
+No starting char list
JIT study was not successful
/abc/S+I>testsavedregex
@@ -36,7 +36,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
JIT study was successful
Compiled pattern written to testsavedregex
Study data written to testsavedregex
@@ -165,7 +165,7 @@ No options
First char = 'a'
Need char = 'd'
Subject length lower bound = 4
-No set of starting bytes
+No starting char list
JIT study was successful
/(*NO_START_OPT)a(*:m)b/KS++
diff --git a/pcre/testdata/testoutput13 b/pcre/testdata/testoutput13
index 9f73c5000f6..d6fb8a5ca29 100644
--- a/pcre/testdata/testoutput13
+++ b/pcre/testdata/testoutput13
@@ -8,7 +8,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
JIT support is not available in this version of PCRE
/a*/SI
diff --git a/pcre/testdata/testoutput14 b/pcre/testdata/testoutput14
index 52680a8f9cd..ae85681e0e0 100644
--- a/pcre/testdata/testoutput14
+++ b/pcre/testdata/testoutput14
@@ -361,7 +361,7 @@ Options: extended
No first char
No need char
Subject length lower bound = 3
-Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8
+Starting chars: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8
9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e
f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f
@@ -388,7 +388,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x20 \xa0
+Starting chars: \x09 \x20 \xa0
/\H/SI
Capturing subpattern count = 0
@@ -396,7 +396,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\v/SI
Capturing subpattern count = 0
@@ -404,7 +404,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85
+Starting chars: \x0a \x0b \x0c \x0d \x85
/\V/SI
Capturing subpattern count = 0
@@ -412,7 +412,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\R/SI
Capturing subpattern count = 0
@@ -420,7 +420,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85
+Starting chars: \x0a \x0b \x0c \x0d \x85
/[\h]/BZ
------------------------------------------------------------------
diff --git a/pcre/testdata/testoutput15 b/pcre/testdata/testoutput15
index 5792be72df7..5af369d06d9 100644
--- a/pcre/testdata/testoutput15
+++ b/pcre/testdata/testoutput15
@@ -481,7 +481,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
\x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
\x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4
5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y
@@ -519,7 +519,7 @@ Options: utf
First char = \x{c4}
Need char = \x{80}
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
\x{100}\x{100}\x{100}\x{100\x{100}
0: \x{100}\x{100}\x{100}
@@ -539,7 +539,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x \xc4
+Starting chars: x \xc4
/(\x{100}*a|x)/8SDZ
------------------------------------------------------------------
@@ -558,7 +558,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a x \xc4
+Starting chars: a x \xc4
/(\x{100}{0,2}a|x)/8SDZ
------------------------------------------------------------------
@@ -577,7 +577,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a x \xc4
+Starting chars: a x \xc4
/(\x{100}{1,2}a|x)/8SDZ
------------------------------------------------------------------
@@ -597,7 +597,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x \xc4
+Starting chars: x \xc4
/\x{100}/8DZ
------------------------------------------------------------------
@@ -799,7 +799,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3
+Starting chars: \x09 \x20 \xc2 \xe1 \xe2 \xe3
ABC\x{09}
0: \x{09}
ABC\x{20}
@@ -825,7 +825,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2
+Starting chars: \x0a \x0b \x0c \x0d \xc2 \xe2
ABC\x{0a}
0: \x{0a}
ABC\x{0b}
@@ -845,7 +845,7 @@ Options: utf
No first char
Need char = 'A'
Subject length lower bound = 1
-Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3
+Starting chars: \x09 \x20 A \xc2 \xe1 \xe2 \xe3
CDBABC
0: A
@@ -855,7 +855,7 @@ Options: utf
No first char
Need char = 'A'
Subject length lower bound = 2
-Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2
+Starting chars: \x0a \x0b \x0c \x0d \xc2 \xe2
/\s?xxx\s/8SI
Capturing subpattern count = 0
@@ -863,7 +863,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 4
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x
/\sxxx\s/I8ST1
Capturing subpattern count = 0
@@ -871,7 +871,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 5
-Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2
+Starting chars: \x09 \x0a \x0c \x0d \x20 \xc2
AB\x{85}xxx\x{a0}XYZ
0: \x{85}xxx\x{a0}
AB\x{a0}xxx\x{85}XYZ
@@ -883,7 +883,7 @@ Options: utf
No first char
Need char = ' '
Subject length lower bound = 3
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
\x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
\x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e
@@ -917,7 +917,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \xe1
+Starting chars: \xe1
/\x{1234}+?/iS8I
Capturing subpattern count = 0
@@ -925,7 +925,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \xe1
+Starting chars: \xe1
/\x{1234}++/iS8I
Capturing subpattern count = 0
@@ -933,7 +933,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \xe1
+Starting chars: \xe1
/\x{1234}{2}/iS8I
Capturing subpattern count = 0
@@ -941,7 +941,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 2
-Starting byte set: \xe1
+Starting chars: \xe1
/[^\x{c4}]/8DZ
------------------------------------------------------------------
@@ -974,7 +974,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2
+Starting chars: \x0a \x0b \x0c \x0d \xc2 \xe2
/\777/8DZ
------------------------------------------------------------------
diff --git a/pcre/testdata/testoutput16 b/pcre/testdata/testoutput16
index 1d5f31d929a..63e9eb06ae6 100644
--- a/pcre/testdata/testoutput16
+++ b/pcre/testdata/testoutput16
@@ -64,7 +64,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 17
-Starting byte set: \xd0 \xd1
+Starting chars: \xd0 \xd1
\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
\x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
@@ -92,7 +92,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x20 \xa0
+Starting chars: \x09 \x20 \xa0
/\v/SI
Capturing subpattern count = 0
@@ -100,7 +100,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85
+Starting chars: \x0a \x0b \x0c \x0d \x85
/\R/SI
Capturing subpattern count = 0
@@ -108,7 +108,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85
+Starting chars: \x0a \x0b \x0c \x0d \x85
/[[:blank:]]/WBZ
------------------------------------------------------------------
diff --git a/pcre/testdata/testoutput17 b/pcre/testdata/testoutput17
index 9a469c51ae1..1a3b492fb49 100644
--- a/pcre/testdata/testoutput17
+++ b/pcre/testdata/testoutput17
@@ -228,7 +228,7 @@ Options: extended
No first char
No need char
Subject length lower bound = 3
-Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8
+Starting chars: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8
9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e
f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xff
@@ -274,7 +274,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x20 \xa0 \xff
+Starting chars: \x09 \x20 \xa0 \xff
\x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000}
0: \x{1680}\x{2000}\x{202f}\x{3000}
\x{3001}\x{2fff}\x{200a}\xa0\x{2000}
@@ -292,7 +292,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+Starting chars: \x09 \x20 \xa0 \xff
\x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000}
0: \x{1680}\x{2000}\x{202f}\x{3000}
\x{3001}\x{2fff}\x{200a}\xa0\x{2000}
@@ -304,7 +304,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
\x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f}
0: \x{167f}\x{1681}\x{180d}\x{180f}
\x{2000}\x{200a}\x{1fff}\x{200b}
@@ -330,7 +330,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
\x{2027}\x{2030}\x{2028}\x{2029}
0: \x{2028}\x{2029}
\x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
@@ -348,7 +348,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
\x{2027}\x{2030}\x{2028}\x{2029}
0: \x{2028}\x{2029}
\x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
@@ -360,7 +360,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
\x{2028}\x{2029}\x{2027}\x{2030}
0: \x{2027}\x{2030}
\x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86
@@ -378,7 +378,7 @@ Options: bsr_unicode
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
\x{2027}\x{2030}\x{2028}\x{2029}
0: \x{2028}\x{2029}
\x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
@@ -534,18 +534,18 @@ MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789AB
------------------------------------------------------------------
Bra
a*
- [b-\x{200}]?+
+ [b-\xff\x{100}-\x{200}]?+
a#
a*+
- [b-\x{200}]?
+ [b-\xff\x{100}-\x{200}]?
b#
- [a-f]*
- [g-\x{200}]*+
+ [a-f]*+
+ [g-\xff\x{100}-\x{200}]*+
#
- [g-\x{200}]*
+ [g-\xff\x{100}-\x{200}]*+
[a-c]*+
#
- [g-\x{200}]*
+ [g-\xff\x{100}-\x{200}]*
[a-h]*+
Ket
End
diff --git a/pcre/testdata/testoutput18-16 b/pcre/testdata/testoutput18-16
index 1ca9ee74018..a1962057050 100644
--- a/pcre/testdata/testoutput18-16
+++ b/pcre/testdata/testoutput18-16
@@ -339,7 +339,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
\x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
\x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4
5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y
@@ -378,7 +378,7 @@ Options: utf
First char = \x{100}
Need char = \x{100}
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
\x{100}\x{100}\x{100}\x{100\x{100}
0: \x{100}\x{100}\x{100}
@@ -398,7 +398,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x \xff
+Starting chars: x \xff
/(\x{100}*a|x)/8SDZ
------------------------------------------------------------------
@@ -417,7 +417,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a x \xff
+Starting chars: a x \xff
/(\x{100}{0,2}a|x)/8SDZ
------------------------------------------------------------------
@@ -436,7 +436,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a x \xff
+Starting chars: a x \xff
/(\x{100}{1,2}a|x)/8SDZ
------------------------------------------------------------------
@@ -456,7 +456,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x \xff
+Starting chars: x \xff
/\x{100}/8DZ
------------------------------------------------------------------
@@ -666,7 +666,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x20 \xa0 \xff
+Starting chars: \x09 \x20 \xa0 \xff
ABC\x{09}
0: \x{09}
ABC\x{20}
@@ -692,7 +692,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
ABC\x{0a}
0: \x{0a}
ABC\x{0b}
@@ -712,19 +712,19 @@ Options: utf
No first char
Need char = 'A'
Subject length lower bound = 1
-Starting byte set: \x09 \x20 A \xa0 \xff
+Starting chars: \x09 \x20 A \xa0 \xff
CDBABC
0: A
\x{2000}ABC
0: \x{2000}A
-/\R*A/SI8
+/\R*A/SI8<bsr_unicode>
Capturing subpattern count = 0
-Options: utf
+Options: bsr_unicode utf
No first char
Need char = 'A'
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d A \x85 \xff
CDBABC
0: A
\x{2028}A
@@ -736,7 +736,7 @@ Options: utf
No first char
Need char = 'A'
Subject length lower bound = 2
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
/\s?xxx\s/8SI
Capturing subpattern count = 0
@@ -744,7 +744,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 4
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x
/\sxxx\s/I8ST1
Capturing subpattern count = 0
@@ -752,7 +752,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 5
-Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0
+Starting chars: \x09 \x0a \x0c \x0d \x20 \x85 \xa0
AB\x{85}xxx\x{a0}XYZ
0: \x{85}xxx\x{a0}
AB\x{a0}xxx\x{85}XYZ
@@ -764,7 +764,7 @@ Options: utf
No first char
Need char = ' '
Subject length lower bound = 3
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
\x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
\x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e
@@ -803,7 +803,7 @@ Options: caseless utf
First char = \x{1234}
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\x{1234}+?/iS8I
Capturing subpattern count = 0
@@ -811,7 +811,7 @@ Options: caseless utf
First char = \x{1234}
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\x{1234}++/iS8I
Capturing subpattern count = 0
@@ -819,7 +819,7 @@ Options: caseless utf
First char = \x{1234}
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\x{1234}{2}/iS8I
Capturing subpattern count = 0
@@ -827,7 +827,7 @@ Options: caseless utf
First char = \x{1234}
Need char = \x{1234}
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
/[^\x{c4}]/8DZ
------------------------------------------------------------------
@@ -860,7 +860,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
/-- Check bad offset --/
diff --git a/pcre/testdata/testoutput18-32 b/pcre/testdata/testoutput18-32
index 89be3a4b051..1525994db98 100644
--- a/pcre/testdata/testoutput18-32
+++ b/pcre/testdata/testoutput18-32
@@ -337,7 +337,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
\x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
\x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4
5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y
@@ -376,7 +376,7 @@ Options: utf
First char = \x{100}
Need char = \x{100}
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
\x{100}\x{100}\x{100}\x{100\x{100}
0: \x{100}\x{100}\x{100}
@@ -396,7 +396,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x \xff
+Starting chars: x \xff
/(\x{100}*a|x)/8SDZ
------------------------------------------------------------------
@@ -415,7 +415,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a x \xff
+Starting chars: a x \xff
/(\x{100}{0,2}a|x)/8SDZ
------------------------------------------------------------------
@@ -434,7 +434,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a x \xff
+Starting chars: a x \xff
/(\x{100}{1,2}a|x)/8SDZ
------------------------------------------------------------------
@@ -454,7 +454,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x \xff
+Starting chars: x \xff
/\x{100}/8DZ
------------------------------------------------------------------
@@ -663,7 +663,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x20 \xa0 \xff
+Starting chars: \x09 \x20 \xa0 \xff
ABC\x{09}
0: \x{09}
ABC\x{20}
@@ -689,7 +689,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
ABC\x{0a}
0: \x{0a}
ABC\x{0b}
@@ -709,19 +709,19 @@ Options: utf
No first char
Need char = 'A'
Subject length lower bound = 1
-Starting byte set: \x09 \x20 A \xa0 \xff
+Starting chars: \x09 \x20 A \xa0 \xff
CDBABC
0: A
\x{2000}ABC
0: \x{2000}A
-/\R*A/SI8
+/\R*A/SI8<bsr_unicode>
Capturing subpattern count = 0
-Options: utf
+Options: bsr_unicode utf
No first char
Need char = 'A'
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d A \x85 \xff
CDBABC
0: A
\x{2028}A
@@ -733,7 +733,7 @@ Options: utf
No first char
Need char = 'A'
Subject length lower bound = 2
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
/\s?xxx\s/8SI
Capturing subpattern count = 0
@@ -741,7 +741,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 4
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 x
/\sxxx\s/I8ST1
Capturing subpattern count = 0
@@ -749,7 +749,7 @@ Options: utf
No first char
Need char = 'x'
Subject length lower bound = 5
-Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0
+Starting chars: \x09 \x0a \x0c \x0d \x20 \x85 \xa0
AB\x{85}xxx\x{a0}XYZ
0: \x{85}xxx\x{a0}
AB\x{a0}xxx\x{85}XYZ
@@ -761,7 +761,7 @@ Options: utf
No first char
Need char = ' '
Subject length lower bound = 3
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
\x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
\x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e
@@ -800,7 +800,7 @@ Options: caseless utf
First char = \x{1234}
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\x{1234}+?/iS8I
Capturing subpattern count = 0
@@ -808,7 +808,7 @@ Options: caseless utf
First char = \x{1234}
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\x{1234}++/iS8I
Capturing subpattern count = 0
@@ -816,7 +816,7 @@ Options: caseless utf
First char = \x{1234}
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/\x{1234}{2}/iS8I
Capturing subpattern count = 0
@@ -824,7 +824,7 @@ Options: caseless utf
First char = \x{1234}
Need char = \x{1234}
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
/[^\x{c4}]/8DZ
------------------------------------------------------------------
@@ -857,7 +857,7 @@ Options: utf
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+Starting chars: \x0a \x0b \x0c \x0d \x85 \xff
/-- Check bad offset --/
diff --git a/pcre/testdata/testoutput19 b/pcre/testdata/testoutput19
index ccc198cc153..21fe677900b 100644
--- a/pcre/testdata/testoutput19
+++ b/pcre/testdata/testoutput19
@@ -55,7 +55,7 @@ Options: caseless utf
First char = \x{401} (caseless)
Need char = \x{42f} (caseless)
Subject length lower bound = 17
-No set of starting bytes
+No starting char list
\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
\x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
diff --git a/pcre/testdata/testoutput2 b/pcre/testdata/testoutput2
index 844497abcdc..b6da7df187e 100644
--- a/pcre/testdata/testoutput2
+++ b/pcre/testdata/testoutput2
@@ -178,7 +178,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: c d e
+Starting chars: c d e
this sentence eventually mentions a cat
0: cat
this sentences rambles on and on for a while and then reaches elephant
@@ -190,7 +190,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 3
-Starting byte set: C D E c d e
+Starting chars: C D E c d e
this sentence eventually mentions a CAT cat
0: CAT
this sentences rambles on and on for a while to elephant ElePhant
@@ -202,7 +202,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a|[^\dZ])/IS
Capturing subpattern count = 1
@@ -210,7 +210,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
\x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
\x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = >
? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y [ \ ] ^ _ ` a b c d
@@ -231,7 +231,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 a b
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 a b
/(ab\2)/
Failed: reference to non-existent subpattern at offset 6
@@ -512,7 +512,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(?i)[abcd]/IS
Capturing subpattern count = 0
@@ -520,7 +520,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B C D a b c d
+Starting chars: A B C D a b c d
/(?m)[xy]|(b|c)/IS
Capturing subpattern count = 1
@@ -528,7 +528,7 @@ Options: multiline
No first char
No need char
Subject length lower bound = 1
-Starting byte set: b c x y
+Starting chars: b c x y
/(^a|^b)/Im
Capturing subpattern count = 1
@@ -591,7 +591,7 @@ No options
First char = 'b' (caseless)
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/(a*b|(?i:c*(?-i)d))/IS
Capturing subpattern count = 1
@@ -599,7 +599,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: C a b c d
+Starting chars: C a b c d
/a$/I
Capturing subpattern count = 0
@@ -666,7 +666,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/(?<!foo)(alpha|omega)/IS
Capturing subpattern count = 1
@@ -675,7 +675,7 @@ No options
No first char
Need char = 'a'
Subject length lower bound = 5
-Starting byte set: a o
+Starting chars: a o
/(?!alphabet)[ab]/IS
Capturing subpattern count = 0
@@ -683,7 +683,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/(?<=foo\n)^bar/Im
Capturing subpattern count = 0
@@ -1642,7 +1642,7 @@ Options: anchored
No first char
Need char = 'd'
Subject length lower bound = 4
-No set of starting bytes
+No starting char list
/\( # ( at start
(?: # Non-capturing bracket
@@ -1875,7 +1875,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+Starting chars: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
_ a b c d e f g h i j k l m n o p q r s t u v w x y z
/^[[:ascii:]]/DZ
@@ -1937,7 +1937,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20
/^[[:cntrl:]]/DZ
------------------------------------------------------------------
@@ -3178,6 +3178,10 @@ Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1
/\U/I
Failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 1
+/a{1,3}b/U
+ ab
+ 0: ab
+
/[/I
Failed: missing terminating ] for character class at offset 1
@@ -3434,7 +3438,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/[^a]/I
Capturing subpattern count = 0
@@ -3454,7 +3458,7 @@ No options
No first char
Need char = '6'
Subject length lower bound = 4
-Starting byte set: 0 1 2 3 4 5 6 7 8 9
+Starting chars: 0 1 2 3 4 5 6 7 8 9
/a^b/I
Capturing subpattern count = 0
@@ -3488,7 +3492,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B a b
+Starting chars: A B a b
/[ab](?i)cd/IS
Capturing subpattern count = 0
@@ -3496,7 +3500,7 @@ No options
No first char
Need char = 'd' (caseless)
Subject length lower bound = 3
-Starting byte set: a b
+Starting chars: a b
/abc(?C)def/I
Capturing subpattern count = 0
@@ -3537,7 +3541,7 @@ No options
No first char
Need char = 'f'
Subject length lower bound = 7
-Starting byte set: 0 1 2 3 4 5 6 7 8 9
+Starting chars: 0 1 2 3 4 5 6 7 8 9
1234abcdef
--->1234abcdef
1 ^ \d
@@ -3856,7 +3860,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
/(?R)/I
Failed: recursive call could loop indefinitely at offset 3
@@ -4637,7 +4641,7 @@ Options: caseless
No first char
Need char = 'g' (caseless)
Subject length lower bound = 8
-No set of starting bytes
+No starting char list
Baby Bjorn Active Carrier - With free SHIPPING!!
0: Baby Bjorn Active Carrier - With free SHIPPING!!
1: Baby Bjorn Active Carrier - With free SHIPPING!!
@@ -4656,7 +4660,7 @@ No options
No first char
Need char = 'b'
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/(a|b)*.?c/ISDZ
------------------------------------------------------------------
@@ -4677,7 +4681,7 @@ No options
No first char
Need char = 'c'
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/abc(?C255)de(?C)f/DZ
------------------------------------------------------------------
@@ -4750,7 +4754,7 @@ Options:
No first char
Need char = 'b'
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
ab
--->ab
+0 ^ a*
@@ -4893,7 +4897,7 @@ Options:
No first char
Need char = 'x'
Subject length lower bound = 4
-Starting byte set: a d
+Starting chars: a d
abcx
--->abcx
+0 ^ (abc|def)
@@ -5127,7 +5131,7 @@ Options:
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b x
+Starting chars: a b x
Note: that { does NOT introduce a quantifier
--->Note: that { does NOT introduce a quantifier
+0 ^ ([ab]{,4}c|xy)
@@ -5607,7 +5611,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5642,7 +5646,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5677,7 +5681,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -5716,7 +5720,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b
+Starting chars: a b
Compiled pattern written to testsavedregex
Study data written to testsavedregex
<testsavedregex
@@ -6431,7 +6435,7 @@ No options
No first char
Need char = ','
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 ,
+Starting chars: \x09 \x0a \x0b \x0c \x0d \x20 ,
\x0b,\x0b
0: \x0b,\x0b
\x0c,\x0d
@@ -6738,7 +6742,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: C a b c d
+Starting chars: C a b c d
/()[ab]xyz/IS
Capturing subpattern count = 1
@@ -6746,7 +6750,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b
+Starting chars: a b
/(|)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6754,7 +6758,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b
+Starting chars: a b
/(|c)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6762,7 +6766,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c
+Starting chars: a b c
/(|c?)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6770,7 +6774,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c
+Starting chars: a b c
/(d?|c?)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6778,7 +6782,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c d
+Starting chars: a b c d
/(d?|c)[ab]xyz/IS
Capturing subpattern count = 1
@@ -6786,7 +6790,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 4
-Starting byte set: a b c d
+Starting chars: a b c d
/^a*b\d/DZ
------------------------------------------------------------------
@@ -6879,7 +6883,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a+|b*)[cd]/IS
Capturing subpattern count = 1
@@ -6887,7 +6891,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a*|b+)[cd]/IS
Capturing subpattern count = 1
@@ -6895,7 +6899,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/(a+|b+)[cd]/IS
Capturing subpattern count = 1
@@ -6903,7 +6907,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
@@ -9307,7 +9311,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: x y z
+Starting chars: x y z
/(?(?=.*b)b|^)/CI
Capturing subpattern count = 0
@@ -10096,7 +10100,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|bc)\1{2,3}/SI
Capturing subpattern count = 1
@@ -10105,7 +10109,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: a b
+Starting chars: a b
/(a|bc)(?1)/SI
Capturing subpattern count = 1
@@ -10113,7 +10117,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|b\1)(a|b\1)/SI
Capturing subpattern count = 2
@@ -10122,7 +10126,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|b\1){2}/SI
Capturing subpattern count = 1
@@ -10131,7 +10135,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|bbbb\1)(a|bbbb\1)/SI
Capturing subpattern count = 2
@@ -10140,7 +10144,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/(a|bbbb\1){2}/SI
Capturing subpattern count = 1
@@ -10149,7 +10153,7 @@ No options
No first char
No need char
Subject length lower bound = 2
-Starting byte set: a b
+Starting chars: a b
/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/SI
Capturing subpattern count = 1
@@ -10157,7 +10161,7 @@ Options: anchored
No first char
Need char = ':'
Subject length lower bound = 22
-No set of starting bytes
+No starting char list
/<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/isIS
Capturing subpattern count = 11
@@ -10165,7 +10169,7 @@ Options: caseless dotall
First char = '<'
Need char = '>'
Subject length lower bound = 47
-No set of starting bytes
+No starting char list
"(?>.*/)foo"SI
Capturing subpattern count = 0
@@ -10173,7 +10177,7 @@ No options
No first char
Need char = 'o'
Subject length lower bound = 4
-No set of starting bytes
+No starting char list
/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /xSI
Capturing subpattern count = 0
@@ -10181,7 +10185,7 @@ Options: extended
No first char
Need char = '-'
Subject length lower bound = 8
-No set of starting bytes
+No starting char list
/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/iSI
Capturing subpattern count = 1
@@ -10189,7 +10193,7 @@ Options: caseless
No first char
No need char
Subject length lower bound = 1
-Starting byte set: A B C a b c
+Starting chars: A B C a b c
/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/SI
Capturing subpattern count = 0
@@ -10197,7 +10201,7 @@ No options
No first char
Need char = 'b'
Subject length lower bound = 41
-Starting byte set: c d
+Starting chars: c d
/<a[\s]+href[\s]*=[\s]* # find <a href=
([\"\'])? # find single or double quote
@@ -10210,7 +10214,7 @@ Options: caseless extended dotall
First char = '<'
Need char = '='
Subject length lower bound = 9
-No set of starting bytes
+No starting char list
/^(?!:) # colon disallowed at start
(?: # start of item
@@ -10226,7 +10230,7 @@ Options: anchored caseless extended
No first char
Need char = ':'
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
/(?|(?<a>A)|(?<a>B))/I
Capturing subpattern count = 1
@@ -10450,7 +10454,7 @@ Options:
No first char
Need char = 'a'
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
cat
0: a
1:
@@ -10464,7 +10468,7 @@ No options
No first char
Need char = 'a'
Subject length lower bound = 3
-No set of starting bytes
+No starting char list
cat
No match
@@ -10476,7 +10480,7 @@ No options
First char = 'i'
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
i
0: i
@@ -10486,7 +10490,7 @@ No options
No first char
Need char = 'i'
Subject length lower bound = 1
-Starting byte set: i
+Starting chars: i
ia
0: ia
1:
@@ -11080,7 +11084,7 @@ No options
First char = 'a'
Need char = '4'
Subject length lower bound = 5
-No set of starting bytes
+No starting char list
/([abc])++1234/SI
Capturing subpattern count = 1
@@ -11088,7 +11092,7 @@ No options
No first char
Need char = '4'
Subject length lower bound = 5
-Starting byte set: a b c
+Starting chars: a b c
/(?<=(abc)+)X/
Failed: lookbehind assertion is not fixed length at offset 10
@@ -11369,7 +11373,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/(a(?2)|b)(b(?1)|a)(?:(?1)|(?2))/SI
Capturing subpattern count = 2
@@ -11377,7 +11381,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: a b
+Starting chars: a b
/(a(?2)|b)(b(?1)|a)(?1)(?2)/SI
Capturing subpattern count = 2
@@ -11385,7 +11389,7 @@ No options
No first char
No need char
Subject length lower bound = 4
-Starting byte set: a b
+Starting chars: a b
/(abc)(?1)/SI
Capturing subpattern count = 1
@@ -11393,7 +11397,7 @@ No options
First char = 'a'
Need char = 'c'
Subject length lower bound = 6
-No set of starting bytes
+No starting char list
/^(?>a)++/
aa\M
@@ -11711,7 +11715,7 @@ No options
First char = 't'
Need char = 't'
Subject length lower bound = 18
-No set of starting bytes
+No starting char list
/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|<input\b.*?\btype\b\W*?\bimage\b|\bonkeyup\b\W*?\=/IS
Capturing subpattern count = 0
@@ -11720,7 +11724,7 @@ No options
No first char
No need char
Subject length lower bound = 8
-Starting byte set: < o t u
+Starting chars: < o t u
/a(*SKIP)c|b(*ACCEPT)|/+S!I
Capturing subpattern count = 0
@@ -11729,7 +11733,7 @@ No options
No first char
No need char
Subject length lower bound = -1
-No set of starting bytes
+No starting char list
a
0:
0+
@@ -11740,7 +11744,7 @@ No options
No first char
No need char
Subject length lower bound = -1
-Starting byte set: a b x
+Starting chars: a b x
ax
0: x
@@ -12436,7 +12440,7 @@ No options
No first char
No need char
Subject length lower bound = -1
-No set of starting bytes
+No starting char list
/(?:(a)+(?C1)bb|aa(?C2)b)/
aab\C+
@@ -12722,7 +12726,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
-Starting byte set: a z
+Starting chars: a z
aaaaaaaaaaaaaz
Error -21 (recursion limit exceeded)
aaaaaaaaaaaaaz\Q1000
@@ -12735,7 +12739,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
-Starting byte set: a z
+Starting chars: a z
aaaaaaaaaaaaaz
Error -21 (recursion limit exceeded)
@@ -12746,7 +12750,7 @@ No options
No first char
Need char = 'z'
Subject length lower bound = 2
-Starting byte set: a z
+Starting chars: a z
aaaaaaaaaaaaaz
No match
aaaaaaaaaaaaaz\Q10
@@ -12790,7 +12794,7 @@ Options: dupnames
First char = 'a'
Need char = 'z'
Subject length lower bound = 5
-No set of starting bytes
+No starting char list
/a*[bcd]/BZ
------------------------------------------------------------------
@@ -13902,7 +13906,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/[a-c]+d/DZS
------------------------------------------------------------------
@@ -13917,7 +13921,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 2
-Starting byte set: a b c
+Starting chars: a b c
/[a-c]?d/DZS
------------------------------------------------------------------
@@ -13932,7 +13936,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/[a-c]{4,6}d/DZS
------------------------------------------------------------------
@@ -13947,7 +13951,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 5
-Starting byte set: a b c
+Starting chars: a b c
/[a-c]{0,6}d/DZS
------------------------------------------------------------------
@@ -13962,7 +13966,7 @@ No options
No first char
Need char = 'd'
Subject length lower bound = 1
-Starting byte set: a b c d
+Starting chars: a b c d
/-- End of special auto-possessive tests --/
@@ -14125,4 +14129,24 @@ No match
/[a[:<:]] should give error/
Failed: unknown POSIX class name at offset 4
+/(?=ab\K)/+
+ abcd
+Start of matched string is beyond its end - displaying from end to start.
+ 0: ab
+ 0+ abcd
+
+/abcd/f<lf>
+ xx\nxabcd
+No match
+
+/ -- Test stack check external calls --/
+
+/(((((a)))))/Q0
+
+/(((((a)))))/Q1
+Failed: parentheses are too deeply nested (stack check) at offset 0
+
+/(((((a)))))/Q
+** Missing 0 or 1 after /Q
+
/-- End of testinput2 --/
diff --git a/pcre/testdata/testoutput21-16 b/pcre/testdata/testoutput21-16
index 0e21350f891..da194d90e0b 100644
--- a/pcre/testdata/testoutput21-16
+++ b/pcre/testdata/testoutput21-16
@@ -50,7 +50,7 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
-No set of starting bytes
+No starting char list
<!testsaved16BE-1
Compiled pattern loaded from testsaved16BE-1
@@ -83,7 +83,7 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
-No set of starting bytes
+No starting char list
<!testsaved32LE-1
Compiled pattern loaded from testsaved32LE-1
diff --git a/pcre/testdata/testoutput21-32 b/pcre/testdata/testoutput21-32
index 183487aca13..d087bb6f4dd 100644
--- a/pcre/testdata/testoutput21-32
+++ b/pcre/testdata/testoutput21-32
@@ -62,7 +62,7 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
-No set of starting bytes
+No starting char list
<!testsaved32BE-1
Compiled pattern loaded from testsaved32BE-1
@@ -95,6 +95,6 @@ Options: anchored extended
No first char
No need char
Subject length lower bound = 6
-No set of starting bytes
+No starting char list
/-- End of testinput21 --/
diff --git a/pcre/testdata/testoutput22-16 b/pcre/testdata/testoutput22-16
index f896b13e18a..32a71cd4438 100644
--- a/pcre/testdata/testoutput22-16
+++ b/pcre/testdata/testoutput22-16
@@ -37,7 +37,7 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
<!testsaved16BE-2
Compiled pattern loaded from testsaved16BE-2
@@ -64,7 +64,7 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
<!testsaved32LE-2
Compiled pattern loaded from testsaved32LE-2
diff --git a/pcre/testdata/testoutput22-32 b/pcre/testdata/testoutput22-32
index 783926b8210..13e441d159c 100644
--- a/pcre/testdata/testoutput22-32
+++ b/pcre/testdata/testoutput22-32
@@ -49,7 +49,7 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
<!testsaved32BE-2
Compiled pattern loaded from testsaved32BE-2
@@ -76,6 +76,6 @@ Options: extended utf
No first char
No need char
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
/-- End of testinput22 --/
diff --git a/pcre/testdata/testoutput23 b/pcre/testdata/testoutput23
index 6f5384c34e8..6dabf03b0fa 100644
--- a/pcre/testdata/testoutput23
+++ b/pcre/testdata/testoutput23
@@ -18,7 +18,7 @@ Failed: character value in \x{} or \o{} is too large at offset 8
/[\H]/BZSI
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}]
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}]
Ket
End
------------------------------------------------------------------
@@ -27,12 +27,25 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0a \x0b
+ \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a
+ \x1b \x1c \x1d \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9
+ : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^
+ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80
+ \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f
+ \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e
+ \x9f \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae
+ \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd
+ \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc
+ \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb
+ \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea
+ \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9
+ \xfa \xfb \xfc \xfd \xfe \xff
/[\V]/BZSI
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{ffff}]
+ [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffff}]
Ket
End
------------------------------------------------------------------
@@ -41,6 +54,19 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0e
+ \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
+ \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = >
+ ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
+ d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82
+ \x83 \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92
+ \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1
+ \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0
+ \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf
+ \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce
+ \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd
+ \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec
+ \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb
+ \xfc \xfd \xfe \xff
/-- End of testinput23 --/
diff --git a/pcre/testdata/testoutput25 b/pcre/testdata/testoutput25
index 7ad3378368f..4c62c8d8079 100644
--- a/pcre/testdata/testoutput25
+++ b/pcre/testdata/testoutput25
@@ -1,6 +1,6 @@
/-- Tests for the 32-bit library only */
-< forbid 8w
+< forbid 8W
/-- Check maximum character size --/
@@ -65,7 +65,7 @@ Need char = \x{800000}
/[\H]/BZSI
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffffffff}]
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffffffff}]
Ket
End
------------------------------------------------------------------
@@ -74,12 +74,25 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0a \x0b
+ \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a
+ \x1b \x1c \x1d \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9
+ : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^
+ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80
+ \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f
+ \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e
+ \x9f \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae
+ \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd
+ \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc
+ \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb
+ \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea
+ \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9
+ \xfa \xfb \xfc \xfd \xfe \xff
/[\V]/BZSI
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{ffffffff}]
+ [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{ffffffff}]
Ket
End
------------------------------------------------------------------
@@ -88,6 +101,19 @@ No options
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+Starting chars: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0e
+ \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
+ \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = >
+ ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
+ d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82
+ \x83 \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92
+ \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1
+ \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0
+ \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf
+ \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce
+ \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd
+ \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec
+ \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb
+ \xfc \xfd \xfe \xff
/-- End of testinput25 --/
diff --git a/pcre/testdata/testoutput3 b/pcre/testdata/testoutput3
index 12ffc9911b6..73119ab4b7b 100644
--- a/pcre/testdata/testoutput3
+++ b/pcre/testdata/testoutput3
@@ -1,7 +1,10 @@
-/-- This set of tests checks local-specific features, using the fr_FR locale.
- It is not Perl-compatible. There is different version called wintestinput3
- f or use on Windows, where the locale is called "french". --/
-
+/-- This set of tests checks local-specific features, using the "fr_FR" locale.
+ It is not Perl-compatible. When run via RunTest, the locale is edited to
+ be whichever of "fr_FR", "french", or "fr" is found to exist. There is
+ different version of this file called wintestinput3 for use on Windows,
+ where the locale is called "french" and the tests are run using
+ RunTest.bat. --/
+
< forbid 8W
/^[\w]+/
@@ -90,7 +93,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
/\w/ISLfr_FR
@@ -99,7 +102,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â
ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
diff --git a/pcre/testdata/testoutput3A b/pcre/testdata/testoutput3A
new file mode 100644
index 00000000000..0bde024e4e1
--- /dev/null
+++ b/pcre/testdata/testoutput3A
@@ -0,0 +1,174 @@
+/-- This set of tests checks local-specific features, using the "fr_FR" locale.
+ It is not Perl-compatible. When run via RunTest, the locale is edited to
+ be whichever of "fr_FR", "french", or "fr" is found to exist. There is
+ different version of this file called wintestinput3 for use on Windows,
+ where the locale is called "french" and the tests are run using
+ RunTest.bat. --/
+
+< forbid 8W
+
+/^[\w]+/
+ *** Failers
+No match
+ École
+No match
+
+/^[\w]+/Lfr_FR
+ École
+ 0: École
+
+/^[\w]+/
+ *** Failers
+No match
+ École
+No match
+
+/^[\W]+/
+ École
+ 0: \xc9
+
+/^[\W]+/Lfr_FR
+ *** Failers
+ 0: ***
+ École
+No match
+
+/[\b]/
+ \b
+ 0: \x08
+ *** Failers
+No match
+ a
+No match
+
+/[\b]/Lfr_FR
+ \b
+ 0: \x08
+ *** Failers
+No match
+ a
+No match
+
+/^\w+/
+ *** Failers
+No match
+ École
+No match
+
+/^\w+/Lfr_FR
+ École
+ 0: École
+
+/(.+)\b(.+)/
+ École
+ 0: \xc9cole
+ 1: \xc9
+ 2: cole
+
+/(.+)\b(.+)/Lfr_FR
+ *** Failers
+ 0: *** Failers
+ 1: ***
+ 2: Failers
+ École
+No match
+
+/École/i
+ École
+ 0: \xc9cole
+ *** Failers
+No match
+ école
+No match
+
+/École/iLfr_FR
+ École
+ 0: École
+ école
+ 0: école
+
+/\w/IS
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+ Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
+
+/\w/ISLfr_FR
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+ Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
+ ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â
+ ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
+
+/^[\xc8-\xc9]/iLfr_FR
+ École
+ 0: É
+ école
+ 0: é
+
+/^[\xc8-\xc9]/Lfr_FR
+ École
+ 0: É
+ *** Failers
+No match
+ école
+No match
+
+/\W+/Lfr_FR
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/[\W]+/Lfr_FR
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/[^[:alpha:]]+/Lfr_FR
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/\w+/Lfr_FR
+ >>>\xaa<<<
+ 0: ª
+ >>>\xba<<<
+ 0: º
+
+/[\w]+/Lfr_FR
+ >>>\xaa<<<
+ 0: ª
+ >>>\xba<<<
+ 0: º
+
+/[[:alpha:]]+/Lfr_FR
+ >>>\xaa<<<
+ 0: ª
+ >>>\xba<<<
+ 0: º
+
+/[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR
+------------------------------------------------------------------
+ Bra
+ [A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff]
+ [a-z\xaa\xb5\xba\xdf-\xf6\xf8-\xff]
+ [A-Z\xc0-\xd6\xd8-\xde]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/-- End of testinput3 --/
diff --git a/pcre/testdata/testoutput3B b/pcre/testdata/testoutput3B
new file mode 100644
index 00000000000..8d9fe7df772
--- /dev/null
+++ b/pcre/testdata/testoutput3B
@@ -0,0 +1,174 @@
+/-- This set of tests checks local-specific features, using the "fr_FR" locale.
+ It is not Perl-compatible. When run via RunTest, the locale is edited to
+ be whichever of "fr_FR", "french", or "fr" is found to exist. There is
+ different version of this file called wintestinput3 for use on Windows,
+ where the locale is called "french" and the tests are run using
+ RunTest.bat. --/
+
+< forbid 8W
+
+/^[\w]+/
+ *** Failers
+No match
+ École
+No match
+
+/^[\w]+/Lfr_FR
+ École
+ 0: École
+
+/^[\w]+/
+ *** Failers
+No match
+ École
+No match
+
+/^[\W]+/
+ École
+ 0: \xc9
+
+/^[\W]+/Lfr_FR
+ *** Failers
+ 0: ***
+ École
+No match
+
+/[\b]/
+ \b
+ 0: \x08
+ *** Failers
+No match
+ a
+No match
+
+/[\b]/Lfr_FR
+ \b
+ 0: \x08
+ *** Failers
+No match
+ a
+No match
+
+/^\w+/
+ *** Failers
+No match
+ École
+No match
+
+/^\w+/Lfr_FR
+ École
+ 0: École
+
+/(.+)\b(.+)/
+ École
+ 0: \xc9cole
+ 1: \xc9
+ 2: cole
+
+/(.+)\b(.+)/Lfr_FR
+ *** Failers
+ 0: *** Failers
+ 1: ***
+ 2: Failers
+ École
+No match
+
+/École/i
+ École
+ 0: \xc9cole
+ *** Failers
+No match
+ école
+No match
+
+/École/iLfr_FR
+ École
+ 0: École
+ école
+ 0: école
+
+/\w/IS
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+ Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
+
+/\w/ISLfr_FR
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+ Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
+ ª µ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â
+ ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ
+
+/^[\xc8-\xc9]/iLfr_FR
+ École
+ 0: É
+ école
+ 0: é
+
+/^[\xc8-\xc9]/Lfr_FR
+ École
+ 0: É
+ *** Failers
+No match
+ école
+No match
+
+/\W+/Lfr_FR
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/[\W]+/Lfr_FR
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/[^[:alpha:]]+/Lfr_FR
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/\w+/Lfr_FR
+ >>>\xaa<<<
+ 0: ª
+ >>>\xba<<<
+ 0: º
+
+/[\w]+/Lfr_FR
+ >>>\xaa<<<
+ 0: ª
+ >>>\xba<<<
+ 0: º
+
+/[[:alpha:]]+/Lfr_FR
+ >>>\xaa<<<
+ 0: ª
+ >>>\xba<<<
+ 0: º
+
+/[[:alpha:]][[:lower:]][[:upper:]]/DZLfr_FR
+------------------------------------------------------------------
+ Bra
+ [A-Za-z\x83\x8a\x8c\x8e\x9a\x9c\x9e\x9f\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff]
+ [a-z\x83\x9a\x9c\x9e\xaa\xb5\xba\xdf-\xf6\xf8-\xff]
+ [A-Z\x8a\x8c\x8e\x9f\xc0-\xd6\xd8-\xde]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/-- End of testinput3 --/
diff --git a/pcre/testdata/testoutput4 b/pcre/testdata/testoutput4
index 0dbec4eccab..dcf13b08507 100644
--- a/pcre/testdata/testoutput4
+++ b/pcre/testdata/testoutput4
@@ -1263,4 +1263,12 @@ No match
aa
0: aa
+/^.\B.\B./8
+ \x{10123}\x{10124}\x{10125}
+ 0: \x{10123}\x{10124}\x{10125}
+
+/^#[^\x{ffff}]#[^\x{ffff}]#[^\x{ffff}]#/8
+ #\x{10000}#\x{100}#\x{10ffff}#
+ 0: #\x{10000}#\x{100}#\x{10ffff}#
+
/-- End of testinput4 --/
diff --git a/pcre/testdata/testoutput5 b/pcre/testdata/testoutput5
index 3fa581052e6..5c098e650ba 100644
--- a/pcre/testdata/testoutput5
+++ b/pcre/testdata/testoutput5
@@ -270,7 +270,7 @@ No match
/[z-\x{100}]/8DZ
------------------------------------------------------------------
Bra
- [z-\x{100}]
+ [z-\xff\x{100}]
Ket
End
------------------------------------------------------------------
@@ -812,7 +812,7 @@ No match
/[\H]/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}]
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}]
Ket
End
------------------------------------------------------------------
@@ -820,7 +820,7 @@ No match
/[\V]/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}]
+ [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}]
Ket
End
------------------------------------------------------------------
@@ -1536,7 +1536,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/[^\x{1234}]+?/iS8I
Capturing subpattern count = 0
@@ -1544,7 +1544,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/[^\x{1234}]++/iS8I
Capturing subpattern count = 0
@@ -1552,7 +1552,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 1
-No set of starting bytes
+No starting char list
/[^\x{1234}]{2}/iS8I
Capturing subpattern count = 0
@@ -1560,7 +1560,7 @@ Options: caseless utf
No first char
No need char
Subject length lower bound = 2
-No set of starting bytes
+No starting char list
//<bsr_anycrlf><bsr_unicode>
Failed: inconsistent NEWLINE options at offset 0
@@ -1620,7 +1620,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\H\x{d7ff}]+/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]++
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff\x{100}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]++
Ket
End
------------------------------------------------------------------
@@ -1660,7 +1660,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\V\x{d7ff}]+/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]++
+ [\x00-\x09\x0e-\x84\x86-\xff\x{100}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]++
Ket
End
------------------------------------------------------------------
@@ -1882,4 +1882,19 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5
aa
0: aa
+/[b-d\x{200}-\x{250}]*[ae-h]?#[\x{200}-\x{250}]{0,8}[\x00-\xff]*#[\x{200}-\x{250}]+[a-z]/8BZ
+------------------------------------------------------------------
+ Bra
+ [b-d\x{200}-\x{250}]*+
+ [ae-h]?+
+ #
+ [\x{200}-\x{250}]{0,8}+
+ [\x00-\xff]*
+ #
+ [\x{200}-\x{250}]++
+ [a-z]
+ Ket
+ End
+------------------------------------------------------------------
+
/-- End of testinput5 --/
diff --git a/pcre/testdata/testoutput6 b/pcre/testdata/testoutput6
index 6c42fce1a5b..f355e601383 100644
--- a/pcre/testdata/testoutput6
+++ b/pcre/testdata/testoutput6
@@ -2445,4 +2445,16 @@ No match
\x{37e}
No match
+/[RST]+/8iW
+ Ss\x{17f}
+ 0: Ss\x{17f}
+
+/[R-T]+/8iW
+ Ss\x{17f}
+ 0: Ss\x{17f}
+
+/[q-u]+/8iW
+ Ss\x{17f}
+ 0: Ss\x{17f}
+
/-- End of testinput6 --/
diff --git a/pcre/testdata/testoutput7 b/pcre/testdata/testoutput7
index 45ac72fd8d4..c64e0499421 100644
--- a/pcre/testdata/testoutput7
+++ b/pcre/testdata/testoutput7
@@ -124,7 +124,7 @@ No match
/[z-\x{100}]/8iDZ
------------------------------------------------------------------
Bra
- [Z\x{39c}\x{3bc}\x{1e9e}\x{178}z-\x{101}]
+ [Zz-\xff\x{39c}\x{3bc}\x{212b}\x{1e9e}\x{212b}\x{178}\x{100}-\x{101}]
Ket
End
------------------------------------------------------------------
@@ -162,7 +162,7 @@ No match
/[z-\x{100}]/8DZi
------------------------------------------------------------------
Bra
- [Z\x{39c}\x{3bc}\x{1e9e}\x{178}z-\x{101}]
+ [Zz-\xff\x{39c}\x{3bc}\x{212b}\x{1e9e}\x{212b}\x{178}\x{100}-\x{101}]
Ket
End
------------------------------------------------------------------
@@ -2263,4 +2263,28 @@ No match
End
------------------------------------------------------------------
+/[RST]+/8iWBZ
+------------------------------------------------------------------
+ Bra
+ [R-Tr-t\x{17f}]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[R-T]+/8iWBZ
+------------------------------------------------------------------
+ Bra
+ [R-Tr-t\x{17f}]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[Q-U]+/8iWBZ
+------------------------------------------------------------------
+ Bra
+ [Q-Uq-u\x{17f}]++
+ Ket
+ End
+------------------------------------------------------------------
+
/-- End of testinput7 --/
diff --git a/pcre/testdata/testoutput8 b/pcre/testdata/testoutput8
index bb68d3e6452..3861ea41fdb 100644
--- a/pcre/testdata/testoutput8
+++ b/pcre/testdata/testoutput8
@@ -7232,7 +7232,7 @@ No options
No first char
No need char
Subject length lower bound = 3
-Starting byte set: a d x
+Starting chars: a d x
terhjk;abcdaadsfe
0: abc
the quick xyz brown fox
diff --git a/pcre/testdata/wintestoutput3 b/pcre/testdata/wintestoutput3
index 00880070670..456ad196b56 100644
--- a/pcre/testdata/wintestoutput3
+++ b/pcre/testdata/wintestoutput3
@@ -84,7 +84,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
/\w/ISLfrench
@@ -93,7 +93,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+Starting chars: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
ƒ Š Œ Ž š œ ž Ÿ ª ² ³ µ ¹ º À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö
Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý
diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in
index 40dc275a29c..bfb910278b2 100644
--- a/scripts/mysql_install_db.pl.in
+++ b/scripts/mysql_install_db.pl.in
@@ -558,7 +558,7 @@ else
"database and look at the grant tables:",
"",
"shell> $bindir/mysql -u root mysql",
- "mysql> show tables",
+ "mysql> show tables;",
"",
"Try 'mysqld --help' if you have problems with paths. Using --log",
"gives you a log in $opt->{ldata} that may be helpful.",
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index c24aacaf883..801fdae5565 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -445,7 +445,7 @@ else
echo "to connect to the mysql database and look at the grant tables:"
echo
echo " shell> $bindir/mysql -u root mysql"
- echo " mysql> show tables"
+ echo " mysql> show tables;"
echo
echo "Try 'mysqld --help' if you have problems with paths. Using"
echo "--general-log gives you a log in $ldata that may be helpful."
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index 34742aa6dfb..a53a73656e7 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -23,6 +23,9 @@ set sql_mode='';
set @orig_storage_engine=@@storage_engine;
set storage_engine=myisam;
+set @have_innodb= (select count(engine) from information_schema.engines where engine='INNODB' and support != 'NO');
+SET @innodb_or_myisam=IF(@have_innodb <> 0, 'InnoDB', 'MyISAM');
+
CREATE TABLE IF NOT EXISTS db ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges';
-- Remember for later if db table already existed
@@ -126,8 +129,6 @@ SET @create_innodb_index_stats="CREATE TABLE IF NOT EXISTS innodb_index_stats (
PRIMARY KEY (database_name, table_name, index_name, stat_name)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0";
-set @have_innodb= (select count(engine) from information_schema.engines where engine='INNODB' and support != 'NO');
-
SET @str=IF(@have_innodb <> 0, @create_innodb_table_stats, "SET @dummy = 0");
PREPARE stmt FROM @str;
EXECUTE stmt;
@@ -149,7 +150,7 @@ SET @cmd="CREATE TABLE IF NOT EXISTS slave_relay_log_info (
Id INTEGER UNSIGNED NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
PRIMARY KEY(Id)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'Relay Log Information'";
-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB;'), CONCAT(@cmd, ' ENGINE= MYISAM;'));
+SET @str=CONCAT(@cmd, ' ENGINE=', @innodb_or_myisam);
-- Don't create the table; MariaDB will have another implementation
#PREPARE stmt FROM @str;
#EXECUTE stmt;
@@ -181,7 +182,7 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS slave_master_info (
Enabled_auto_position BOOLEAN NOT NULL COMMENT 'Indicates whether GTIDs will be used to retrieve events from the master.',
PRIMARY KEY(Host, Port)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'Master Information'";
-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB;'), CONCAT(@cmd, ' ENGINE= MYISAM;'));
+SET @str=CONCAT(@cmd, ' ENGINE=', @innodb_or_myisam);
-- Don't create the table; MariaDB will have another implementation
#PREPARE stmt FROM @str;
#EXECUTE stmt;
@@ -202,7 +203,7 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS slave_worker_info (
Checkpoint_group_bitmap BLOB NOT NULL,
PRIMARY KEY(Id)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'Worker Information'";
-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB;'), CONCAT(@cmd, ' ENGINE= MYISAM;'));
+SET @str=CONCAT(@cmd, ' ENGINE=', @innodb_or_myisam);
-- Don't create the table; MariaDB will have another implementation
#PREPARE stmt FROM @str;
#EXECUTE stmt;
@@ -223,9 +224,16 @@ CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_nam
CREATE TABLE IF NOT EXISTS index_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, index_name varchar(64) NOT NULL, prefix_arity int(11) unsigned NOT NULL, avg_frequency decimal(12,4) DEFAULT NULL, PRIMARY KEY (db_name,table_name,index_name,prefix_arity) ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Indexes';
--- GTID table.
--- We want this to be created with the default storage engine.
--- This way, if InnoDB is used we get crash safety, and if MyISAM is used
--- we avoid mixed-engine transactions.
+SET @cmd= "CREATE TABLE IF NOT EXISTS gtid_slave_pos (
+ domain_id INT UNSIGNED NOT NULL,
+ sub_id BIGINT UNSIGNED NOT NULL,
+ server_id INT UNSIGNED NOT NULL,
+ seq_no BIGINT UNSIGNED NOT NULL,
+ PRIMARY KEY (domain_id, sub_id))
+COMMENT='Replication slave GTID position'";
+SET @str=CONCAT(@cmd, ' ENGINE=', @innodb_or_myisam);
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
set storage_engine=@orig_storage_engine;
-CREATE TABLE IF NOT EXISTS gtid_slave_pos (domain_id INT UNSIGNED NOT NULL, sub_id BIGINT UNSIGNED NOT NULL, server_id INT UNSIGNED NOT NULL, seq_no BIGINT UNSIGNED NOT NULL, PRIMARY KEY (domain_id, sub_id)) comment='Replication slave GTID position';
diff --git a/sql-common/client.c b/sql-common/client.c
index a1ea9ed44e5..72760560903 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -4714,21 +4714,31 @@ const char * STDCALL mysql_error(MYSQL *mysql)
RETURN
Signed number > 323000
+ Zero if there is no connection
*/
ulong STDCALL
mysql_get_server_version(MYSQL *mysql)
{
- uint major, minor, version;
- const char *pos= mysql->server_version;
- char *end_pos;
- /* Skip possible prefix */
- while (*pos && !my_isdigit(&my_charset_latin1, *pos))
- pos++;
- major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
- minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
- version= (uint) strtoul(pos, &end_pos, 10);
- return (ulong) major*10000L+(ulong) (minor*100+version);
+ ulong major= 0, minor= 0, version= 0;
+
+ if (mysql->server_version)
+ {
+ const char *pos= mysql->server_version;
+ char *end_pos;
+ /* Skip possible prefix */
+ while (*pos && !my_isdigit(&my_charset_latin1, *pos))
+ pos++;
+ major= strtoul(pos, &end_pos, 10); pos=end_pos+1;
+ minor= strtoul(pos, &end_pos, 10); pos=end_pos+1;
+ version= strtoul(pos, &end_pos, 10);
+ }
+ else
+ {
+ set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
+ }
+
+ return major*10000 + minor*100 + version;
}
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 0942544d0be..6a011df795a 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -1214,7 +1214,7 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
*was_cut= 0;
time_res->time_type=MYSQL_TIMESTAMP_DATE;
- if (nr == 0 || nr >= 10000101000000LL || sec_part)
+ if (nr == 0 || nr >= 10000101000000LL)
{
time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
goto ok;
@@ -1272,7 +1272,11 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
time_res->minute <= 59 && time_res->second <= 59 &&
sec_part <= TIME_MAX_SECOND_PART &&
!check_date(time_res, nr || sec_part, flags, was_cut))
+ {
+ if (time_res->time_type == MYSQL_TIMESTAMP_DATE && sec_part != 0)
+ *was_cut= MYSQL_TIME_NOTE_TRUNCATED;
return nr;
+ }
/* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */
if (nr || !(flags & TIME_NO_ZERO_DATE))
@@ -1306,10 +1310,10 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
0 time value is valid, but was possibly truncated
-1 time value is invalid
*/
-int number_to_time(my_bool neg, longlong nr, ulong sec_part,
+int number_to_time(my_bool neg, ulonglong nr, ulong sec_part,
MYSQL_TIME *ltime, int *was_cut)
{
- if (nr > 9999999 && neg == 0)
+ if (nr > 9999999 && nr < 99991231235959ULL && neg == 0)
{
if (number_to_datetime(nr, sec_part, ltime,
TIME_INVALID_DATES, was_cut) < 0)
@@ -1317,7 +1321,7 @@ int number_to_time(my_bool neg, longlong nr, ulong sec_part,
ltime->year= ltime->month= ltime->day= 0;
ltime->time_type= MYSQL_TIMESTAMP_TIME;
- *was_cut= MYSQL_TIME_WARN_TRUNCATED;
+ *was_cut= MYSQL_TIME_NOTE_TRUNCATED;
return 0;
}
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 598462d1bba..d25ed87e1fa 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -99,7 +99,7 @@ SET (SQL_SOURCE
sql_profile.cc event_parse_data.cc sql_alter.cc
sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc
transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
- sql_reload.cc sql_cmd.h
+ sql_reload.cc sql_cmd.h item_inetfunc.cc
# added in MariaDB:
sql_explain.h sql_explain.cc
sql_lifo_buffer.h sql_join_cache.h sql_join_cache.cc
diff --git a/sql/field.cc b/sql/field.cc
index 68617d0204e..103a8920d7e 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1965,8 +1965,8 @@ Field *Field::new_field(MEM_ROOT *root, TABLE *new_table,
Field *Field::new_key_field(MEM_ROOT *root, TABLE *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit)
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit)
{
Field *tmp;
if ((tmp= new_field(root, new_table, table == new_table)))
@@ -4706,7 +4706,7 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
{
MYSQL_TIME l_time;
int error;
- ErrConvInteger str(nr);
+ ErrConvInteger str(nr, unsigned_val);
THD *thd= get_thd();
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
@@ -5210,7 +5210,7 @@ int Field_temporal_with_date::store(longlong nr, bool unsigned_val)
MYSQL_TIME ltime;
longlong tmp;
THD *thd= get_thd();
- ErrConvInteger str(nr);
+ ErrConvInteger str(nr, unsigned_val);
tmp= number_to_datetime(nr, 0, &ltime, sql_mode_for_dates(thd), &error);
@@ -5316,12 +5316,41 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
}
+/**
+ subtract a given number of days from DATETIME, return TIME
+
+ optimized version of calc_time_diff()
+
+ @note it might generate TIME values outside of the valid TIME range!
+*/
+static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days)
+{
+ long daydiff= calc_daynr(ltime->year, ltime->month, ltime->day) - days;
+ ltime->year= ltime->month= 0;
+ if (daydiff >=0 )
+ ltime->day= daydiff;
+ else
+ {
+ longlong timediff= ((((daydiff * 24LL +
+ ltime->hour) * 60LL +
+ ltime->minute) * 60LL +
+ ltime->second) * 1000000LL +
+ ltime->second_part);
+ unpack_time(timediff, ltime);
+ }
+ ltime->time_type= MYSQL_TIMESTAMP_TIME;
+}
+
+
int Field_time::store_time_dec(MYSQL_TIME *ltime, uint dec)
{
MYSQL_TIME l_time= *ltime;
ErrConvTime str(ltime);
int was_cut= 0;
+ if (curdays && l_time.time_type != MYSQL_TIMESTAMP_TIME)
+ calc_datetime_days_diff(&l_time, curdays);
+
int have_smth_to_conv= !check_time_range(&l_time, decimals(), &was_cut);
return store_TIME_with_warning(&l_time, &str, was_cut, have_smth_to_conv);
}
@@ -5335,7 +5364,7 @@ int Field_time::store(double nr)
bool neg= nr < 0;
if (neg)
nr= -nr;
- int have_smth_to_conv= !number_to_time(neg, (longlong)nr,
+ int have_smth_to_conv= !number_to_time(neg, (ulonglong) nr,
(ulong)((nr - floor(nr)) * TIME_SECOND_PART_FACTOR),
&ltime, &was_cut);
@@ -5346,15 +5375,40 @@ int Field_time::store(double nr)
int Field_time::store(longlong nr, bool unsigned_val)
{
MYSQL_TIME ltime;
- ErrConvInteger str(nr);
+ ErrConvInteger str(nr, unsigned_val);
int was_cut;
- int have_smth_to_conv= !number_to_time(nr < 0, nr < 0 ? -nr : nr,
+ if (nr < 0 && unsigned_val)
+ nr= 99991231235959LL + 1;
+ int have_smth_to_conv= !number_to_time(nr < 0,
+ (ulonglong) (nr < 0 ? -nr : nr),
0, &ltime, &was_cut);
return store_TIME_with_warning(&ltime, &str, was_cut, have_smth_to_conv);
}
-
-
+
+
+void Field_time::set_curdays(THD *thd)
+{
+ MYSQL_TIME ltime;
+ set_current_date(thd, &ltime);
+ curdays= calc_daynr(ltime.year, ltime.month, ltime.day);
+}
+
+
+Field *Field_time::new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit)
+{
+ THD *thd= get_thd();
+ Field_time *res=
+ (Field_time*) Field::new_key_field(root, new_table, new_ptr, length,
+ new_null_ptr, new_null_bit);
+ if (!(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST) && res)
+ res->set_curdays(thd);
+ return res;
+}
+
+
double Field_time::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -5705,7 +5759,8 @@ bool Field_year::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
int tmp= (int) ptr[0];
if (tmp || field_length != 4)
tmp+= 1900;
- return int_to_datetime_with_warn(tmp * 10000, ltime, fuzzydate, field_name);
+ return int_to_datetime_with_warn(false, tmp * 10000,
+ ltime, fuzzydate, field_name);
}
@@ -7200,17 +7255,14 @@ Field *Field_varstring::new_field(MEM_ROOT *root, TABLE *new_table,
}
-Field *Field_varstring::new_key_field(MEM_ROOT *root,
- TABLE *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit)
+Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit)
{
Field_varstring *res;
- if ((res= (Field_varstring*) Field::new_key_field(root,
- new_table,
- new_ptr,
- new_null_ptr,
- new_null_bit)))
+ if ((res= (Field_varstring*) Field::new_key_field(root, new_table,
+ new_ptr, length,
+ new_null_ptr, new_null_bit)))
{
/* Keys length prefixes are always packed with 2 bytes */
res->length_bytes= 2;
@@ -7218,7 +7270,6 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root,
return res;
}
-
uint Field_varstring::is_equal(Create_field *new_field)
{
if (new_field->sql_type == real_type() &&
@@ -7312,8 +7363,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
If content of the 'from'-address is cached in the 'value'-object
it is possible that the content needs a character conversion.
*/
- uint32 dummy_offset;
- if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
+ if (!String::needs_conversion_on_storage(length, cs, field_charset))
{
Field_blob::store_length(length);
bmove(ptr + packlength, &from, sizeof(char*));
@@ -7576,6 +7626,18 @@ int Field_blob::key_cmp(const uchar *a,const uchar *b)
}
+Field *Field_blob::new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit)
+{
+ Field_varstring *res= new (root) Field_varstring(new_ptr, length, 2,
+ new_null_ptr, new_null_bit, Field::NONE,
+ field_name, table->s, charset());
+ res->init(new_table);
+ return res;
+}
+
+
/**
Save the field metadata for blob fields.
@@ -7885,12 +7947,11 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
{
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
int err= 0;
- uint32 not_used;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if necessary */
- if (String::needs_conversion(length, cs, field_charset, &not_used))
+ if (String::needs_conversion_on_storage(length, cs, field_charset))
{
uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
@@ -8067,12 +8128,11 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
int err= 0;
char *not_used;
uint not_used2;
- uint32 not_used_offset;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
/* Convert character set if necessary */
- if (String::needs_conversion(length, cs, field_charset, &not_used_offset))
+ if (String::needs_conversion_on_storage(length, cs, field_charset))
{
uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
@@ -8425,15 +8485,13 @@ Field_bit::do_last_null_byte() const
}
-Field *Field_bit::new_key_field(MEM_ROOT *root,
- TABLE *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit)
+Field *Field_bit::new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit)
{
Field_bit *res;
- if ((res= (Field_bit*) Field::new_key_field(root, new_table,
- new_ptr, new_null_ptr,
- new_null_bit)))
+ if ((res= (Field_bit*) Field::new_key_field(root, new_table, new_ptr, length,
+ new_null_ptr, new_null_bit)))
{
/* Move bits normally stored in null_pointer to new_ptr */
res->bit_ptr= new_ptr;
diff --git a/sql/field.h b/sql/field.h
index cbd9175f26c..b5f332f5edc 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -94,6 +94,31 @@ inline uint get_set_pack_length(int elements)
/**
+ Tests if field type is temporal and has date part,
+ i.e. represents DATE, DATETIME or TIMESTAMP types in SQL.
+
+ @param type Field type, as returned by field->type().
+ @retval true If field type is temporal type with date part.
+ @retval false If field type is not temporal type with date part.
+*/
+inline bool is_temporal_type_with_date(enum_field_types type)
+{
+ switch (type)
+ {
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ return true;
+ case MYSQL_TYPE_DATETIME2:
+ case MYSQL_TYPE_TIMESTAMP2:
+ DBUG_ASSERT(0); // field->real_type() should not get to here.
+ default:
+ return false;
+ }
+}
+
+
+/**
Recognizer for concrete data type (called real_type for some reason),
returning true if it is one of the TIMESTAMP types.
*/
@@ -228,9 +253,13 @@ class Field
Field(const Item &); /* Prevent use of these */
void operator=(Field &);
public:
+ static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
+ { return alloc_root(mem_root, size); }
static void *operator new(size_t size) throw ()
{ return sql_alloc(size); }
static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); }
+ static void operator delete(void *ptr, MEM_ROOT *mem_root)
+ { DBUG_ASSERT(0); }
uchar *ptr; // Position to field in record
/**
@@ -684,8 +713,8 @@ public:
virtual Field *new_field(MEM_ROOT *root, TABLE *new_table,
bool keep_type);
virtual Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit);
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit);
Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff,
bool stat_flag= FALSE);
@@ -1823,6 +1852,12 @@ public:
class Field_time :public Field_temporal {
+ /*
+ when this Field_time instance is used for storing values for index lookups
+ (see class store_key, Field::new_key_field(), etc), the following
+ might be set to TO_DAYS(CURDATE()). See also Field_time::store_time_dec()
+ */
+ long curdays;
protected:
virtual void store_TIME(MYSQL_TIME *ltime);
int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str,
@@ -1832,7 +1867,7 @@ public:
uchar null_bit_arg, enum utype unireg_check_arg,
const char *field_name_arg)
:Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg)
+ unireg_check_arg, field_name_arg), curdays(0)
{}
enum_field_types type() const { return MYSQL_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
@@ -1851,6 +1886,10 @@ public:
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
+ void set_curdays(THD *thd);
+ Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit);
};
@@ -2298,8 +2337,8 @@ public:
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
Field *new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit);
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit);
uint is_equal(Create_field *new_field);
void hash(ulong *nr, ulong *nr2);
uint length_size() { return length_bytes; }
@@ -2432,6 +2471,9 @@ public:
}
uint get_key_image(uchar *buff,uint length, imagetype type);
void set_key_image(const uchar *buff,uint length);
+ Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit);
void sql_type(String &str) const;
inline bool copy()
{
@@ -2702,8 +2744,8 @@ public:
virtual void set_default();
Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit);
+ uchar *new_ptr, uint32 length,
+ uchar *new_null_ptr, uint new_null_bit);
void set_bit_ptr(uchar *bit_ptr_arg, uchar bit_ofs_arg)
{
bit_ptr= bit_ptr_arg;
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 0d554df6e18..5ca6be2a2f4 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -166,6 +166,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
TABLE_LIST *tab= table->pos_in_table_list;
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
+ *found_rows= HA_POS_ERROR;
+
MYSQL_FILESORT_START(table->s->db.str, table->s->table_name.str);
DEBUG_SYNC(thd, "filesort_start");
@@ -686,7 +688,8 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
ref_pos= ref_buff;
quick_select=select && select->quick;
record=0;
- *found_rows= 0;
+ if (pq) // don't count unless pq is used
+ *found_rows= 0;
flag= ((file->ha_table_flags() & HA_REC_NOT_IN_SEQ) || quick_select);
if (flag)
ref_pos= &file->ref[0];
@@ -806,9 +809,14 @@ static ha_rows find_all_keys(Sort_param *param, SQL_SELECT *select,
if (write_record)
{
- (*found_rows)++;
if (pq)
{
+ /*
+ only count rows when pq is used - otherwise there might be
+ other filters *after* the filesort, we don't know the final row
+ count here
+ */
+ (*found_rows)++;
pq->push(ref_pos);
idx= pq->num_elements();
}
diff --git a/sql/handler.h b/sql/handler.h
index 53e8997acbe..d5a371027f6 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1618,7 +1618,7 @@ struct HA_CREATE_INFO
For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
Can be changed either explicitly by the parser.
- If nothing speficied inherits the value of the original table (if present).
+ If nothing specified inherits the value of the original table (if present).
*/
enum row_type row_type;
enum ha_choice transactional;
diff --git a/sql/item.cc b/sql/item.cc
index 2c963322eb6..21baf779781 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1352,6 +1352,7 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
case INT_RESULT:
{
longlong value= val_int();
+ bool neg= !unsigned_flag && value < 0;
if (field_type() == MYSQL_TYPE_YEAR)
{
if (max_length == 2)
@@ -1363,7 +1364,8 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
}
value*= 10000; /* make it YYYYMMHH */
}
- if (null_value || int_to_datetime_with_warn(value, ltime, fuzzydate,
+ if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
+ ltime, fuzzydate,
field_name_or_null()))
goto err;
break;
@@ -8848,7 +8850,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
*/
if (field->cmp_type() == TIME_RESULT)
{
- MYSQL_TIME field_time, item_time;
+ MYSQL_TIME field_time, item_time, item_time2, *item_time_cmp= &item_time;
if (field->type() == MYSQL_TYPE_TIME)
{
field->get_time(&field_time);
@@ -8858,8 +8860,11 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
{
field->get_date(&field_time, TIME_INVALID_DATES);
item->get_date(&item_time, TIME_INVALID_DATES);
+ if (item_time.time_type == MYSQL_TIMESTAMP_TIME)
+ if (time_to_datetime(thd, &item_time, item_time_cmp= &item_time2))
+ return 1;
}
- return my_time_compare(&field_time, &item_time);
+ return my_time_compare(&field_time, item_time_cmp);
}
if (res_type == STRING_RESULT)
{
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index f142c51db4d..289668f24ca 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -900,9 +900,11 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
{
MYSQL_TIME ltime;
uint fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
- if (f_type == MYSQL_TYPE_TIME)
- fuzzydate|= TIME_TIME_ONLY;
- if (item->get_date(&ltime, fuzzydate))
+ if ((item->field_type() == MYSQL_TYPE_TIME &&
+ is_temporal_type_with_date(warn_item->field_type())) ?
+ item->get_date_with_conversion(&ltime, fuzzydate) :
+ item->get_date(&ltime, fuzzydate |
+ (f_type == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0)))
value= 0; /* invalid date */
else
value= pack_time(&ltime);
@@ -2559,9 +2561,9 @@ Item_func_ifnull::str_op(String *str)
bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, uint fuzzydate)
{
DBUG_ASSERT(fixed == 1);
- if (!args[0]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ if (!args[0]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
return (null_value= false);
- if (!args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ if (!args[1]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
return (null_value= false);
bzero((char*) ltime,sizeof(*ltime));
return null_value= !(fuzzydate & TIME_FUZZY_DATES);
@@ -2752,7 +2754,7 @@ bool Item_func_if::date_op(MYSQL_TIME *ltime, uint fuzzydate)
{
DBUG_ASSERT(fixed == 1);
Item *arg= args[0]->val_bool() ? args[1] : args[2];
- return (null_value= arg->get_date(ltime, fuzzydate));
+ return (null_value= arg->get_date_with_conversion(ltime, fuzzydate));
}
@@ -2997,7 +2999,7 @@ bool Item_func_case::date_op(MYSQL_TIME *ltime, uint fuzzydate)
Item *item= find_item(&dummy_str);
if (!item)
return (null_value= true);
- return (null_value= item->get_date(ltime, fuzzydate));
+ return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
}
@@ -3315,7 +3317,8 @@ bool Item_func_coalesce::date_op(MYSQL_TIME *ltime,uint fuzzydate)
null_value= 0;
for (uint i= 0; i < arg_count; i++)
{
- bool res= args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES);
+ bool res= args[i]->get_date_with_conversion(ltime,
+ fuzzydate & ~TIME_FUZZY_DATES);
if (!args[i]->null_value)
return res;
}
@@ -4896,21 +4899,20 @@ longlong Item_func_like::val_int()
Item_func::optimize_type Item_func_like::select_optimize() const
{
- if (args[1]->const_item() && !args[1]->is_expensive())
- {
- String* res2= args[1]->val_str((String *)&cmp.value2);
- const char *ptr2;
+ if (!args[1]->const_item() || args[1]->is_expensive())
+ return OPTIMIZE_NONE;
- if (!res2 || !(ptr2= res2->ptr()))
- return OPTIMIZE_NONE;
+ String* res2= args[1]->val_str((String *)&cmp.value2);
+ if (!res2)
+ return OPTIMIZE_NONE;
- if (*ptr2 != wild_many)
- {
- if (args[0]->result_type() != STRING_RESULT || *ptr2 != wild_one)
- return OPTIMIZE_OP;
- }
- }
- return OPTIMIZE_NONE;
+ if (!res2->length()) // Can optimize empty wildcard: column LIKE ''
+ return OPTIMIZE_OP;
+
+ DBUG_ASSERT(res2->ptr());
+ char first= res2->ptr()[0];
+ return (first == wild_many || first == wild_one) ?
+ OPTIMIZE_NONE : OPTIMIZE_OP;
}
diff --git a/sql/item_create.cc b/sql/item_create.cc
index a3e0dc6012b..193c7deb207 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -32,6 +32,7 @@
#include "set_var.h"
#include "sp_head.h"
#include "sp.h"
+#include "item_inetfunc.h"
#include "sql_time.h"
/*
@@ -1343,6 +1344,84 @@ protected:
};
+class Create_func_inet6_aton : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_inet6_aton s_singleton;
+
+protected:
+ Create_func_inet6_aton() {}
+ virtual ~Create_func_inet6_aton() {}
+};
+
+
+class Create_func_inet6_ntoa : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_inet6_ntoa s_singleton;
+
+protected:
+ Create_func_inet6_ntoa() {}
+ virtual ~Create_func_inet6_ntoa() {}
+};
+
+
+class Create_func_is_ipv4 : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_is_ipv4 s_singleton;
+
+protected:
+ Create_func_is_ipv4() {}
+ virtual ~Create_func_is_ipv4() {}
+};
+
+
+class Create_func_is_ipv6 : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_is_ipv6 s_singleton;
+
+protected:
+ Create_func_is_ipv6() {}
+ virtual ~Create_func_is_ipv6() {}
+};
+
+
+class Create_func_is_ipv4_compat : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_is_ipv4_compat s_singleton;
+
+protected:
+ Create_func_is_ipv4_compat() {}
+ virtual ~Create_func_is_ipv4_compat() {}
+};
+
+
+class Create_func_is_ipv4_mapped : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_is_ipv4_mapped s_singleton;
+
+protected:
+ Create_func_is_ipv4_mapped() {}
+ virtual ~Create_func_is_ipv4_mapped() {}
+};
+
+
class Create_func_instr : public Create_func_arg2
{
public:
@@ -4139,6 +4218,24 @@ Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
}
+Create_func_inet6_aton Create_func_inet6_aton::s_singleton;
+
+Item*
+Create_func_inet6_aton::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_inet6_aton(arg1);
+}
+
+
+Create_func_inet6_ntoa Create_func_inet6_ntoa::s_singleton;
+
+Item*
+Create_func_inet6_ntoa::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_inet6_ntoa(arg1);
+}
+
+
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
@@ -4148,6 +4245,42 @@ Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
}
+Create_func_is_ipv4 Create_func_is_ipv4::s_singleton;
+
+Item*
+Create_func_is_ipv4::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_is_ipv4(arg1);
+}
+
+
+Create_func_is_ipv6 Create_func_is_ipv6::s_singleton;
+
+Item*
+Create_func_is_ipv6::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_is_ipv6(arg1);
+}
+
+
+Create_func_is_ipv4_compat Create_func_is_ipv4_compat::s_singleton;
+
+Item*
+Create_func_is_ipv4_compat::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_is_ipv4_compat(arg1);
+}
+
+
+Create_func_is_ipv4_mapped Create_func_is_ipv4_mapped::s_singleton;
+
+Item*
+Create_func_is_ipv4_mapped::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_is_ipv4_mapped(arg1);
+}
+
+
Create_func_instr Create_func_instr::s_singleton;
Item*
@@ -5585,6 +5718,12 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("IFNULL") }, BUILDER(Create_func_ifnull)},
{ { C_STRING_WITH_LEN("INET_ATON") }, BUILDER(Create_func_inet_aton)},
{ { C_STRING_WITH_LEN("INET_NTOA") }, BUILDER(Create_func_inet_ntoa)},
+ { { C_STRING_WITH_LEN("INET6_ATON") }, BUILDER(Create_func_inet6_aton)},
+ { { C_STRING_WITH_LEN("INET6_NTOA") }, BUILDER(Create_func_inet6_ntoa)},
+ { { C_STRING_WITH_LEN("IS_IPV4") }, BUILDER(Create_func_is_ipv4)},
+ { { C_STRING_WITH_LEN("IS_IPV6") }, BUILDER(Create_func_is_ipv6)},
+ { { C_STRING_WITH_LEN("IS_IPV4_COMPAT") }, BUILDER(Create_func_is_ipv4_compat)},
+ { { C_STRING_WITH_LEN("IS_IPV4_MAPPED") }, BUILDER(Create_func_is_ipv4_mapped)},
{ { C_STRING_WITH_LEN("INSTR") }, BUILDER(Create_func_instr)},
{ { C_STRING_WITH_LEN("INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
{ { C_STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_mbr_intersects)},
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 572c9fdde60..11110dddeb8 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
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
@@ -1116,7 +1116,9 @@ bool Item_func_hybrid_result_type::get_date(MYSQL_TIME *ltime,
case INT_RESULT:
{
longlong value= int_op();
- if (null_value || int_to_datetime_with_warn(value, ltime, fuzzydate,
+ bool neg= !unsigned_flag && value < 0;
+ if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
+ ltime, fuzzydate,
field_name_or_null()))
goto err;
break;
@@ -1961,9 +1963,11 @@ void Item_func_int_div::fix_length_and_dec()
{
Item_result argtype= args[0]->result_type();
/* use precision ony for the data type it is applicable for and valid */
- max_length=args[0]->max_length -
- (argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
- args[0]->decimals : 0);
+ uint32 char_length= args[0]->max_char_length() -
+ (argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
+ args[0]->decimals : 0);
+ fix_char_length(char_length > MY_INT64_NUM_DECIMAL_DIGITS ?
+ MY_INT64_NUM_DECIMAL_DIGITS : char_length);
maybe_null=1;
unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
}
@@ -6110,61 +6114,6 @@ void Item_func_get_system_var::cleanup()
}
-longlong Item_func_inet_aton::val_int()
-{
- DBUG_ASSERT(fixed == 1);
- uint byte_result = 0;
- ulonglong result = 0; // We are ready for 64 bit addresses
- const char *p,* end;
- char c = '.'; // we mark c to indicate invalid IP in case length is 0
- char buff[36];
- int dot_count= 0;
-
- String *s, tmp(buff, sizeof(buff), &my_charset_latin1);
- if (!(s = args[0]->val_str_ascii(&tmp))) // If null value
- goto err;
- null_value=0;
-
- end= (p = s->ptr()) + s->length();
- while (p < end)
- {
- c = *p++;
- int digit = (int) (c - '0');
- if (digit >= 0 && digit <= 9)
- {
- if ((byte_result = byte_result * 10 + digit) > 255)
- goto err; // Wrong address
- }
- else if (c == '.')
- {
- dot_count++;
- result= (result << 8) + (ulonglong) byte_result;
- byte_result = 0;
- }
- else
- goto err; // Invalid character
- }
- if (c != '.') // IP number can't end on '.'
- {
- /*
- Handle short-forms addresses according to standard. Examples:
- 127 -> 0.0.0.127
- 127.1 -> 127.0.0.1
- 127.2.1 -> 127.2.0.1
- */
- switch (dot_count) {
- case 1: result<<= 8; /* Fall through */
- case 2: result<<= 8; /* Fall through */
- }
- return (result << 8) + (ulonglong) byte_result;
- }
-
-err:
- null_value=1;
- return 0;
-}
-
-
void Item_func_match::init_search(bool no_order)
{
DBUG_ENTER("Item_func_match::init_search");
diff --git a/sql/item_func.h b/sql/item_func.h
index 69abecc5f39..1696898812d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1871,16 +1871,6 @@ public:
};
-class Item_func_inet_aton : public Item_int_func
-{
-public:
- Item_func_inet_aton(Item *a) :Item_int_func(a) {}
- longlong val_int();
- const char *func_name() const { return "inet_aton"; }
- void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;}
-};
-
-
/* for fulltext search */
class Item_func_match :public Item_real_func
diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc
new file mode 100644
index 00000000000..627ef728a2e
--- /dev/null
+++ b/sql/item_inetfunc.cc
@@ -0,0 +1,830 @@
+/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2014 MariaDB Foundation
+
+ 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 Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "item_inetfunc.h"
+
+#include "my_net.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+static const int IN_ADDR_SIZE= sizeof (in_addr);
+static const int IN6_ADDR_SIZE= sizeof (in6_addr);
+static const int IN6_ADDR_NUM_WORDS= IN6_ADDR_SIZE / 2;
+
+static const char HEX_DIGITS[]= "0123456789abcdef";
+
+///////////////////////////////////////////////////////////////////////////
+
+longlong Item_func_inet_aton::val_int()
+{
+ DBUG_ASSERT(fixed);
+
+ uint byte_result= 0;
+ ulonglong result= 0; // We are ready for 64 bit addresses
+ const char *p,* end;
+ char c= '.'; // we mark c to indicate invalid IP in case length is 0
+ int dot_count= 0;
+
+ StringBuffer<36> tmp;
+ String *s= args[0]->val_str_ascii(&tmp);
+
+ if (!s) // If null value
+ goto err;
+
+ null_value= 0;
+
+ end= (p = s->ptr()) + s->length();
+ while (p < end)
+ {
+ c= *p++;
+ int digit= (int) (c - '0');
+ if (digit >= 0 && digit <= 9)
+ {
+ if ((byte_result= byte_result * 10 + digit) > 255)
+ goto err; // Wrong address
+ }
+ else if (c == '.')
+ {
+ dot_count++;
+ result= (result << 8) + (ulonglong) byte_result;
+ byte_result= 0;
+ }
+ else
+ goto err; // Invalid character
+ }
+ if (c != '.') // IP number can't end on '.'
+ {
+ /*
+ Attempt to support short forms of IP-addresses. It's however pretty
+ basic one comparing to the BSD support.
+ Examples:
+ 127 -> 0.0.0.127
+ 127.255 -> 127.0.0.255
+ 127.256 -> NULL (should have been 127.0.1.0)
+ 127.2.1 -> 127.2.0.1
+ */
+ switch (dot_count) {
+ case 1: result<<= 8; /* Fall through */
+ case 2: result<<= 8; /* Fall through */
+ }
+ return (result << 8) + (ulonglong) byte_result;
+ }
+
+err:
+ null_value=1;
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+String* Item_func_inet_ntoa::val_str(String* str)
+{
+ DBUG_ASSERT(fixed);
+
+ ulonglong n= (ulonglong) args[0]->val_int();
+
+ /*
+ We do not know if args[0] is NULL until we have called
+ some val function on it if args[0] is not a constant!
+
+ Also return null if n > 255.255.255.255
+ */
+ if ((null_value= (args[0]->null_value || n > 0xffffffff)))
+ return 0; // Null value
+
+ str->set_charset(collation.collation);
+ str->length(0);
+
+ uchar buf[8];
+ int4store(buf, n);
+
+ /* Now we can assume little endian. */
+
+ char num[4];
+ num[3]= '.';
+
+ for (uchar *p= buf + 4; p-- > buf;)
+ {
+ uint c= *p;
+ uint n1, n2; // Try to avoid divisions
+ n1= c / 100; // 100 digits
+ c-= n1 * 100;
+ n2= c / 10; // 10 digits
+ c-= n2 * 10; // last digit
+ num[0]= (char) n1 + '0';
+ num[1]= (char) n2 + '0';
+ num[2]= (char) c + '0';
+ uint length= (n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero
+ uint dot_length= (p <= buf) ? 1 : 0;
+ (void) str->append(num + 4 - length, length - dot_length,
+ &my_charset_latin1);
+ }
+
+ return str;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Check the function argument, handle errors properly.
+
+ @return The function value.
+*/
+
+longlong Item_func_inet_bool_base::val_int()
+{
+ DBUG_ASSERT(fixed);
+
+ if (args[0]->result_type() != STRING_RESULT) // String argument expected
+ return 0;
+
+ String buffer;
+ String *arg_str= args[0]->val_str(&buffer);
+
+ if (!arg_str) // Out-of memory happened. The error has been reported.
+ return 0; // Or: the underlying field is NULL
+
+ return calc_value(arg_str) ? 1 : 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Check the function argument, handle errors properly.
+
+ @param [out] buffer Buffer for string operations.
+
+ @return The function value.
+*/
+
+String *Item_func_inet_str_base::val_str_ascii(String *buffer)
+{
+ DBUG_ASSERT(fixed);
+
+ if (args[0]->result_type() != STRING_RESULT) // String argument expected
+ {
+ null_value= true;
+ return NULL;
+ }
+
+ String *arg_str= args[0]->val_str(buffer);
+ if (!arg_str) // Out-of memory happened. The error has been reported.
+ { // Or: the underlying field is NULL
+ null_value= true;
+ return NULL;
+ }
+
+ null_value= !calc_value(arg_str, buffer);
+
+ return null_value ? NULL : buffer;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Tries to convert given string to binary IPv4-address representation.
+ This is a portable alternative to inet_pton(AF_INET).
+
+ @param str String to convert.
+ @param str_len String length.
+ @param[out] ipv4_address Buffer to store IPv4-address.
+
+ @return Completion status.
+ @retval false Given string does not represent an IPv4-address.
+ @retval true The string has been converted sucessfully.
+
+ @note The problem with inet_pton() is that it treats leading zeros in
+ IPv4-part differently on different platforms.
+*/
+
+static bool str_to_ipv4(const char *str, int str_length, in_addr *ipv4_address)
+{
+ if (str_length < 7)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): "
+ "invalid IPv4 address: too short.",
+ str_length, str));
+ return false;
+ }
+
+ if (str_length > 15)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): "
+ "invalid IPv4 address: too long.",
+ str_length, str));
+ return false;
+ }
+
+ unsigned char *ipv4_bytes= (unsigned char *) ipv4_address;
+ const char *p= str;
+ int byte_value= 0;
+ int chars_in_group= 0;
+ int dot_count= 0;
+ char c= 0;
+
+ while (((p - str) < str_length) && *p)
+ {
+ c= *p++;
+
+ if (my_isdigit(&my_charset_latin1, c))
+ {
+ ++chars_in_group;
+
+ if (chars_in_group > 3)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "too many characters in a group.",
+ str_length, str));
+ return false;
+ }
+
+ byte_value= byte_value * 10 + (c - '0');
+
+ if (byte_value > 255)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "invalid byte value.",
+ str_length, str));
+ return false;
+ }
+ }
+ else if (c == '.')
+ {
+ if (chars_in_group == 0)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "too few characters in a group.",
+ str_length, str));
+ return false;
+ }
+
+ ipv4_bytes[dot_count]= (unsigned char) byte_value;
+
+ ++dot_count;
+ byte_value= 0;
+ chars_in_group= 0;
+
+ if (dot_count > 3)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "too many dots.", str_length, str));
+ return false;
+ }
+ }
+ else
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "invalid character at pos %d.",
+ str_length, str, (int) (p - str)));
+ return false;
+ }
+ }
+
+ if (c == '.')
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "ending at '.'.", str_length, str));
+ return false;
+ }
+
+ if (dot_count != 3)
+ {
+ DBUG_PRINT("error", ("str_to_ipv4(%.*s): invalid IPv4 address: "
+ "too few groups.",
+ str_length, str));
+ return false;
+ }
+
+ ipv4_bytes[3]= (unsigned char) byte_value;
+
+ DBUG_PRINT("info", ("str_to_ipv4(%.*s): valid IPv4 address: %d.%d.%d.%d",
+ str_length, str,
+ ipv4_bytes[0], ipv4_bytes[1],
+ ipv4_bytes[2], ipv4_bytes[3]));
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Tries to convert given string to binary IPv6-address representation.
+ This is a portable alternative to inet_pton(AF_INET6).
+
+ @param str String to convert.
+ @param str_len String length.
+ @param[out] ipv6_address Buffer to store IPv6-address.
+
+ @return Completion status.
+ @retval false Given string does not represent an IPv6-address.
+ @retval true The string has been converted sucessfully.
+
+ @note The problem with inet_pton() is that it treats leading zeros in
+ IPv4-part differently on different platforms.
+*/
+
+static bool str_to_ipv6(const char *str, int str_length, in6_addr *ipv6_address)
+{
+ if (str_length < 2)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: too short.",
+ str_length, str));
+ return false;
+ }
+
+ if (str_length > 8 * 4 + 7)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: too long.",
+ str_length, str));
+ return false;
+ }
+
+ memset(ipv6_address, 0, IN6_ADDR_SIZE);
+
+ const char *p= str;
+
+ if (*p == ':')
+ {
+ ++p;
+
+ if (*p != ':')
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "can not start with ':x'.", str_length, str));
+ return false;
+ }
+ }
+
+ char *ipv6_bytes= (char *) ipv6_address;
+ char *ipv6_bytes_end= ipv6_bytes + IN6_ADDR_SIZE;
+ char *dst= ipv6_bytes;
+ char *gap_ptr= NULL;
+ const char *group_start_ptr= p;
+ int chars_in_group= 0;
+ int group_value= 0;
+
+ while (((p - str) < str_length) && *p)
+ {
+ char c= *p++;
+
+ if (c == ':')
+ {
+ group_start_ptr= p;
+
+ if (!chars_in_group)
+ {
+ if (gap_ptr)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "too many gaps(::).", str_length, str));
+ return false;
+ }
+
+ gap_ptr= dst;
+ continue;
+ }
+
+ if (!*p || ((p - str) >= str_length))
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "ending at ':'.", str_length, str));
+ return false;
+ }
+
+ if (dst + 2 > ipv6_bytes_end)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "too many groups (1).", str_length, str));
+ return false;
+ }
+
+ dst[0]= (unsigned char) (group_value >> 8) & 0xff;
+ dst[1]= (unsigned char) group_value & 0xff;
+ dst += 2;
+
+ chars_in_group= 0;
+ group_value= 0;
+ }
+ else if (c == '.')
+ {
+ if (dst + IN_ADDR_SIZE > ipv6_bytes_end)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "unexpected IPv4-part.", str_length, str));
+ return false;
+ }
+
+ if (!str_to_ipv4(group_start_ptr,
+ str + str_length - group_start_ptr,
+ (in_addr *) dst))
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "invalid IPv4-part.", str_length, str));
+ return false;
+ }
+
+ dst += IN_ADDR_SIZE;
+ chars_in_group= 0;
+
+ break;
+ }
+ else
+ {
+ const char *hdp= strchr(HEX_DIGITS, my_tolower(&my_charset_latin1, c));
+
+ if (!hdp)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "invalid character at pos %d.",
+ str_length, str, (int) (p - str)));
+ return false;
+ }
+
+ if (chars_in_group >= 4)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "too many digits in group.",
+ str_length, str));
+ return false;
+ }
+
+ group_value <<= 4;
+ group_value |= hdp - HEX_DIGITS;
+
+ DBUG_ASSERT(group_value <= 0xffff);
+
+ ++chars_in_group;
+ }
+ }
+
+ if (chars_in_group > 0)
+ {
+ if (dst + 2 > ipv6_bytes_end)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "too many groups (2).", str_length, str));
+ return false;
+ }
+
+ dst[0]= (unsigned char) (group_value >> 8) & 0xff;
+ dst[1]= (unsigned char) group_value & 0xff;
+ dst += 2;
+ }
+
+ if (gap_ptr)
+ {
+ if (dst == ipv6_bytes_end)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "no room for a gap (::).", str_length, str));
+ return false;
+ }
+
+ int bytes_to_move= dst - gap_ptr;
+
+ for (int i= 1; i <= bytes_to_move; ++i)
+ {
+ ipv6_bytes_end[-i]= gap_ptr[bytes_to_move - i];
+ gap_ptr[bytes_to_move - i]= 0;
+ }
+
+ dst= ipv6_bytes_end;
+ }
+
+ if (dst < ipv6_bytes_end)
+ {
+ DBUG_PRINT("error", ("str_to_ipv6(%.*s): invalid IPv6 address: "
+ "too few groups.", str_length, str));
+ return false;
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Converts IPv4-binary-address to a string. This function is a portable
+ alternative to inet_ntop(AF_INET).
+
+ @param[in] ipv4 IPv4-address data (byte array)
+ @param[out] str A buffer to store string representation of IPv4-address.
+ It must be at least of INET_ADDRSTRLEN.
+
+ @note The problem with inet_ntop() is that it is available starting from
+ Windows Vista, but the minimum supported version is Windows 2000.
+*/
+
+static void ipv4_to_str(const in_addr *ipv4, char *str)
+{
+ const unsigned char *ipv4_bytes= (const unsigned char *) ipv4;
+
+ sprintf(str, "%d.%d.%d.%d",
+ ipv4_bytes[0], ipv4_bytes[1], ipv4_bytes[2], ipv4_bytes[3]);
+}
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Converts IPv6-binary-address to a string. This function is a portable
+ alternative to inet_ntop(AF_INET6).
+
+ @param[in] ipv6 IPv6-address data (byte array)
+ @param[out] str A buffer to store string representation of IPv6-address.
+ It must be at least of INET6_ADDRSTRLEN.
+
+ @note The problem with inet_ntop() is that it is available starting from
+ Windows Vista, but out the minimum supported version is Windows 2000.
+*/
+
+static void ipv6_to_str(const in6_addr *ipv6, char *str)
+{
+ struct Region
+ {
+ int pos;
+ int length;
+ };
+
+ const unsigned char *ipv6_bytes= (const unsigned char *) ipv6;
+
+ // 1. Translate IPv6-address bytes to words.
+ // We can't just cast to short, because it's not guaranteed
+ // that sizeof (short) == 2. So, we have to make a copy.
+
+ uint16 ipv6_words[IN6_ADDR_NUM_WORDS];
+
+ for (int i= 0; i < IN6_ADDR_NUM_WORDS; ++i)
+ ipv6_words[i]= (ipv6_bytes[2 * i] << 8) + ipv6_bytes[2 * i + 1];
+
+ // 2. Find "the gap" -- longest sequence of zeros in IPv6-address.
+
+ Region gap= { -1, -1 };
+
+ {
+ Region rg= { -1, -1 };
+
+ for (int i = 0; i < IN6_ADDR_NUM_WORDS; ++i)
+ {
+ if (ipv6_words[i] != 0)
+ {
+ if (rg.pos >= 0)
+ {
+ if (rg.length > gap.length)
+ gap= rg;
+
+ rg.pos= -1;
+ rg.length= -1;
+ }
+ }
+ else
+ {
+ if (rg.pos >= 0)
+ {
+ ++rg.length;
+ }
+ else
+ {
+ rg.pos= i;
+ rg.length= 1;
+ }
+ }
+ }
+
+ if (rg.pos >= 0)
+ {
+ if (rg.length > gap.length)
+ gap= rg;
+ }
+ }
+
+ // 3. Convert binary data to string.
+
+ char *p= str;
+
+ for (int i = 0; i < IN6_ADDR_NUM_WORDS; ++i)
+ {
+ if (i == gap.pos)
+ {
+ // We're at the gap position. We should put trailing ':' and jump to
+ // the end of the gap.
+
+ if (i == 0)
+ {
+ // The gap starts from the beginning of the data -- leading ':'
+ // should be put additionally.
+
+ *p= ':';
+ ++p;
+ }
+
+ *p= ':';
+ ++p;
+
+ i += gap.length - 1;
+ }
+ else if (i == 6 && gap.pos == 0 &&
+ (gap.length == 6 || // IPv4-compatible
+ (gap.length == 5 && ipv6_words[5] == 0xffff) // IPv4-mapped
+ ))
+ {
+ // The data represents either IPv4-compatible or IPv4-mapped address.
+ // The IPv6-part (zeros or zeros + ffff) has been already put into
+ // the string (str). Now it's time to dump IPv4-part.
+
+ ipv4_to_str((const in_addr *) (ipv6_bytes + 12), p);
+ return;
+ }
+ else
+ {
+ // Usual IPv6-address-field. Print it out using lower-case
+ // hex-letters without leading zeros (recommended IPv6-format).
+ //
+ // If it is not the last field, append closing ':'.
+
+ p += sprintf(p, "%x", ipv6_words[i]);
+
+ if (i != IN6_ADDR_NUM_WORDS - 1)
+ {
+ *p= ':';
+ ++p;
+ }
+ }
+ }
+
+ *p= 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Converts IP-address-string to IP-address-data.
+
+ @param arg IP-address-string.
+ @param [out] buffer Buffer to store IP-address-data.
+
+ @return Completion status.
+ @retval false Given string does not represent an IP-address.
+ @retval true The string has been converted sucessfully.
+*/
+
+bool Item_func_inet6_aton::calc_value(String *arg, String *buffer)
+{
+ // ipv4-string -> varbinary(4)
+ // ipv6-string -> varbinary(16)
+
+ in_addr ipv4_address;
+ in6_addr ipv6_address;
+
+ if (str_to_ipv4(arg->ptr(), arg->length(), &ipv4_address))
+ {
+ buffer->length(0);
+ buffer->append((char *) &ipv4_address, sizeof (in_addr), &my_charset_bin);
+
+ return true;
+ }
+
+ if (str_to_ipv6(arg->ptr(), arg->length(), &ipv6_address))
+ {
+ buffer->length(0);
+ buffer->append((char *) &ipv6_address, sizeof (in6_addr), &my_charset_bin);
+
+ return true;
+ }
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Converts IP-address-data to IP-address-string.
+
+ @param arg IP-address-data.
+ @param [out] buffer Buffer to store IP-address-string.
+
+ @return Completion status.
+ @retval false The argument does not correspond to IP-address.
+ @retval true The string has been converted sucessfully.
+*/
+
+bool Item_func_inet6_ntoa::calc_value(String *arg, String *buffer)
+{
+ if (arg->charset() != &my_charset_bin)
+ return false;
+
+ if ((int) arg->length() == IN_ADDR_SIZE)
+ {
+ char str[INET_ADDRSTRLEN];
+
+ ipv4_to_str((const in_addr *) arg->ptr(), str);
+
+ buffer->length(0);
+ buffer->append(str, (uint32) strlen(str), &my_charset_latin1);
+
+ return true;
+ }
+ else if ((int) arg->length() == IN6_ADDR_SIZE)
+ {
+ char str[INET6_ADDRSTRLEN];
+
+ ipv6_to_str((const in6_addr *) arg->ptr(), str);
+
+ buffer->length(0);
+ buffer->append(str, (uint32) strlen(str), &my_charset_latin1);
+
+ return true;
+ }
+
+ DBUG_PRINT("info",
+ ("INET6_NTOA(): varbinary(4) or varbinary(16) expected."));
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Checks if the passed string represents an IPv4-address.
+
+ @param arg The string to check.
+
+ @return Check status.
+ @retval false The passed string does not represent an IPv4-address.
+ @retval true The passed string represents an IPv4-address.
+*/
+
+bool Item_func_is_ipv4::calc_value(const String *arg)
+{
+ in_addr ipv4_address;
+
+ return str_to_ipv4(arg->ptr(), arg->length(), &ipv4_address);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Checks if the passed string represents an IPv6-address.
+
+ @param arg The string to check.
+
+ @return Check status.
+ @retval false The passed string does not represent an IPv6-address.
+ @retval true The passed string represents an IPv6-address.
+*/
+
+bool Item_func_is_ipv6::calc_value(const String *arg)
+{
+ in6_addr ipv6_address;
+
+ return str_to_ipv6(arg->ptr(), arg->length(), &ipv6_address);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Checks if the passed IPv6-address is an IPv4-compat IPv6-address.
+
+ @param arg The IPv6-address to check.
+
+ @return Check status.
+ @retval false The passed IPv6-address is not an IPv4-compatible IPv6-address.
+ @retval true The passed IPv6-address is an IPv4-compatible IPv6-address.
+*/
+
+bool Item_func_is_ipv4_compat::calc_value(const String *arg)
+{
+ if ((int) arg->length() != IN6_ADDR_SIZE || arg->charset() != &my_charset_bin)
+ return false;
+
+ return IN6_IS_ADDR_V4COMPAT((struct in6_addr *) arg->ptr());
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ Checks if the passed IPv6-address is an IPv4-mapped IPv6-address.
+
+ @param arg The IPv6-address to check.
+
+ @return Check status.
+ @retval false The passed IPv6-address is not an IPv4-mapped IPv6-address.
+ @retval true The passed IPv6-address is an IPv4-mapped IPv6-address.
+*/
+
+bool Item_func_is_ipv4_mapped::calc_value(const String *arg)
+{
+ if ((int) arg->length() != IN6_ADDR_SIZE || arg->charset() != &my_charset_bin)
+ return false;
+
+ return IN6_IS_ADDR_V4MAPPED((struct in6_addr *) arg->ptr());
+}
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
new file mode 100644
index 00000000000..3a85d367ff1
--- /dev/null
+++ b/sql/item_inetfunc.h
@@ -0,0 +1,244 @@
+#ifndef ITEM_INETFUNC_INCLUDED
+#define ITEM_INETFUNC_INCLUDED
+
+/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2014 MariaDB Foundation
+
+ 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 Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+
+#include "item.h"
+
+/*************************************************************************
+ Item_func_inet_aton implements INET_ATON() SQL-function.
+*************************************************************************/
+
+class Item_func_inet_aton : public Item_int_func
+{
+public:
+ Item_func_inet_aton(Item *a) :Item_int_func(a) {}
+ longlong val_int();
+ const char *func_name() const { return "inet_aton"; }
+ void fix_length_and_dec()
+ {
+ decimals= 0;
+ max_length= 21;
+ maybe_null= 1;
+ unsigned_flag= 1;
+ }
+};
+
+
+/*************************************************************************
+ Item_func_inet_ntoa implements INET_NTOA() SQL-function.
+*************************************************************************/
+
+class Item_func_inet_ntoa : public Item_str_func
+{
+public:
+ Item_func_inet_ntoa(Item *a)
+ : Item_str_func(a)
+ { }
+ String* val_str(String* str);
+ const char *func_name() const { return "inet_ntoa"; }
+ void fix_length_and_dec()
+ {
+ decimals= 0;
+ fix_length_and_charset(3 * 8 + 7, default_charset());
+ maybe_null= 1;
+ }
+};
+
+
+/*************************************************************************
+ Item_func_inet_bool_base implements common code for INET6/IP-related
+ functions returning boolean value.
+*************************************************************************/
+
+class Item_func_inet_bool_base : public Item_bool_func
+{
+public:
+ inline Item_func_inet_bool_base(Item *ip_addr)
+ : Item_bool_func(ip_addr)
+ {
+ null_value= false;
+ }
+
+public:
+ virtual longlong val_int();
+
+protected:
+ virtual bool calc_value(const String *arg) = 0;
+};
+
+
+/*************************************************************************
+ Item_func_inet_str_base implements common code for INET6/IP-related
+ functions returning string value.
+*************************************************************************/
+
+class Item_func_inet_str_base : public Item_str_ascii_func
+{
+public:
+ inline Item_func_inet_str_base(Item *arg)
+ : Item_str_ascii_func(arg)
+ { }
+
+public:
+ virtual String *val_str_ascii(String *buffer);
+
+protected:
+ virtual bool calc_value(String *arg, String *buffer) = 0;
+};
+
+
+/*************************************************************************
+ Item_func_inet6_aton implements INET6_ATON() SQL-function.
+*************************************************************************/
+
+class Item_func_inet6_aton : public Item_func_inet_str_base
+{
+public:
+ inline Item_func_inet6_aton(Item *ip_addr)
+ : Item_func_inet_str_base(ip_addr)
+ { }
+
+public:
+ virtual const char *func_name() const
+ { return "inet6_aton"; }
+
+ virtual void fix_length_and_dec()
+ {
+ decimals= 0;
+ fix_length_and_charset(16, &my_charset_bin);
+ maybe_null= 1;
+ }
+
+protected:
+ virtual bool calc_value(String *arg, String *buffer);
+};
+
+
+/*************************************************************************
+ Item_func_inet6_ntoa implements INET6_NTOA() SQL-function.
+*************************************************************************/
+
+class Item_func_inet6_ntoa : public Item_func_inet_str_base
+{
+public:
+ inline Item_func_inet6_ntoa(Item *ip_addr)
+ : Item_func_inet_str_base(ip_addr)
+ { }
+
+public:
+ virtual const char *func_name() const
+ { return "inet6_ntoa"; }
+
+ virtual void fix_length_and_dec()
+ {
+ decimals= 0;
+
+ // max length: IPv6-address -- 16 bytes
+ // 16 bytes / 2 bytes per group == 8 groups => 7 delimiter
+ // 4 symbols per group
+ fix_length_and_charset(8 * 4 + 7, default_charset());
+
+ maybe_null= 1;
+ }
+
+protected:
+ virtual bool calc_value(String *arg, String *buffer);
+};
+
+
+/*************************************************************************
+ Item_func_is_ipv4 implements IS_IPV4() SQL-function.
+*************************************************************************/
+
+class Item_func_is_ipv4 : public Item_func_inet_bool_base
+{
+public:
+ inline Item_func_is_ipv4(Item *ip_addr)
+ : Item_func_inet_bool_base(ip_addr)
+ { }
+
+public:
+ virtual const char *func_name() const
+ { return "is_ipv4"; }
+
+protected:
+ virtual bool calc_value(const String *arg);
+};
+
+
+/*************************************************************************
+ Item_func_is_ipv6 implements IS_IPV6() SQL-function.
+*************************************************************************/
+
+class Item_func_is_ipv6 : public Item_func_inet_bool_base
+{
+public:
+ inline Item_func_is_ipv6(Item *ip_addr)
+ : Item_func_inet_bool_base(ip_addr)
+ { }
+
+public:
+ virtual const char *func_name() const
+ { return "is_ipv6"; }
+
+protected:
+ virtual bool calc_value(const String *arg);
+};
+
+
+/*************************************************************************
+ Item_func_is_ipv4_compat implements IS_IPV4_COMPAT() SQL-function.
+*************************************************************************/
+
+class Item_func_is_ipv4_compat : public Item_func_inet_bool_base
+{
+public:
+ inline Item_func_is_ipv4_compat(Item *ip_addr)
+ : Item_func_inet_bool_base(ip_addr)
+ { }
+
+public:
+ virtual const char *func_name() const
+ { return "is_ipv4_compat"; }
+
+protected:
+ virtual bool calc_value(const String *arg);
+};
+
+
+/*************************************************************************
+ Item_func_is_ipv4_mapped implements IS_IPV4_MAPPED() SQL-function.
+*************************************************************************/
+
+class Item_func_is_ipv4_mapped : public Item_func_inet_bool_base
+{
+public:
+ inline Item_func_is_ipv4_mapped(Item *ip_addr)
+ : Item_func_inet_bool_base(ip_addr)
+ { }
+
+public:
+ virtual const char *func_name() const
+ { return "is_ipv4_mapped"; }
+
+protected:
+ virtual bool calc_value(const String *arg);
+};
+
+#endif // ITEM_INETFUNC_INCLUDED
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 100d54133dd..ec6ab0f3040 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3861,48 +3861,6 @@ void Item_func_export_set::fix_length_and_dec()
fix_char_length(length * 64 + sep_length * 63);
}
-String* Item_func_inet_ntoa::val_str(String* str)
-{
- DBUG_ASSERT(fixed == 1);
- uchar buf[8], *p;
- ulonglong n = (ulonglong) args[0]->val_int();
- char num[4];
-
- /*
- We do not know if args[0] is NULL until we have called
- some val function on it if args[0] is not a constant!
-
- Also return null if n > 255.255.255.255
- */
- if ((null_value= (args[0]->null_value || n > 0xffffffff)))
- return 0; // Null value
-
- str->set_charset(collation.collation);
- str->length(0);
- int4store(buf,n);
-
- /* Now we can assume little endian. */
-
- num[3]='.';
- for (p=buf+4 ; p-- > buf ; )
- {
- uint c = *p;
- uint n1,n2; // Try to avoid divisions
- n1= c / 100; // 100 digits
- c-= n1*100;
- n2= c / 10; // 10 digits
- c-=n2*10; // last digit
- num[0]=(char) n1+'0';
- num[1]=(char) n2+'0';
- num[2]=(char) c+'0';
- uint length= (n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero
- uint dot_length= (p <= buf) ? 1 : 0;
- (void) str->append(num + 4 - length, length - dot_length,
- &my_charset_latin1);
- }
- return str;
-}
-
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
@@ -5098,8 +5056,10 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
case DYN_COL_UINT:
if (signed_value || val.x.ulong_value <= LONGLONG_MAX)
{
- if (int_to_datetime_with_warn(val.x.ulong_value, ltime, fuzzy_date,
- 0 /* TODO */))
+ bool neg= val.x.ulong_value > LONGLONG_MAX;
+ if (int_to_datetime_with_warn(neg, neg ? -val.x.ulong_value :
+ val.x.ulong_value,
+ ltime, fuzzy_date, 0 /* TODO */))
goto null;
return 0;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index ff8a916d200..f3d5c064423 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -880,21 +880,6 @@ class Item_func_export_set: public Item_str_func
const char *func_name() const { return "export_set"; }
};
-class Item_func_inet_ntoa : public Item_str_func
-{
-public:
- Item_func_inet_ntoa(Item *a) :Item_str_func(a)
- {
- }
- String* val_str(String* str);
- const char *func_name() const { return "inet_ntoa"; }
- void fix_length_and_dec()
- {
- decimals= 0;
- fix_length_and_charset(3 * 8 + 7, default_charset());
- maybe_null= 1;
- }
-};
class Item_func_quote :public Item_str_func
{
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 0aaeb3d55db..5fddad56028 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1298,6 +1298,16 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
if (!(val= args->val_decimal(&decimal_value)))
return true;
interval->neg= my_decimal2seconds(val, &second, &second_part);
+ if (second == LONGLONG_MAX)
+ {
+ ErrConvDecimal err(val);
+ push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), "DECIMAL",
+ err.ptr());
+ return true;
+ }
+
interval->second= second;
interval->second_part= second_part;
return false;
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 30db7e635e2..759b929ff82 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2899,7 +2899,7 @@ bool Item_func_xml_update::collect_result(String *str,
str->length(0);
str->set_charset(collation.collation);
return
- /* Put the XML part preceeding the replaced piece */
+ /* Put the XML part preceding the replaced piece */
str->append(xml.raw()->ptr(), cut->beg - xml.raw()->ptr() - offs) ||
/* Put the replacement */
str->append(replace->ptr(), replace->length()) ||
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c8b394e8290..4edd41fdb2e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -4101,7 +4101,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
if ((error= rows_event_stmt_cleanup(rgi, thd)))
{
const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
- "Error in cleaning up after an event preceeding the commit; "
+ "Error in cleaning up after an event preceding the commit; "
"the group log file/position: %s %s",
const_cast<Relay_log_info*>(rli)->group_master_log_name,
llstr(const_cast<Relay_log_info*>(rli)->group_master_log_pos,
diff --git a/sql/log_event.h b/sql/log_event.h
index 020af59ae81..2091d968558 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -2004,7 +2004,7 @@ public:
bool is_valid() const { return query != 0; }
/*
- Returns number of bytes additionaly written to post header by derived
+ Returns number of bytes additionally written to post header by derived
events (so far it is only Execute_load_query event).
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index 0c35ac5b029..b63db9ecea2 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -1341,8 +1341,14 @@ int Key_value_records_iterator::get_next(range_id_t *range_info)
}
handler *h= owner->file;
+ uchar *lookup_key;
+ if (owner->keypar.use_key_pointers)
+ memcpy(&lookup_key, identical_key_it.read_ptr1, sizeof(void*));
+ else
+ lookup_key= identical_key_it.read_ptr1;
+
if ((res= h->ha_index_next_same(h->get_table()->record[0],
- identical_key_it.read_ptr1,
+ lookup_key,
owner->keypar.key_tuple_length)))
{
/* It's either HA_ERR_END_OF_FILE or some other error */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b523769677e..3ba38ac6ec2 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2174,6 +2174,7 @@ void clean_up(bool print_message)
free_global_table_stats();
free_global_index_stats();
delete_dynamic(&all_options);
+ free_all_rpl_filters();
#ifdef HAVE_REPLICATION
end_slave_list();
#endif
@@ -2216,6 +2217,13 @@ void clean_up(bool print_message)
mysql_mutex_unlock(&LOCK_thread_count);
free_list(opt_plugin_load_list_ptr);
+
+ if (THR_THD)
+ (void) pthread_key_delete(THR_THD);
+
+ if (THR_MALLOC)
+ (void) pthread_key_delete(THR_MALLOC);
+
/*
The following lines may never be executed as the main thread may have
killed us
@@ -7886,7 +7894,7 @@ struct my_option my_long_options[]=
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"plugin-load-add", OPT_PLUGIN_LOAD_ADD,
"Optional semicolon-separated list of plugins to load. This option adds "
- "to the list speficied by --plugin-load in an incremental way. "
+ "to the list specified by --plugin-load in an incremental way. "
"It can be specified many times, adding more plugins every time.",
0, 0, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index bfba74cf587..fc2aa75e604 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -8291,6 +8291,17 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
if (field->cmp_type() == STRING_RESULT && value->cmp_type() != STRING_RESULT)
goto end;
err= value->save_in_field_no_warnings(field, 1);
+ if (err == 2 && field->cmp_type() == STRING_RESULT)
+ {
+ if (type == Item_func::EQ_FUNC)
+ {
+ tree= new (alloc) SEL_ARG(field, 0, 0);
+ tree->type= SEL_ARG::IMPOSSIBLE;
+ }
+ else
+ tree= NULL; /* Cannot infer anything */
+ goto end;
+ }
if (err > 0)
{
if (field->cmp_type() != value->result_type())
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index e00083c4b8b..6e65b5ea177 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -4120,6 +4120,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
{
if (!(key_field= field->new_key_field(thd->mem_root, table,
group_buff,
+ key_part_info->length,
field->null_ptr,
field->null_bit)))
goto err;
diff --git a/sql/password.c b/sql/password.c
index 7a3d8aafde3..37d06136d80 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -442,7 +442,7 @@ void make_scrambled_password(char *to, const char *password)
/*
Produce an obscure octet sequence from password and random
- string, recieved from the server. This sequence corresponds to the
+ string, received from the server. This sequence corresponds to the
password, but password can not be easily restored from it. The sequence
is then sent to the server for validation. Trailing zero is not stored
in the buf as it is not needed.
@@ -476,7 +476,7 @@ scramble(char *to, const char *message, const char *password)
/*
Check that scrambled message corresponds to the password; the function
- is used by server to check that recieved reply is authentic.
+ is used by server to check that received reply is authentic.
This function does not check lengths of given strings: message must be
null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE
long (if not, something fishy is going on).
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index 17c3b15c902..105bdad6f97 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -326,7 +326,9 @@ rpl_slave_state::update(uint32 domain_id, uint32 server_id, uint64 sub_id,
{
if (rgi->gtid_ignore_duplicate_state==rpl_group_info::GTID_DUPLICATE_OWNER)
{
+#ifndef DBUG_OFF
Relay_log_info *rli= rgi->rli;
+#endif
uint32 count= elem->owner_count;
DBUG_ASSERT(count > 0);
DBUG_ASSERT(elem->owner_rli == rli);
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index fcb6a849fb1..05227a29775 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -1229,7 +1229,7 @@ bool Deferred_log_events::execute(rpl_group_info *rgi)
void Deferred_log_events::rewind()
{
/*
- Reset preceeding Query log event events which execution was
+ Reset preceding Query log event events which execution was
deferred because of slave side filtering.
*/
if (!is_empty())
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index ed7976e2abd..c36bdf3869f 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -5196,8 +5196,8 @@ ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER
ER_VIEW_NO_EXPLAIN
eng "EXPLAIN/SHOW can not be issued; lacking privileges for underlying table"
ger "EXPLAIN/SHOW kann nicht verlangt werden. Rechte für zugrunde liegende Tabelle fehlen"
- rus "EXPLAIN/SHOW не может быть выполненно; недоÑтаточно прав на такблицы запроÑа"
- ukr "EXPLAIN/SHOW не може бути віконано; немає прав на тиблиці запиту"
+ rus "EXPLAIN/SHOW не может быть выполнено; недоÑтаточно прав на таблицы запроÑа"
+ ukr "EXPLAIN/SHOW не може бути виконано; немає прав на таблиці запиту"
ER_FRM_UNKNOWN_TYPE
eng "File '%-.192s' has unknown type '%-.64s' in its header"
ger "Datei '%-.192s' hat unbekannten Typ '%-.64s' im Header"
diff --git a/sql/slave.cc b/sql/slave.cc
index 7e6162c88b4..54a32f320c0 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4436,7 +4436,7 @@ pthread_handler_t handle_slave_sql(void *arg)
/*
binlog_annotate_row_events must be TRUE only after an Annotate_rows event
- has been recieved and only till the last corresponding rbr event has been
+ has been received and only till the last corresponding rbr event has been
applied. In all other cases it must be FALSE.
*/
thd->variables.binlog_annotate_row_events= 0;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4ea0692fa0e..b643f0689e2 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -877,7 +877,6 @@ static char *fix_plugin_ptr(char *name)
*/
static bool fix_user_plugin_ptr(ACL_USER *user)
{
- user->salt_len= 0;
if (my_strcasecmp(system_charset_info, user->plugin.str,
native_password_plugin_name.str) == 0)
user->plugin= native_password_plugin_name;
@@ -888,7 +887,8 @@ static bool fix_user_plugin_ptr(ACL_USER *user)
else
return true;
- set_user_salt(user, user->auth_string.str, user->auth_string.length);
+ if (user->auth_string.length)
+ set_user_salt(user, user->auth_string.str, user->auth_string.length);
return false;
}
@@ -1259,7 +1259,11 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
{
user.plugin.str= tmpstr;
user.plugin.length= strlen(user.plugin.str);
- if (user.auth_string.length)
+ user.auth_string.str=
+ safe_str(get_field(&acl_memroot, table->field[next_field++]));
+ user.auth_string.length= strlen(user.auth_string.str);
+
+ if (user.auth_string.length && password_len)
{
sql_print_warning("'user' entry '%s@%s' has both a password "
"and an authentication plugin specified. The "
@@ -1267,9 +1271,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
safe_str(user.user.str),
safe_str(user.host.hostname));
}
- user.auth_string.str=
- safe_str(get_field(&acl_memroot, table->field[next_field++]));
- user.auth_string.length= strlen(user.auth_string.str);
fix_user_plugin_ptr(&user);
}
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index bea331fe8ee..91b3281e231 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -718,7 +718,7 @@ static void update_global_user_stats_with_user(THD *thd,
user_stats->cpu_time+= (thd->status_var.cpu_time -
thd->org_status_var.cpu_time);
/*
- This is handle specially as bytes_recieved is incremented BEFORE
+ This is handle specially as bytes_received is incremented BEFORE
org_status_var is copied.
*/
user_stats->bytes_received+= (thd->org_status_var.bytes_received-
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index c2941d55dcb..a910ed6290f 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -392,17 +392,13 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
if (parent_lex->get_free_table_map(&map, &tablenr))
{
/* There is no enough table bits, fall back to materialization. */
- derived->change_refs_to_fields();
- derived->set_materialized_derived();
- goto exit_merge;
+ goto unconditional_materialization;
}
if (dt_select->leaf_tables.elements + tablenr > MAX_TABLES)
{
/* There is no enough table bits, fall back to materialization. */
- derived->change_refs_to_fields();
- derived->set_materialized_derived();
- goto exit_merge;
+ goto unconditional_materialization;
}
if (dt_select->options & OPTION_SCHEMA_TABLE)
@@ -473,6 +469,15 @@ exit_merge:
if (arena)
thd->restore_active_arena(arena, &backup);
DBUG_RETURN(res);
+
+unconditional_materialization:
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
+ if (!derived->table || !derived->table->created)
+ res= mysql_derived_create(thd, lex, derived);
+ if (!res)
+ res= mysql_derived_fill(thd, lex, derived);
+ goto exit_merge;
}
diff --git a/sql/sql_error.h b/sql/sql_error.h
index 14338ee041d..a993e9203c9 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -575,11 +575,16 @@ public:
class ErrConvInteger : public ErrConv
{
- longlong num;
+ longlong m_value;
+ bool m_unsigned;
public:
- ErrConvInteger(longlong num_arg) : ErrConv(), num(num_arg) {}
+ ErrConvInteger(longlong num_arg, bool unsigned_flag= false) :
+ ErrConv(), m_value(num_arg), m_unsigned(unsigned_flag) {}
const char *ptr() const
- { return llstr(num, err_buffer); }
+ {
+ return m_unsigned ? ullstr(m_value, err_buffer) :
+ llstr(m_value, err_buffer);
+ }
};
class ErrConvDouble: public ErrConv
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index abd23c344c2..cab9628837c 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -929,6 +929,9 @@ int JOIN_CACHE::alloc_buffer()
join->shrink_join_buffers(join_tab, curr_buff_space_sz,
join_buff_space_limit))))
goto fail;
+
+ if (for_explain_only)
+ return 0;
for (ulong buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; )
{
@@ -1023,6 +1026,7 @@ int JOIN_CACHE::realloc_buffer()
SYNOPSIS
init()
+ for_explain join buffer is initialized for explain only
DESCRIPTION
The function initializes the join cache structure. It supposed to be called
@@ -1044,10 +1048,12 @@ int JOIN_CACHE::realloc_buffer()
1 otherwise
*/
-int JOIN_CACHE::init()
+int JOIN_CACHE::init(bool for_explain)
{
DBUG_ENTER("JOIN_CACHE::init");
+ for_explain_only= for_explain;
+
calc_record_fields();
collect_info_on_key_args();
@@ -2632,6 +2638,7 @@ void JOIN_CACHE_BKAH::save_explain_data(struct st_explain_bka_type *explain)
SYNOPSIS
init()
+ for_explain join buffer is initialized for explain only
DESCRIPTION
The function initializes the cache structure with a hash table in it.
@@ -2651,7 +2658,7 @@ void JOIN_CACHE_BKAH::save_explain_data(struct st_explain_bka_type *explain)
1 otherwise
*/
-int JOIN_CACHE_HASHED::init()
+int JOIN_CACHE_HASHED::init(bool for_explain)
{
int rc= 0;
TABLE_REF *ref= &join_tab->ref;
@@ -2663,8 +2670,8 @@ int JOIN_CACHE_HASHED::init()
key_length= ref->key_length;
- if ((rc= JOIN_CACHE::init()))
- DBUG_RETURN (rc);
+ if ((rc= JOIN_CACHE::init(for_explain)) || for_explain)
+ DBUG_RETURN (rc);
if (!(key_buff= (uchar*) sql_alloc(key_length)))
DBUG_RETURN(1);
@@ -3572,6 +3579,7 @@ void JOIN_CACHE_BNL::read_next_candidate_for_match(uchar *rec_ptr)
SYNOPSIS
init
+ for_explain join buffer is initialized for explain only
DESCRIPTION
The function initializes the cache structure. It is supposed to be called
@@ -3586,14 +3594,14 @@ void JOIN_CACHE_BNL::read_next_candidate_for_match(uchar *rec_ptr)
1 otherwise
*/
-int JOIN_CACHE_BNL::init()
+int JOIN_CACHE_BNL::init(bool for_explain)
{
DBUG_ENTER("JOIN_CACHE_BNL::init");
if (!(join_tab_scan= new JOIN_TAB_SCAN(join, join_tab)))
DBUG_RETURN(1);
- DBUG_RETURN(JOIN_CACHE::init());
+ DBUG_RETURN(JOIN_CACHE::init(for_explain));
}
@@ -3758,6 +3766,7 @@ void JOIN_CACHE_BNLH::read_next_candidate_for_match(uchar *rec_ptr)
SYNOPSIS
init
+ for_explain join buffer is initialized for explain only
DESCRIPTION
The function initializes the cache structure. It is supposed to be called
@@ -3772,14 +3781,14 @@ void JOIN_CACHE_BNLH::read_next_candidate_for_match(uchar *rec_ptr)
1 otherwise
*/
-int JOIN_CACHE_BNLH::init()
+int JOIN_CACHE_BNLH::init(bool for_explain)
{
DBUG_ENTER("JOIN_CACHE_BNLH::init");
if (!(join_tab_scan= new JOIN_TAB_SCAN(join, join_tab)))
DBUG_RETURN(1);
- DBUG_RETURN(JOIN_CACHE_HASHED::init());
+ DBUG_RETURN(JOIN_CACHE_HASHED::init(for_explain));
}
@@ -4176,6 +4185,8 @@ Initialize the BKA join cache
SYNOPSIS
init
+ for_explain join buffer is initialized for explain only
+
DESCRIPTION
The function initializes the cache structure. It is supposed to be called
@@ -4190,7 +4201,7 @@ RETURN VALUE
1 otherwise
*/
-int JOIN_CACHE_BKA::init()
+int JOIN_CACHE_BKA::init(bool for_explain)
{
int res;
bool check_only_first_match= join_tab->check_only_first_match();
@@ -4209,7 +4220,7 @@ if (!(join_tab_scan= jsm= new JOIN_TAB_SCAN_MRR(join, join_tab,
mrr_mode, rs_funcs)))
DBUG_RETURN(1);
-if ((res= JOIN_CACHE::init()))
+if ((res= JOIN_CACHE::init(for_explain)))
DBUG_RETURN(res);
if (use_emb_key)
@@ -4570,6 +4581,7 @@ if (no_association &&
SYNOPSIS
init
+ for_explain join buffer is initialized for explain only
DESCRIPTION
The function initializes the cache structure. It is supposed to be called
@@ -4584,7 +4596,7 @@ if (no_association &&
1 otherwise
*/
-int JOIN_CACHE_BKAH::init()
+int JOIN_CACHE_BKAH::init(bool for_explain)
{
bool check_only_first_match= join_tab->check_only_first_match();
@@ -4603,7 +4615,7 @@ int JOIN_CACHE_BKAH::init()
mrr_mode, rs_funcs)))
DBUG_RETURN(1);
- DBUG_RETURN(JOIN_CACHE_HASHED::init());
+ DBUG_RETURN(JOIN_CACHE_HASHED::init(for_explain));
}
diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h
index 568cc91ecf7..a3e69f92e34 100644
--- a/sql/sql_join_cache.h
+++ b/sql/sql_join_cache.h
@@ -99,6 +99,9 @@ private:
/* Size of the offset of a field within a record in the cache */
uint size_of_fld_ofs;
+ /* This structure is used only for explain, not for execution */
+ bool for_explain_only;
+
protected:
/* 3 functions below actually do not use the hidden parameter 'this' */
@@ -595,7 +598,7 @@ public:
JOIN_CACHE *next_cache;
/* Shall initialize the join cache structure */
- virtual int init();
+ virtual int init(bool for_explain);
/* Get the current size of the cache join buffer */
size_t get_join_buffer_size() { return buff_size; }
@@ -991,7 +994,7 @@ protected:
public:
/* Initialize a hashed join cache */
- int init();
+ int init(bool for_explain);
/* Reset the buffer of a hashed join cache for reading/writing */
void reset(bool for_writing);
@@ -1127,7 +1130,7 @@ public:
:JOIN_CACHE(j, tab, prev) {}
/* Initialize the BNL cache */
- int init();
+ int init(bool for_explain);
enum Join_algorithm get_join_alg() { return BNL_JOIN_ALG; }
@@ -1194,7 +1197,7 @@ public:
: JOIN_CACHE_HASHED(j, tab, prev) {}
/* Initialize the BNLH cache */
- int init();
+ int init(bool for_explain);
enum Join_algorithm get_join_alg() { return BNLH_JOIN_ALG; }
@@ -1325,7 +1328,7 @@ public:
uchar **get_curr_association_ptr() { return &curr_association; }
/* Initialize the BKA cache */
- int init();
+ int init(bool for_explain);
enum Join_algorithm get_join_alg() { return BKA_JOIN_ALG; }
@@ -1421,7 +1424,7 @@ public:
uchar **get_curr_association_ptr() { return &curr_matching_chain; }
/* Initialize the BKAH cache */
- int init();
+ int init(bool for_explain);
enum Join_algorithm get_join_alg() { return BKAH_JOIN_ALG; }
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index bdf26ec0292..534a8fa5484 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2013, Monty Progrm Ab
+ Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2014, SkySQL Ab.
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
@@ -58,13 +58,17 @@ XML_TAG::XML_TAG(int l, String f, String v)
}
+#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache))
+#define PUSH(A) *(stack_pos++)=(A)
+
class READ_INFO {
File file;
uchar *buffer, /* Buffer for read text */
*end_of_buff; /* Data in bufferts ends here */
uint buff_length, /* Length of buffert */
max_length; /* Max length of row */
- char *field_term_ptr,*line_term_ptr,*line_start_ptr,*line_start_end;
+ const uchar *field_term_ptr,*line_term_ptr;
+ const char *line_start_ptr,*line_start_end;
uint field_term_length,line_term_length,enclosed_length;
int field_term_char,line_term_char,enclosed_char,escape_char;
int *stack,*stack_pos;
@@ -88,7 +92,7 @@ public:
int read_fixed_length(void);
int next_line(void);
char unescape(char chr);
- int terminator(char *ptr,uint length);
+ int terminator(const uchar *ptr, uint length);
bool find_start_of_fields();
/* load xml */
List<XML_TAG> taglist;
@@ -114,6 +118,15 @@ public:
either the table or THD value
*/
void set_io_cache_arg(void* arg) { cache.arg = arg; }
+
+ /**
+ skip all data till the eof.
+ */
+ void skip_data_till_eof()
+ {
+ while (GET != my_b_EOF)
+ ;
+ }
};
static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
@@ -531,8 +544,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (error)
{
if (read_file_from_client)
- while (!read_info.next_line())
- ;
+ read_info.skip_data_till_eof();
#ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open())
@@ -1337,10 +1349,18 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
found_end_of_line(false), eof(false), need_end_io_cache(false),
error(false), line_cuted(false), found_null(false), read_charset(cs)
{
- field_term_ptr=(char*) field_term.ptr();
+ /*
+ Field and line terminators must be interpreted as sequence of unsigned char.
+ Otherwise, non-ascii terminators will be negative on some platforms,
+ and positive on others (depending on the implementation of char).
+ */
+ field_term_ptr=
+ static_cast<const uchar*>(static_cast<const void*>(field_term.ptr()));
field_term_length= field_term.length();
- line_term_ptr=(char*) line_term.ptr();
+ line_term_ptr=
+ static_cast<const uchar*>(static_cast<const void*>(line_term.ptr()));
line_term_length= line_term.length();
+
level= 0; /* for load xml */
if (line_start.length() == 0)
{
@@ -1349,7 +1369,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
}
else
{
- line_start_ptr=(char*) line_start.ptr();
+ line_start_ptr= line_start.ptr();
line_start_end=line_start_ptr+line_start.length();
start_of_line= 1;
}
@@ -1358,12 +1378,12 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
!memcmp(field_term_ptr,line_term_ptr,field_term_length))
{
line_term_length=0;
- line_term_ptr=(char*) "";
+ line_term_ptr= NULL;
}
enclosed_char= (enclosed_length=enclosed_par.length()) ?
(uchar) enclosed_par[0] : INT_MAX;
- field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX;
- line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX;
+ field_term_char= field_term_length ? field_term_ptr[0] : INT_MAX;
+ line_term_char= line_term_length ? line_term_ptr[0] : INT_MAX;
/* Set of a stack for unget if long terminators */
uint length= MY_MAX(cs->mbmaxlen, MY_MAX(field_term_length, line_term_length)) + 1;
@@ -1418,11 +1438,7 @@ READ_INFO::~READ_INFO()
}
-#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache))
-#define PUSH(A) *(stack_pos++)=(A)
-
-
-inline int READ_INFO::terminator(char *ptr,uint length)
+inline int READ_INFO::terminator(const uchar *ptr,uint length)
{
int chr=0; // Keep gcc happy
uint i;
@@ -1437,7 +1453,7 @@ inline int READ_INFO::terminator(char *ptr,uint length)
return 1;
PUSH(chr);
while (i-- > 1)
- PUSH((uchar) *--ptr);
+ PUSH(*--ptr);
return 0;
}
@@ -1569,7 +1585,7 @@ int READ_INFO::read_field()
if (my_mbcharlen(read_charset, chr) > 1 &&
to + my_mbcharlen(read_charset, chr) <= end_of_buff)
{
- uchar* p= (uchar*) to;
+ uchar* p= to;
int ml, i;
*to++ = chr;
@@ -1594,7 +1610,7 @@ int READ_INFO::read_field()
(const char *)to))
continue;
for (i= 0; i < ml; i++)
- PUSH((uchar) *--to);
+ PUSH(*--to);
chr= GET;
}
#endif
@@ -1743,7 +1759,7 @@ bool READ_INFO::find_start_of_fields()
return 1;
}
} while ((char) chr != line_start_ptr[0]);
- for (char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++)
+ for (const char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++)
{
chr=GET; // Eof will be checked later
if ((char) chr != *ptr)
@@ -1751,7 +1767,7 @@ bool READ_INFO::find_start_of_fields()
PUSH(chr);
while (--ptr != line_start_ptr)
{ // Restart with next char
- PUSH((uchar) *ptr);
+ PUSH( *ptr);
}
goto try_again;
}
@@ -1947,7 +1963,7 @@ int READ_INFO::read_xml()
// row tag should be in ROWS IDENTIFIED BY '<row>' - stored in line_term
if((tag.length() == line_term_length -2) &&
- (strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
+ (memcmp(tag.ptr(), line_term_ptr + 1, tag.length()) == 0))
{
DBUG_PRINT("read_xml", ("start-of-row: %i %s %s",
level,tag.c_ptr_safe(), line_term_ptr));
@@ -2009,7 +2025,7 @@ int READ_INFO::read_xml()
}
if((tag.length() == line_term_length -2) &&
- (strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
+ (memcmp(tag.ptr(), line_term_ptr + 1, tag.length()) == 0))
{
DBUG_PRINT("read_xml", ("found end-of-row %i %s",
level, tag.c_ptr_safe()));
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 21463afa1b3..4e19d648cfa 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4880,6 +4880,10 @@ end_with_restore_list:
goto create_sp_error;
}
+ if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
+ NULL, NULL, 0, 0))
+ goto create_sp_error;
+
/*
Check that a database directory with this name
exists. Design note: This won't work on virtual databases
@@ -4891,10 +4895,6 @@ end_with_restore_list:
goto create_sp_error;
}
- if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
- NULL, NULL, 0, 0))
- goto create_sp_error;
-
name= lex->sphead->name(&namelen);
#ifdef HAVE_DLOPEN
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 3456a7b381f..8a6de8b6693 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -74,7 +74,7 @@ When one supplies long data for a placeholder:
- Server gets the long data in pieces with command type
'COM_STMT_SEND_LONG_DATA'.
- - The packet recieved will have the format as:
+ - The packet received will have the format as:
[COM_STMT_SEND_LONG_DATA:1][STMT_ID:4][parameter_number:2][data]
- data from the packet is appended to the long data value buffer for this
placeholder.
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 0676fca8fdc..5dc19181e9b 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -253,7 +253,8 @@ template <class T> bool valid_buffer_range(T jump,
OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
OPTIMIZER_SWITCH_SEMIJOIN | \
OPTIMIZER_SWITCH_FIRSTMATCH | \
- OPTIMIZER_SWITCH_LOOSE_SCAN )
+ OPTIMIZER_SWITCH_LOOSE_SCAN | \
+ OPTIMIZER_SWITCH_EXISTS_TO_IN)
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
use strictly more than 64 bits by adding one more define above, you should
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b97cedb5b05..2e4227ed8a0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1248,7 +1248,8 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
part of the nested outer join, and we can't do partition pruning
(TODO: check if this limitation can be lifted)
*/
- if (!tbl->embedding)
+ if (!tbl->embedding ||
+ (tbl->embedding && tbl->embedding->sj_on_expr))
{
Item *prune_cond= tbl->on_expr? tbl->on_expr : conds;
tbl->table->all_partitions_pruned_away= prune_partitions(thd,
@@ -3074,8 +3075,7 @@ void JOIN::exec_inner()
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure);
thd->limit_found_rows= curr_join->send_records;
- if (curr_join->order && curr_join->sortorder &&
- curr_join->select_options & OPTION_FOUND_ROWS)
+ if (curr_join->order && curr_join->filesort_found_rows)
{
/* Use info provided by filesort. */
DBUG_ASSERT(curr_join->table_count > curr_join->const_tables);
@@ -7367,6 +7367,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
Go through the "keypart{N}=..." equalities and find those that were
already taken into account in table->cond_selectivity.
*/
+ keyuse= pos->key;
while (keyuse->table == table && keyuse->key == key)
{
if (!(keyuse->used_tables & (rem_tables | table->map)))
@@ -7435,21 +7436,28 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
If the field f from the table is equal to a field from one the
earlier joined tables then the selectivity of the range conditions
over the field f must be discounted.
- */
- for (Field **f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
+
+ We need to discount selectivity only if we're using ref-based
+ access method (and have sel!=1).
+ If we use ALL/range/index_merge, then sel==1, and no need to discount.
+ */
+ if (pos->key != NULL)
{
- if (!bitmap_is_set(read_set, field->field_index) ||
- !field->next_equal_field)
- continue;
- for (Field *next_field= field->next_equal_field;
- next_field != field;
- next_field= next_field->next_equal_field)
+ for (Field **f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
- if (!(next_field->table->map & rem_tables) && next_field->table != table)
- {
- if (field->cond_selectivity > 0)
- sel/= field->cond_selectivity;
- break;
+ if (!bitmap_is_set(read_set, field->field_index) ||
+ !field->next_equal_field)
+ continue;
+ for (Field *next_field= field->next_equal_field;
+ next_field != field;
+ next_field= next_field->next_equal_field)
+ {
+ if (!(next_field->table->map & rem_tables) && next_field->table != table)
+ {
+ if (field->cond_selectivity > 0)
+ sel/= field->cond_selectivity;
+ break;
+ }
}
}
}
@@ -10541,7 +10549,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (cache_level == 1)
prev_cache= 0;
if ((tab->cache= new JOIN_CACHE_BNL(join, tab, prev_cache)) &&
- ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ !tab->cache->init(options & SELECT_DESCRIBE))
{
tab->icp_other_tables_ok= FALSE;
return (2 - MY_TEST(!prev_cache));
@@ -10576,7 +10584,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (cache_level == 3)
prev_cache= 0;
if ((tab->cache= new JOIN_CACHE_BNLH(join, tab, prev_cache)) &&
- ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ !tab->cache->init(options & SELECT_DESCRIBE))
{
tab->icp_other_tables_ok= FALSE;
return (4 - MY_TEST(!prev_cache));
@@ -10597,7 +10605,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (cache_level == 5)
prev_cache= 0;
if ((tab->cache= new JOIN_CACHE_BKA(join, tab, flags, prev_cache)) &&
- ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ !tab->cache->init(options & SELECT_DESCRIBE))
return (6 - MY_TEST(!prev_cache));
goto no_join_cache;
}
@@ -10606,7 +10614,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (cache_level == 7)
prev_cache= 0;
if ((tab->cache= new JOIN_CACHE_BKAH(join, tab, flags, prev_cache)) &&
- ((options & SELECT_DESCRIBE) || !tab->cache->init()))
+ !tab->cache->init(options & SELECT_DESCRIBE))
{
tab->idx_cond_fact_out= FALSE;
return (8 - MY_TEST(!prev_cache));
@@ -11018,20 +11026,25 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
else if (!table->covering_keys.is_clear_all() &&
!(tab->select && tab->select->quick))
{ // Only read index tree
+ if (tab->loosescan_match_tab)
+ tab->index= tab->loosescan_key;
+ else
+ {
#ifdef BAD_OPTIMIZATION
- /*
- It has turned out that the below change, while speeding things
- up for disk-bound loads, slows them down for cases when the data
- is in disk cache (see BUG#35850):
- See bug #26447: "Using the clustered index for a table scan
- is always faster than using a secondary index".
- */
- if (table->s->primary_key != MAX_KEY &&
- table->file->primary_key_is_clustered())
- tab->index= table->s->primary_key;
- else
+ /*
+ It has turned out that the below change, while speeding things
+ up for disk-bound loads, slows them down for cases when the data
+ is in disk cache (see BUG#35850):
+ See bug #26447: "Using the clustered index for a table scan
+ is always faster than using a secondary index".
+ */
+ if (table->s->primary_key != MAX_KEY &&
+ table->file->primary_key_is_clustered())
+ tab->index= table->s->primary_key;
+ else
#endif
- tab->index=find_shortest_key(table, & table->covering_keys);
+ tab->index=find_shortest_key(table, & table->covering_keys);
+ }
tab->read_first_record= join_read_first;
/* Read with index_first / index_next */
tab->type= tab->type == JT_ALL ? JT_NEXT : JT_HASH_NEXT;
@@ -16191,6 +16204,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
group_buff +
MY_TEST(maybe_null),
+ key_part_info->length,
field->null_ptr,
field->null_bit)))
goto err; /* purecov: inspected */
@@ -18702,7 +18716,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
records are read. Because of optimization in some cases it can
provide only select_limit_cnt+1 records.
*/
- if (join->order && join->sortorder &&
+ if (join->order && join->filesort_found_rows &&
join->select_options & OPTION_FOUND_ROWS)
{
DBUG_PRINT("info", ("filesort NESTED_LOOP_QUERY_LIMIT"));
@@ -18724,8 +18738,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
/* Join over all rows in table; Return number of found rows */
TABLE *table=jt->table;
- if (table->sort.record_pointers ||
- (table->sort.io_cache && my_b_inited(table->sort.io_cache)))
+ join->select_options ^= OPTION_FOUND_ROWS;
+ if (join->filesort_found_rows)
{
/* Using filesort */
join->send_records= table->sort.found_records;
@@ -20556,7 +20570,11 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
select, filesort_limit, 0,
&examined_rows, &found_rows);
table->sort.found_records= filesort_retval;
- tab->records= found_rows; // For SQL_CALC_ROWS
+ if (found_rows != HA_POS_ERROR)
+ {
+ tab->records= found_rows; // For SQL_CALC_ROWS
+ join->filesort_found_rows= true;
+ }
if (quick_created)
{
@@ -21094,7 +21112,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item *view_ref= NULL;
/*
If we have found field not by its alias in select list but by its
- original field name, we should additionaly check if we have conflict
+ original field name, we should additionally check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
@@ -22117,7 +22135,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
We are replacing the argument of Item_func_set_user_var after its value
has been read. The argument's null_value should be set by now, so we
must set it explicitly for the replacement argument since the null_value
- may be read without any preceeding call to val_*().
+ may be read without any preceding call to val_*().
*/
new_field->update_null_value();
List<Item> list;
@@ -24905,7 +24923,8 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
switch (test_if_order_by_key(order, table, select->quick->index,
&used_key_parts)) {
case 1: // desired order
- *need_sort= FALSE;
+ *need_sort= FALSE;
+ *scanned_limit= MY_MIN(limit, select->quick->records);
return select->quick->index;
case 0: // unacceptable order
*need_sort= TRUE;
@@ -24918,7 +24937,7 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
{
select->set_quick(reverse_quick);
*need_sort= FALSE;
- *scanned_limit= select->quick->records;
+ *scanned_limit= MY_MIN(limit, select->quick->records);
return select->quick->index;
}
else
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 271199e3d51..dc86825e8e9 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1119,6 +1119,12 @@ public:
restore_no_rows_in_result() in ::reinit()
*/
bool no_rows_in_result_called;
+
+ /**
+ This is set if SQL_CALC_ROWS was calculated by filesort()
+ and should be taken from the appropriate JOIN_TAB
+ */
+ bool filesort_found_rows;
/**
Copy of this JOIN to be used with temporary tables.
@@ -1335,6 +1341,7 @@ public:
emb_sjm_nest= NULL;
sjm_lookup_tables= 0;
+ filesort_found_rows= false;
exec_saved_explain= false;
/*
The following is needed because JOIN::cleanup(true) may be called for
@@ -1541,21 +1548,8 @@ public:
store_key(THD *thd, Field *field_arg, uchar *ptr, uchar *null, uint length)
:null_key(0), null_ptr(null), err(0)
{
- if (field_arg->type() == MYSQL_TYPE_BLOB
- || field_arg->type() == MYSQL_TYPE_GEOMETRY)
- {
- /*
- Key segments are always packed with a 2 byte length prefix.
- See mi_rkey for details.
- */
- to_field= new Field_varstring(ptr, length, 2, null, 1,
- Field::NONE, field_arg->field_name,
- field_arg->table->s, field_arg->charset());
- to_field->init(field_arg->table);
- }
- else
- to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
- ptr, null, 1);
+ to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
+ ptr, length, null, 1);
}
store_key(store_key &arg)
:Sql_alloc(), null_key(arg.null_key), to_field(arg.to_field),
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 205697e4466..026b767d5a3 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, SkySQL Ab.
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
@@ -125,12 +125,41 @@ append_algorithm(TABLE_LIST *table, String *buff);
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
+/**
+ Condition pushdown used for INFORMATION_SCHEMA / SHOW queries.
+ This structure is to implement an optimization when
+ accessing data dictionary data in the INFORMATION_SCHEMA
+ or SHOW commands.
+ When the query contain a TABLE_SCHEMA or TABLE_NAME clause,
+ narrow the search for data based on the constraints given.
+*/
typedef struct st_lookup_field_values
{
- LEX_STRING db_value, table_value;
- bool wild_db_value, wild_table_value;
+ /**
+ Value of a TABLE_SCHEMA clause.
+ Note that this value length may exceed @c NAME_LEN.
+ @sa wild_db_value
+ */
+ LEX_STRING db_value;
+ /**
+ Value of a TABLE_NAME clause.
+ Note that this value length may exceed @c NAME_LEN.
+ @sa wild_table_value
+ */
+ LEX_STRING table_value;
+ /**
+ True when @c db_value is a LIKE clause,
+ false when @c db_value is an '=' clause.
+ */
+ bool wild_db_value;
+ /**
+ True when @c table_value is a LIKE clause,
+ false when @c table_value is an '=' clause.
+ */
+ bool wild_table_value;
} LOOKUP_FIELD_VALUES;
+
bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *);
/***************************************************************************
@@ -3901,14 +3930,22 @@ int make_db_list(THD *thd, Dynamic_array<LEX_STRING*> *files,
/*
- If we have db lookup vaule we just add it to list and
+ If we have db lookup value we just add it to list and
exit from the function.
We don't do this for database names longer than the maximum
- path length.
+ name length.
*/
- if (lookup_field_vals->db_value.str &&
- lookup_field_vals->db_value.length < FN_REFLEN)
+ if (lookup_field_vals->db_value.str)
{
+ if (lookup_field_vals->db_value.length > NAME_LEN)
+ {
+ /*
+ Impossible value for a database name,
+ found in a WHERE DATABASE_NAME = 'xxx' clause.
+ */
+ return 0;
+ }
+
if (is_infoschema_db(lookup_field_vals->db_value.str,
lookup_field_vals->db_value.length))
{
@@ -4041,6 +4078,14 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_STRING*> *table_names,
if (!lookup_field_vals->wild_table_value &&
lookup_field_vals->table_value.str)
{
+ if (lookup_field_vals->table_value.length > NAME_LEN)
+ {
+ /*
+ Impossible value for a table name,
+ found in a WHERE TABLE_NAME = 'xxx' clause.
+ */
+ return 0;
+ }
if (db_name == &INFORMATION_SCHEMA_NAME)
{
LEX_STRING *name;
@@ -4485,6 +4530,9 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
bzero((char*) &table_list, sizeof(TABLE_LIST));
bzero((char*) &tbl, sizeof(TABLE));
+ DBUG_ASSERT(db_name->length <= NAME_LEN);
+ DBUG_ASSERT(table_name->length <= NAME_LEN);
+
if (lower_case_table_names)
{
/*
@@ -4792,6 +4840,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
for (size_t i=0; i < db_names.elements(); i++)
{
LEX_STRING *db_name= db_names.at(i);
+ DBUG_ASSERT(db_name->length <= NAME_LEN);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!(check_access(thd, SELECT_ACL, db_name->str,
&thd->col_access, NULL, 0, 1) ||
@@ -4811,6 +4860,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
for (size_t i=0; i < table_names.elements(); i++)
{
LEX_STRING *table_name= table_names.at(i);
+ DBUG_ASSERT(table_name->length <= NAME_LEN);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!(thd->col_access & TABLE_ACLS))
@@ -4950,6 +5000,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
for (size_t i=0; i < db_names.elements(); i++)
{
LEX_STRING *db_name= db_names.at(i);
+ DBUG_ASSERT(db_name->length <= NAME_LEN);
if (db_name == &INFORMATION_SCHEMA_NAME)
{
if (store_schema_shemata(thd, table, db_name,
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index bcc811e426d..f8348cfb30e 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -231,6 +231,42 @@ bool String::needs_conversion(uint32 arg_length,
/*
+ Checks that the source string can just be copied to the destination string
+ without conversion.
+ Unlike needs_conversion it will require conversion on incoming binary data
+ to ensure the data are verified for vailidity first.
+
+ @param arg_length Length of string to copy.
+ @param from_cs Character set to copy from
+ @param to_cs Character set to copy to
+
+ @return conversion needed
+*/
+bool String::needs_conversion_on_storage(uint32 arg_length,
+ CHARSET_INFO *cs_from,
+ CHARSET_INFO *cs_to)
+{
+ uint32 offset;
+ return (needs_conversion(arg_length, cs_from, cs_to, &offset) ||
+ /* force conversion when storing a binary string */
+ (cs_from == &my_charset_bin &&
+ /* into a non-binary destination */
+ cs_to != &my_charset_bin &&
+ /* and any of the following is true :*/
+ (
+ /* it's a variable length encoding */
+ cs_to->mbminlen != cs_to->mbmaxlen ||
+ /* longer than 2 bytes : neither 1 byte nor ucs2 */
+ cs_to->mbminlen > 2 ||
+ /* and is not a multiple of the char byte size */
+ 0 != (arg_length % cs_to->mbmaxlen)
+ )
+ )
+ );
+}
+
+
+/*
Copy a multi-byte character sets with adding leading zeros.
SYNOPSIS
diff --git a/sql/sql_string.h b/sql/sql_string.h
index bc9e7f11bd6..95c82518f9e 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -343,6 +343,9 @@ public:
static bool needs_conversion(uint32 arg_length,
CHARSET_INFO *cs_from, CHARSET_INFO *cs_to,
uint32 *offset);
+ static bool needs_conversion_on_storage(uint32 arg_length,
+ CHARSET_INFO *cs_from,
+ CHARSET_INFO *cs_to);
bool copy_aligned(const char *s, uint32 arg_length, uint32 offset,
CHARSET_INFO *cs);
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index d9702472221..a8e17cf3276 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -5728,21 +5728,35 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
{
if (my_strcasecmp(system_charset_info,
sql_field->field_name, (*f_ptr)->field_name) == 0)
+ goto drop_create_field;
+ }
+ {
+ /*
+ If in the ADD list there is a field with the same name,
+ remove the sql_field from the list.
+ */
+ List_iterator<Create_field> chk_it(alter_info->create_list);
+ Create_field *chk_field;
+ while ((chk_field= chk_it++) && chk_field != sql_field)
{
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME),
- sql_field->field_name);
- it.remove();
- if (alter_info->create_list.is_empty())
- {
- alter_info->flags&= ~Alter_info::ALTER_ADD_COLUMN;
- if (alter_info->key_list.is_empty())
- alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
- Alter_info::ADD_FOREIGN_KEY);
- }
- break;
+ if (my_strcasecmp(system_charset_info,
+ sql_field->field_name, chk_field->field_name) == 0)
+ goto drop_create_field;
}
}
+ continue;
+drop_create_field:
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME),
+ sql_field->field_name);
+ it.remove();
+ if (alter_info->create_list.is_empty())
+ {
+ alter_info->flags&= ~Alter_info::ALTER_ADD_COLUMN;
+ if (alter_info->key_list.is_empty())
+ alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
+ Alter_info::ADD_FOREIGN_KEY);
+ }
}
}
@@ -5842,6 +5856,26 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
}
}
}
+
+ if (!remove_drop)
+ {
+ /*
+ Check if the name appears twice in the DROP list.
+ */
+ List_iterator<Alter_drop> chk_it(alter_info->drop_list);
+ Alter_drop *chk_drop;
+ while ((chk_drop= chk_it++) && chk_drop != drop)
+ {
+ if (drop->type == chk_drop->type &&
+ my_strcasecmp(system_charset_info,
+ drop->name, chk_drop->name) == 0)
+ {
+ remove_drop= TRUE;
+ break;
+ }
+ }
+ }
+
if (remove_drop)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
@@ -5862,7 +5896,6 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
Key *key;
List_iterator<Key> key_it(alter_info->key_list);
uint n_key;
- bool remove_key;
const char *keyname;
while ((key=key_it++))
{
@@ -5879,7 +5912,6 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
if (keyname == NULL)
continue;
}
- remove_key= FALSE;
if (key->type != Key::FOREIGN_KEY)
{
for (n_key=0; n_key < table->s->keys; n_key++)
@@ -5887,8 +5919,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
if (my_strcasecmp(system_charset_info,
keyname, table->key_info[n_key].name) == 0)
{
- remove_key= TRUE;
- break;
+ goto remove_key;
}
}
}
@@ -5902,25 +5933,44 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
{
if (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
key->name.str) == 0)
- remove_key= TRUE;
- break;
+ goto remove_key;
}
}
- if (remove_key)
+
{
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), keyname);
- key_it.remove();
- if (key->type == Key::FOREIGN_KEY)
+ Key *chk_key;
+ List_iterator<Key> chk_it(alter_info->key_list);
+ const char *chkname;
+ while ((chk_key=chk_it++) && chk_key != key)
{
- /* ADD FOREIGN KEY appends two items. */
- key_it.remove();
+ if ((chkname= chk_key->name.str) == NULL)
+ {
+ List_iterator<Key_part_spec> part_it(chk_key->columns);
+ Key_part_spec *kp;
+ if ((kp= part_it++))
+ chkname= kp->field_name.str;
+ if (keyname == NULL)
+ continue;
+ }
+ if (key->type == chk_key->type &&
+ my_strcasecmp(system_charset_info, keyname, chkname) == 0)
+ goto remove_key;
}
- if (alter_info->key_list.is_empty())
- alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
- Alter_info::ADD_FOREIGN_KEY);
- break;
}
+ continue;
+
+remove_key:
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), keyname);
+ key_it.remove();
+ if (key->type == Key::FOREIGN_KEY)
+ {
+ /* ADD FOREIGN KEY appends two items. */
+ key_it.remove();
+ }
+ if (alter_info->key_list.is_empty())
+ alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
+ Alter_info::ADD_FOREIGN_KEY);
}
}
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index c8a2c2daf85..cc824298bc5 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -358,20 +358,30 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part,
int was_cut;
longlong res;
enum_field_types f_type;
+ bool have_warnings;
if (fuzzydate & TIME_TIME_ONLY)
{
fuzzydate= TIME_TIME_ONLY; // clear other flags
f_type= MYSQL_TYPE_TIME;
res= number_to_time(neg, nr, sec_part, ltime, &was_cut);
+ have_warnings= MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut);
}
else
{
f_type= MYSQL_TYPE_DATETIME;
- res= neg ? -1 : number_to_datetime(nr, sec_part, ltime, fuzzydate, &was_cut);
+ if (neg)
+ {
+ res= -1;
+ }
+ else
+ {
+ res= number_to_datetime(nr, sec_part, ltime, fuzzydate, &was_cut);
+ have_warnings= was_cut && (fuzzydate & TIME_NO_ZERO_IN_DATE);
+ }
}
- if (res < 0 || (was_cut && (fuzzydate & TIME_NO_ZERO_IN_DATE)))
+ if (res < 0 || have_warnings)
{
make_truncated_value_warning(current_thd,
Sql_condition::WARN_LEVEL_WARN, str,
@@ -414,12 +424,11 @@ bool decimal_to_datetime_with_warn(const my_decimal *value, MYSQL_TIME *ltime,
}
-bool int_to_datetime_with_warn(longlong value, MYSQL_TIME *ltime,
+bool int_to_datetime_with_warn(bool neg, ulonglong value, MYSQL_TIME *ltime,
ulonglong fuzzydate, const char *field_name)
{
- const ErrConvInteger str(value);
- bool neg= value < 0;
- return number_to_time_with_warn(neg, neg ? -value : value, 0, ltime,
+ const ErrConvInteger str(neg ? -value : value, !neg);
+ return number_to_time_with_warn(neg, value, 0, ltime,
fuzzydate, &str, field_name);
}
@@ -1250,8 +1259,7 @@ mix_date_and_time(MYSQL_TIME *to, const MYSQL_TIME *from)
/**
Get current date in DATE format
*/
-static void
-set_current_date(THD *thd, MYSQL_TIME *to)
+void set_current_date(THD *thd, MYSQL_TIME *to)
{
thd->variables.time_zone->gmt_sec_to_TIME(to, thd->query_start());
thd->time_zone_used= 1;
diff --git a/sql/sql_time.h b/sql/sql_time.h
index 5a468ef0649..dc8e4668e1e 100644
--- a/sql/sql_time.h
+++ b/sql/sql_time.h
@@ -33,6 +33,7 @@ typedef struct st_known_date_time_format KNOWN_DATE_TIME_FORMAT;
ulong convert_period_to_month(ulong period);
ulong convert_month_to_period(ulong month);
+void set_current_date(THD *thd, MYSQL_TIME *to);
bool time_to_datetime(MYSQL_TIME *ltime);
void time_to_daytime_interval(MYSQL_TIME *l_time);
bool get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
@@ -46,7 +47,7 @@ bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
bool decimal_to_datetime_with_warn(const my_decimal *value, MYSQL_TIME *ltime,
ulonglong fuzzydate,
const char *name);
-bool int_to_datetime_with_warn(longlong value, MYSQL_TIME *ltime,
+bool int_to_datetime_with_warn(bool neg, ulonglong value, MYSQL_TIME *ltime,
ulonglong fuzzydate,
const char *name);
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index c7981ae36d5..e8286707563 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2013, 2014, SkySQL Ab.
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
@@ -184,12 +185,19 @@ fk_truncate_illegal_if_parent(THD *thd, TABLE *table)
@param table_ref Table list element for the table to be truncated.
@param is_tmp_table True if element refers to a temp table.
- @retval 0 Success.
- @retval > 0 Error code.
+ @retval TRUNCATE_OK Truncate was successful and statement can be safely
+ binlogged.
+ @retval TRUNCATE_FAILED_BUT_BINLOG Truncate failed but still go ahead with
+ binlogging as in case of non transactional tables
+ partial truncation is possible.
+
+ @retval TRUNCATE_FAILED_SKIP_BINLOG Truncate was not successful hence donot
+ binlong the statement.
*/
-int Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
- bool is_tmp_table)
+enum Sql_cmd_truncate_table::truncate_result
+Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
+ bool is_tmp_table)
{
int error= 0;
uint flags= 0;
@@ -229,16 +237,30 @@ int Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
/* Open the table as it will handle some required preparations. */
if (open_and_lock_tables(thd, table_ref, FALSE, flags))
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
/* Whether to truncate regardless of foreign keys. */
if (! (thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS))
- error= fk_truncate_illegal_if_parent(thd, table_ref->table);
+ if (fk_truncate_illegal_if_parent(thd, table_ref->table))
+ DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
- if (!error && (error= table_ref->table->file->ha_truncate()))
+ error= table_ref->table->file->ha_truncate();
+ if (error)
+ {
table_ref->table->file->print_error(error, MYF(0));
-
- DBUG_RETURN(error);
+ /*
+ If truncate method is not implemented then we don't binlog the
+ statement. If truncation has failed in a transactional engine then also we
+ donot binlog the statment. Only in non transactional engine we binlog
+ inspite of errors.
+ */
+ if (error == HA_ERR_WRONG_COMMAND ||
+ table_ref->table->file->has_transactions())
+ DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
+ else
+ DBUG_RETURN(TRUNCATE_FAILED_BUT_BINLOG);
+ }
+ DBUG_RETURN(TRUNCATE_OK);
}
@@ -491,10 +513,14 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
/*
All effects of a TRUNCATE TABLE operation are committed even if
- truncation fails. Thus, the query must be written to the binary
- log. The only exception is a unimplemented truncate method.
+ truncation fails in the case of non transactional tables. Thus, the
+ query must be written to the binary log. The only exception is a
+ unimplemented truncate method.
*/
- binlog_stmt= !error || error != HA_ERR_WRONG_COMMAND;
+ if (error == TRUNCATE_OK || error == TRUNCATE_FAILED_BUT_BINLOG)
+ binlog_stmt= true;
+ else
+ binlog_stmt= false;
}
/*
diff --git a/sql/sql_truncate.h b/sql/sql_truncate.h
index 061c561b8ea..b8525fd6abb 100644
--- a/sql/sql_truncate.h
+++ b/sql/sql_truncate.h
@@ -1,6 +1,6 @@
#ifndef SQL_TRUNCATE_INCLUDED
#define SQL_TRUNCATE_INCLUDED
-/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,11 +50,17 @@ public:
}
protected:
+ enum truncate_result{
+ TRUNCATE_OK=0,
+ TRUNCATE_FAILED_BUT_BINLOG,
+ TRUNCATE_FAILED_SKIP_BINLOG
+ };
+
/** Handle locking a base table for truncate. */
bool lock_table(THD *, TABLE_LIST *, bool *);
/** Truncate table via the handler method. */
- int handler_truncate(THD *, TABLE_LIST *, bool);
+ enum truncate_result handler_truncate(THD *, TABLE_LIST *, bool);
/**
Optimized delete of all rows by doing a full regenerate of the table.
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index f3a1ec18aaf..f437bef15dd 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1070,6 +1070,13 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
thd->lex->allow_sum_func= 0;
+ /*
+ We do not call DT_MERGE_FOR_INSERT because it has no sense for simple
+ (not multi-) update
+ */
+ if (mysql_handle_derived(thd->lex, DT_PREPARE))
+ DBUG_RETURN(TRUE);
+
if (setup_tables_and_check_access(thd, &select_lex->context,
&select_lex->top_join_list,
table_list,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 9ea72676b13..d6b3fa41c78 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -14535,7 +14535,7 @@ opt_var_ident_type:
| SESSION_SYM '.' { $$=OPT_SESSION; }
;
-// Option values with preceeding option_type.
+// Option values with preceding option_type.
option_value_following_option_type:
internal_variable_name equal set_expr_or_default
{
@@ -14551,7 +14551,7 @@ option_value_following_option_type:
{
/*
Not in trigger assigning value to new row,
- and option_type preceeding local variable is illegal.
+ and option_type preceding local variable is illegal.
*/
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
@@ -14559,7 +14559,7 @@ option_value_following_option_type:
}
;
-// Option values without preceeding option_type.
+// Option values without preceding option_type.
option_value_no_option_type:
internal_variable_name equal set_expr_or_default
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index d9b43f4d5b6..d5939473cf2 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -77,7 +77,7 @@ static Sys_var_mybool Sys_pfs_enabled(
"performance_schema",
"Enable the performance schema.",
PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_enabled),
- CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
static Sys_var_long Sys_pfs_events_waits_history_long_size(
"performance_schema_events_waits_history_long_size",
@@ -4929,7 +4929,7 @@ static Sys_var_mybool Sys_binlog_annotate_row_events(
#ifdef HAVE_REPLICATION
static Sys_var_mybool Sys_replicate_annotate_row_events(
"replicate_annotate_row_events",
- "Tells the slave to write annotate rows events recieved from the master "
+ "Tells the slave to write annotate rows events received from the master "
"to its own binary log. Ignored if log_slave_updates is not set",
READ_ONLY GLOBAL_VAR(opt_replicate_annotate_row_events),
CMD_LINE(OPT_ARG), DEFAULT(0));
diff --git a/sql/table.cc b/sql/table.cc
index 44320a4d644..6b3e0bcc4b7 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5054,6 +5054,10 @@ void TABLE_LIST::set_check_merged()
void TABLE_LIST::set_check_materialized()
{
+ DBUG_ENTER("TABLE_LIST::set_check_materialized");
+ SELECT_LEX_UNIT *derived= this->derived;
+ if (view)
+ derived= &view->unit;
DBUG_ASSERT(derived);
if (!derived->first_select()->exclude_from_table_unique_test)
derived->set_unique_exclude();
@@ -5066,6 +5070,7 @@ void TABLE_LIST::set_check_materialized()
derived->first_select()->first_inner_unit()->first_select()->
exclude_from_table_unique_test);
}
+ DBUG_VOID_RETURN;
}
TABLE *TABLE_LIST::get_real_join_table()
diff --git a/sql/table.h b/sql/table.h
index 86e03cdaaf5..3ac75ec06e1 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2190,7 +2190,7 @@ struct TABLE_LIST
void set_materialized_derived()
{
DBUG_ENTER("set_materialized_derived");
- derived_type= ((derived_type & DTYPE_MASK) |
+ derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) |
DTYPE_TABLE | DTYPE_MATERIALIZE);
set_check_materialized();
DBUG_VOID_RETURN;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 82f26ca4da4..2a5a5d1681b 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2033,7 +2033,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
/*
At last we are doing the same thing for records in
- mysql.time_zone_transition table. Here we additionaly need records
+ mysql.time_zone_transition table. Here we additionally need records
in ascending order by index scan also satisfies us.
*/
table= tz_tables->table;
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 3625df73c4f..6c308e7eef1 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2004, 2012, Oracle and/or its affiliates
- Copyright (c) 2010, 2013 Monty Program Ab.
+ Copyright (c) 2004, 2014, Oracle and/or its affiliates
+ Copyright (c) 2010, 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h
index e1d4fc7e948..a340ee4450a 100644
--- a/storage/connect/colblk.h
+++ b/storage/connect/colblk.h
@@ -55,6 +55,7 @@ class DllExport COLBLK : public XOBJECT {
PSZ GetFmt(void) {return (Cdp) ? Cdp->Fmt : NULL;}
bool IsUnsigned(void) {return Unsigned;}
bool IsNullable(void) {return Nullable;}
+ bool IsVirtual(void) {return Cdp->IsVirtual();}
void SetNullable(bool b) {Nullable = b;}
// Methods
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 32997f53068..2d8aeb8b5f4 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -191,7 +191,7 @@ PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
PTDB tdbp;
PTABLE tabp;
PDBUSER dup= PlgGetUser(g);
- PCATLG cat= (dup) ? dup->Catalog : NULL; // Safe over longjmp
+ volatile PCATLG cat= (dup) ? dup->Catalog : NULL; // Safe over longjmp
if (trace)
printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);
diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp
index f8a4e7d2f2b..1723ee4ac27 100644
--- a/storage/connect/filamap.cpp
+++ b/storage/connect/filamap.cpp
@@ -382,7 +382,7 @@ int MAPFAM::DeleteRecords(PGLOBAL g, int irc)
if (Tpos == Spos)
/*******************************************************************/
- /* First line to delete. Move of eventual preceeding lines is */
+ /* First line to delete. Move of eventual preceding lines is */
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
Tpos = Fpos; // Spos is set below
diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp
index 7ac81117f35..7ca98eeff55 100644
--- a/storage/connect/filamdbf.cpp
+++ b/storage/connect/filamdbf.cpp
@@ -546,10 +546,11 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
PDOSDEF tdp = (PDOSDEF)Tdbp->GetDef();
// Count the number of columns
- for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) {
- reclen += cdp->GetLong();
- n++;
- } // endfor cdp
+ for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
+ if (!(cdp->Flags & U_SPECIAL)) {
+ reclen += cdp->GetLong();
+ n++;
+ } // endif Flags
if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
@@ -570,30 +571,31 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
descp = (DESCRIPTOR*)header;
// Currently only standard Xbase types are supported
- for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) {
- descp++;
-
- switch ((c = *GetFormatType(cdp->GetType()))) {
- case 'S': // Short integer
- case 'L': // Large (big) integer
- case 'T': // Tiny integer
- c = 'N'; // Numeric
- case 'N': // Numeric (integer)
- case 'F': // Float (double)
- descp->Decimals = (uchar)cdp->F.Prec;
- case 'C': // Char
- case 'D': // Date
- break;
- default: // Should never happen
- sprintf(g->Message, "Unsupported DBF type %c for column %s",
- c, cdp->GetName());
- return true;
- } // endswitch c
-
- strncpy(descp->Name, cdp->GetName(), 11);
- descp->Type = c;
- descp->Length = (uchar)cdp->GetLong();
- } // endfor cdp
+ for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
+ if (!(cdp->Flags & U_SPECIAL)) {
+ descp++;
+
+ switch ((c = *GetFormatType(cdp->GetType()))) {
+ case 'S': // Short integer
+ case 'L': // Large (big) integer
+ case 'T': // Tiny integer
+ c = 'N'; // Numeric
+ case 'N': // Numeric (integer)
+ case 'F': // Float (double)
+ descp->Decimals = (uchar)cdp->F.Prec;
+ case 'C': // Char
+ case 'D': // Date
+ break;
+ default: // Should never happen
+ sprintf(g->Message, "Unsupported DBF type %c for column %s",
+ c, cdp->GetName());
+ return true;
+ } // endswitch c
+
+ strncpy(descp->Name, cdp->GetName(), 11);
+ descp->Type = c;
+ descp->Length = (uchar)cdp->GetLong();
+ } // endif Flags
*(char*)(++descp) = EOH;
diff --git a/storage/connect/filamfix.cpp b/storage/connect/filamfix.cpp
index a64d7bdc04d..9338ae322db 100644
--- a/storage/connect/filamfix.cpp
+++ b/storage/connect/filamfix.cpp
@@ -367,7 +367,7 @@ int FIXFAM::DeleteRecords(PGLOBAL g, int irc)
} else {
/*****************************************************************/
- /* Move of eventual preceeding lines is not required here. */
+ /* Move of eventual preceding lines is not required here. */
/* Set the target file as being the source file itself. */
/* Set the future Tpos, and give Spos a value to block moving. */
/*****************************************************************/
@@ -1165,7 +1165,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
if (Tpos == Spos) {
/*******************************************************************/
- /* First line to delete. Move of eventual preceeding lines is */
+ /* First line to delete. Move of eventual preceding lines is */
/* not required here if a temporary file is not used, just the */
/* setting of future Spos and Tpos. */
/*******************************************************************/
@@ -1178,7 +1178,7 @@ int BGXFAM::DeleteRecords(PGLOBAL g, int irc)
} else {
/*****************************************************************/
- /* Move of eventual preceeding lines is not required here. */
+ /* Move of eventual preceding lines is not required here. */
/* Set the target file as being the source file itself. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
diff --git a/storage/connect/filamtxt.cpp b/storage/connect/filamtxt.cpp
index ecd255afd2e..e4e9130dc86 100644
--- a/storage/connect/filamtxt.cpp
+++ b/storage/connect/filamtxt.cpp
@@ -714,7 +714,7 @@ int DOSFAM::DeleteRecords(PGLOBAL g, int irc)
} else {
/*****************************************************************/
- /* Move of eventual preceeding lines is not required here. */
+ /* Move of eventual preceding lines is not required here. */
/* Set the target file as being the source file itself. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index 97eb4c7c8b4..edadc25b50b 100755
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -712,7 +712,7 @@ int VCTFAM::DeleteRecords(PGLOBAL g, int irc)
} else {
/*****************************************************************/
- /* First line to delete. Move of eventual preceeding lines is */
+ /* First line to delete. Move of eventual preceding lines is */
/* not required here, just the setting of future Spos and Tpos. */
/*****************************************************************/
T_Stream = Stream;
@@ -1459,7 +1459,7 @@ bool VCMFAM::AllocateBuffer(PGLOBAL g)
bool VCMFAM::InitInsert(PGLOBAL g)
{
int rc;
- PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
+ volatile PVCTCOL cp = (PVCTCOL)Tdbp->GetColumns();
// We come here in MODE_INSERT only
if (Last == Nrec) {
@@ -1558,7 +1558,7 @@ int VCMFAM::DeleteRecords(PGLOBAL g, int irc)
if (Tpos == Spos)
/*******************************************************************/
- /* First line to delete. Move of eventual preceeding lines is */
+ /* First line to delete. Move of eventual preceding lines is */
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
Tpos = Fpos; // Spos is set below
@@ -2153,7 +2153,7 @@ int VECFAM::DeleteRecords(PGLOBAL g, int irc)
} else
/*****************************************************************/
- /* Move of eventual preceeding lines is not required here. */
+ /* Move of eventual preceding lines is not required here. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
Spos = Tpos = Fpos;
@@ -2834,7 +2834,7 @@ int VMPFAM::DeleteRecords(PGLOBAL g, int irc)
if (Tpos == Spos)
/*******************************************************************/
- /* First line to delete. Move of eventual preceeding lines is */
+ /* First line to delete. Move of eventual preceding lines is */
/* not required here, just setting of future Spos and Tpos. */
/*******************************************************************/
Tpos = Fpos; // Spos is set below
@@ -3756,7 +3756,7 @@ int BGVFAM::DeleteRecords(PGLOBAL g, int irc)
} else {
/*****************************************************************/
- /* Move of eventual preceeding lines is not required here. */
+ /* Move of eventual preceding lines is not required here. */
/* Set the target file as being the source file itself. */
/* Set the future Tpos, and give Spos a value to block copying. */
/*****************************************************************/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 974906d6ed5..ff15b27ca50 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -1058,6 +1058,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
break;
case TYPE_DECIM:
pcf->Precision= ((Field_new_decimal*)fp)->precision;
+ pcf->Length= pcf->Precision;
pcf->Scale= fp->decimals();
break;
case TYPE_DATE:
@@ -2708,7 +2709,6 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen)
*/
int ha_connect::rnd_init(bool scan)
{
- int rc;
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
(xp) ? xp->g : NULL);
DBUG_ENTER("ha_connect::rnd_init");
@@ -2742,8 +2742,8 @@ int ha_connect::rnd_init(bool scan)
if (xmod == MODE_UPDATE)
bitmap_union(table->read_set, table->write_set);
- if ((rc= OpenTable(g, xmod == MODE_DELETE)))
- DBUG_RETURN(rc);
+ if (OpenTable(g, xmod == MODE_DELETE))
+ DBUG_RETURN(HA_ERR_INITIALIZATION);
xp->nrd= xp->fnd= xp->nfd= 0;
xp->tb1= my_interval_timer();
@@ -4239,7 +4239,6 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
strncpy(dsn, create_info->connect_string.str, len);
dsn[len]= 0;
mydef->SetName(create_info->alias);
- mydef->SetCat(cat);
if (!mydef->ParseURL(g, dsn, false)) {
if (mydef->GetHostname())
@@ -4696,21 +4695,18 @@ int ha_connect::create(const char *name, TABLE *table_arg,
int port;
host= GetListOption(g, "host", options->oplist, NULL);
- db= GetListOption(g, "database", options->oplist, NULL);
+ db= GetStringOption("database", NULL);
port= atoi(GetListOption(g, "port", options->oplist, "0"));
if (create_info->connect_string.str) {
char *dsn;
int len= create_info->connect_string.length;
PMYDEF mydef= new(g) MYSQLDEF();
- PDBUSER dup= PlgGetUser(g);
- PCATLG cat= (dup) ? dup->Catalog : NULL;
dsn= (char*)PlugSubAlloc(g, NULL, len + 1);
strncpy(dsn, create_info->connect_string.str, len);
dsn[len]= 0;
mydef->SetName(create_info->alias);
- mydef->SetCat(cat);
if (!mydef->ParseURL(g, dsn, false)) {
if (mydef->GetHostname())
diff --git a/storage/connect/mysql-test/connect/r/csv.result b/storage/connect/mysql-test/connect/r/csv.result
index 3f424964881..be25a842bc4 100644
--- a/storage/connect/mysql-test/connect/r/csv.result
+++ b/storage/connect/mysql-test/connect/r/csv.result
@@ -52,9 +52,9 @@ children SMALLINT(2) NOT NULL
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
ERROR HY000: Table 't1' is read only
UPDATE t1 SET children=6 WHERE name='BILL';
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
DELETE FROM t1 WHERE name='BILL';
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
SELECT * FROM t1;
diff --git a/storage/connect/mysql-test/connect/r/dbf.result b/storage/connect/mysql-test/connect/r/dbf.result
index 30fac687119..d7b3fe0f114 100644
--- a/storage/connect/mysql-test/connect/r/dbf.result
+++ b/storage/connect/mysql-test/connect/r/dbf.result
@@ -77,9 +77,9 @@ t1 CREATE TABLE `t1` (
INSERT INTO t1 VALUES (30);
ERROR HY000: Table 't1' is read only
UPDATE t1 SET a=30 WHERE a=10;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
DELETE FROM t1 WHERE a=10;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=NO;
diff --git a/storage/connect/mysql-test/connect/r/fix.result b/storage/connect/mysql-test/connect/r/fix.result
index a93948bb9c6..4d620c66a04 100644
--- a/storage/connect/mysql-test/connect/r/fix.result
+++ b/storage/connect/mysql-test/connect/r/fix.result
@@ -30,9 +30,9 @@ t1 CREATE TABLE `t1` (
INSERT INTO t1 VALUES (20);
ERROR HY000: Table 't1' is read only
UPDATE t1 SET id=20 WHERE id=10;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
DELETE FROM t1 WHERE id=10;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=0;
diff --git a/storage/connect/mysql-test/connect/r/ini.result b/storage/connect/mysql-test/connect/r/ini.result
index 79996eb8525..a377cb3ee20 100644
--- a/storage/connect/mysql-test/connect/r/ini.result
+++ b/storage/connect/mysql-test/connect/r/ini.result
@@ -194,9 +194,9 @@ t1 CREATE TABLE `t1` (
INSERT INTO t1 VALUES ('US',40);
ERROR HY000: Table 't1' is read only
UPDATE t1 SET c2=20 WHERE c2=10;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
DELETE FROM t1 WHERE c2=10;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=0;
diff --git a/storage/connect/mysql-test/connect/r/vec.result b/storage/connect/mysql-test/connect/r/vec.result
index e93305fb07a..51fb8aeee77 100644
--- a/storage/connect/mysql-test/connect/r/vec.result
+++ b/storage/connect/mysql-test/connect/r/vec.result
@@ -103,9 +103,9 @@ t1 CREATE TABLE `t1` (
INSERT INTO t1 VALUES (4,'test04');
ERROR HY000: Table 't1' is read only
UPDATE t1 SET b='test04' WHERE a=3;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
DELETE FROM t1 WHERE a=3;
-ERROR HY000: Table 't1' is read only
+ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
TRUNCATE TABLE t1;
ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=no;
diff --git a/storage/connect/mysql-test/connect/t/csv.test b/storage/connect/mysql-test/connect/t/csv.test
index a21686d8a08..5662fdb705b 100644
--- a/storage/connect/mysql-test/connect/t/csv.test
+++ b/storage/connect/mysql-test/connect/t/csv.test
@@ -1,185 +1,185 @@
-let $MYSQLD_DATADIR= `select @@datadir`;
-
---copy_file $MTR_SUITE_DIR/std_data/people.csv $MYSQLD_DATADIR/test/people.csv
-
-SET NAMES utf8;
-
---echo #
---echo # Testing errors
---echo #
-CREATE TABLE t1
-(
- ID INT NOT NULL
-) Engine=CONNECT TABLE_TYPE=CSV FILE_NAME='nonexistent.txt';
---replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
-# TODO: check why this is needed for Windows
---replace_result Open(rt) Open(rb)
-SELECT * FROM t1;
-DROP TABLE t1;
-
---echo #
---echo # Testing examples from the manual
---echo #
-CREATE TABLE t1
-(
- name CHAR(12) NOT NULL,
- birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
- children SMALLINT(2) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
- HEADER=1 SEP_CHAR=';' QUOTED=1;
-SELECT * FROM t1;
-INSERT INTO t1 VALUES ('RONALD','1980-02-26',4);
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/people.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/people.csv'),'\r\n','\n');
-
---echo #
---echo # Testing READONLY tables
---echo #
-CREATE TABLE t1
-(
- name CHAR(12) NOT NULL,
- birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
- children SMALLINT(2) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
- HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
---error ER_OPEN_AS_READONLY
-INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
---error ER_OPEN_AS_READONLY
-UPDATE t1 SET children=6 WHERE name='BILL';
---error ER_OPEN_AS_READONLY
-DELETE FROM t1 WHERE name='BILL';
---error ER_OPEN_AS_READONLY
-TRUNCATE TABLE t1;
-SELECT * FROM t1;
-ALTER TABLE t1 READONLY=no;
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
-SELECT * FROM t1;
-ALTER TABLE t1 READONLY=1;
-SHOW CREATE TABLE t1;
---error ER_OPEN_AS_READONLY
-INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
-SELECT * FROM t1;
-DROP TABLE t1;
-
-
---echo #
---echo # Testing that the underlying file is created
---echo #
-CREATE TABLE t1
-(
- c1 CHAR(12) NOT NULL,
- c2 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='tmp.csv'
- HEADER=1 SEP_CHAR=',' QUOTED=1;
-INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/tmp.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.csv'),'\r\n','\n');
-
---echo #
---echo # Creating a CSV table from a MyISAM table
---echo #
-CREATE TABLE t1 (a VARCHAR(10) NOT NULL, b INT NOT NULL) ENGINE=MyISAM;
-INSERT INTO t1 VALUES ('test1',1), ('test2',2);
-CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t2.csv'
- AS SELECT * FROM t1;
-SELECT * FROM t2;
-DROP TABLE t2;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t2.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.csv'),'\r\n','\n');
---remove_file $MYSQLD_DATADIR/test/t2.csv
-
---echo #
---echo # Testing international data
---echo #
-CREATE TABLE t1
-(
- c1 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
- CHARSET=utf8;
-INSERT INTO t1 VALUES ('á');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
---remove_file $MYSQLD_DATADIR/test/t1.csv
-
-CREATE TABLE t1
-(
- c1 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
- CHARSET=utf8 DATA_CHARSET=latin1;
-INSERT INTO t1 VALUES ('á');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
---remove_file $MYSQLD_DATADIR/test/t1.csv
-
-CREATE TABLE t1
-(
- c1 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
-INSERT INTO t1 VALUES ('á');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
---remove_file $MYSQLD_DATADIR/test/t1.csv
-
-CREATE TABLE t1
-(
- c1 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
- CHARSET=latin1;
-INSERT INTO t1 VALUES ('á');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
---remove_file $MYSQLD_DATADIR/test/t1.csv
-
-CREATE TABLE t1
-(
- c1 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
- CHARSET=latin1 DATA_CHARSET=utf8;
-INSERT INTO t1 VALUES ('á');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
---remove_file $MYSQLD_DATADIR/test/t1.csv
-
-CREATE TABLE t1
-(
- c1 CHAR(12) CHARACTER SET latin1 NOT NULL,
- c2 CHAR(12) CHARACTER SET utf8 NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
-INSERT INTO t1 VALUES ('á','á');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.csv
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
---remove_file $MYSQLD_DATADIR/test/t1.csv
-
-
-#
-# Clean up
-#
---remove_file $MYSQLD_DATADIR/test/people.csv
---remove_file $MYSQLD_DATADIR/test/tmp.csv
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--copy_file $MTR_SUITE_DIR/std_data/people.csv $MYSQLD_DATADIR/test/people.csv
+
+SET NAMES utf8;
+
+--echo #
+--echo # Testing errors
+--echo #
+CREATE TABLE t1
+(
+ ID INT NOT NULL
+) Engine=CONNECT TABLE_TYPE=CSV FILE_NAME='nonexistent.txt';
+--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
+# TODO: check why this is needed for Windows
+--replace_result Open(rt) Open(rb)
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Testing examples from the manual
+--echo #
+CREATE TABLE t1
+(
+ name CHAR(12) NOT NULL,
+ birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
+ children SMALLINT(2) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
+ HEADER=1 SEP_CHAR=';' QUOTED=1;
+SELECT * FROM t1;
+INSERT INTO t1 VALUES ('RONALD','1980-02-26',4);
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/people.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/people.csv'),'\r\n','\n');
+
+--echo #
+--echo # Testing READONLY tables
+--echo #
+CREATE TABLE t1
+(
+ name CHAR(12) NOT NULL,
+ birth DATE NOT NULL DATE_FORMAT='DD/MM/YY',
+ children SMALLINT(2) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
+ HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
+--error ER_OPEN_AS_READONLY
+INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
+--error ER_GET_ERRMSG
+UPDATE t1 SET children=6 WHERE name='BILL';
+--error ER_GET_ERRMSG
+DELETE FROM t1 WHERE name='BILL';
+--error ER_OPEN_AS_READONLY
+TRUNCATE TABLE t1;
+SELECT * FROM t1;
+ALTER TABLE t1 READONLY=no;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
+SELECT * FROM t1;
+ALTER TABLE t1 READONLY=1;
+SHOW CREATE TABLE t1;
+--error ER_OPEN_AS_READONLY
+INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Testing that the underlying file is created
+--echo #
+CREATE TABLE t1
+(
+ c1 CHAR(12) NOT NULL,
+ c2 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='tmp.csv'
+ HEADER=1 SEP_CHAR=',' QUOTED=1;
+INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/tmp.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.csv'),'\r\n','\n');
+
+--echo #
+--echo # Creating a CSV table from a MyISAM table
+--echo #
+CREATE TABLE t1 (a VARCHAR(10) NOT NULL, b INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('test1',1), ('test2',2);
+CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t2.csv'
+ AS SELECT * FROM t1;
+SELECT * FROM t2;
+DROP TABLE t2;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t2.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.csv'),'\r\n','\n');
+--remove_file $MYSQLD_DATADIR/test/t2.csv
+
+--echo #
+--echo # Testing international data
+--echo #
+CREATE TABLE t1
+(
+ c1 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
+ CHARSET=utf8;
+INSERT INTO t1 VALUES ('á');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
+--remove_file $MYSQLD_DATADIR/test/t1.csv
+
+CREATE TABLE t1
+(
+ c1 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
+ CHARSET=utf8 DATA_CHARSET=latin1;
+INSERT INTO t1 VALUES ('á');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
+--remove_file $MYSQLD_DATADIR/test/t1.csv
+
+CREATE TABLE t1
+(
+ c1 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
+INSERT INTO t1 VALUES ('á');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
+--remove_file $MYSQLD_DATADIR/test/t1.csv
+
+CREATE TABLE t1
+(
+ c1 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
+ CHARSET=latin1;
+INSERT INTO t1 VALUES ('á');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
+--remove_file $MYSQLD_DATADIR/test/t1.csv
+
+CREATE TABLE t1
+(
+ c1 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv'
+ CHARSET=latin1 DATA_CHARSET=utf8;
+INSERT INTO t1 VALUES ('á');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
+--remove_file $MYSQLD_DATADIR/test/t1.csv
+
+CREATE TABLE t1
+(
+ c1 CHAR(12) CHARACTER SET latin1 NOT NULL,
+ c2 CHAR(12) CHARACTER SET utf8 NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.csv';
+INSERT INTO t1 VALUES ('á','á');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.csv
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT HEX(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.csv'),'\r\n','\n'));
+--remove_file $MYSQLD_DATADIR/test/t1.csv
+
+
+#
+# Clean up
+#
+--remove_file $MYSQLD_DATADIR/test/people.csv
+--remove_file $MYSQLD_DATADIR/test/tmp.csv
diff --git a/storage/connect/mysql-test/connect/t/dbf.test b/storage/connect/mysql-test/connect/t/dbf.test
index 467c608fe38..b798b1a2bc5 100644
--- a/storage/connect/mysql-test/connect/t/dbf.test
+++ b/storage/connect/mysql-test/connect/t/dbf.test
@@ -68,9 +68,9 @@ ALTER TABLE t1 READONLY=Yes;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (30);
---error ER_OPEN_AS_READONLY
+--error ER_GET_ERRMSG
UPDATE t1 SET a=30 WHERE a=10;
---error ER_OPEN_AS_READONLY
+--error ER_GET_ERRMSG
DELETE FROM t1 WHERE a=10;
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
diff --git a/storage/connect/mysql-test/connect/t/fix.test b/storage/connect/mysql-test/connect/t/fix.test
index 72eb274f7d6..f05abbb9b92 100644
--- a/storage/connect/mysql-test/connect/t/fix.test
+++ b/storage/connect/mysql-test/connect/t/fix.test
@@ -30,9 +30,9 @@ ALTER TABLE t1 READONLY=1;
SHOW CREATE TABLE t1;
--error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (20);
---error ER_OPEN_AS_READONLY
+--error ER_GET_ERRMSG
UPDATE t1 SET id=20 WHERE id=10;
---error ER_OPEN_AS_READONLY
+--error ER_GET_ERRMSG
DELETE FROM t1 WHERE id=10;
--error ER_OPEN_AS_READONLY
TRUNCATE TABLE t1;
diff --git a/storage/connect/mysql-test/connect/t/ini.test b/storage/connect/mysql-test/connect/t/ini.test
index dd3b84e4699..449b97204a6 100644
--- a/storage/connect/mysql-test/connect/t/ini.test
+++ b/storage/connect/mysql-test/connect/t/ini.test
@@ -1,156 +1,156 @@
-let $MYSQLD_DATADIR= `select @@datadir`;
-
---copy_file $MTR_SUITE_DIR/std_data/contact.ini $MYSQLD_DATADIR/test/contact.ini
-
---echo #
---echo # Testing errors
---echo #
-CREATE TABLE t1
-(
- ID INT
-) Engine=CONNECT TABLE_TYPE=INI FILE_NAME='nonexistent.txt';
---replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
-# TODO: check why this is needed for Windows
---replace_result Open(rt) Open(rb)
-SELECT * FROM t1;
-DROP TABLE t1;
-
---echo #
---echo # Testing examples from the manual
---echo #
-
-CREATE TABLE t1
-(
- contact CHAR(16) flag=1,
- name CHAR(20),
- forename CHAR(32),
- hired date date_format='DD/MM/YYYY',
- address CHAR(64),
- city CHAR(20),
- zipcode CHAR(8),
- tel CHAR(16)
-) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
-SELECT contact, name, hired, city, tel FROM t1;
-
-UPDATE t1 SET forename= 'Harry' where contact='UK1';
-SELECT * FROM t1 WHERE contact='UK1';
-INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
-SELECT * FROM t1 WHERE contact='UK1';
-INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
-SELECT * FROM t1 WHERE contact='UK2';
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/contact.ini
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
-
-CREATE TABLE t1
-(
- section CHAR(16) flag=1,
- keyname CHAR(16) flag=2,
- value CHAR(32)
-) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini'
- OPTION_LIST='Layout=Row';
-UPDATE t1 SET value='Paul' WHERE section='UK2' AND keyname='forename';
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/contact.ini
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
-
-
---echo #
---echo # Testing that the underlying file is created
---echo #
-CREATE TABLE t1
-(
- contact CHAR(12) NOT NULL flag=1,
- c2 CHAR(12) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='tmp.ini';
-INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
-SELECT * FROM t1;
-DROP TABLE t1;
---chmod 0777 $MYSQLD_DATADIR/test/tmp.ini
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.ini'),'\r\n','\n'),'\n\n','\n');
-
-
---echo #
---echo # Testing bad table
---echo #
-CREATE TABLE t1
-(
- id INT
-) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
---error ER_GET_ERRMSG
-INSERT INTO t1 VALUES (10);
-SELECT * FROM t1;
-DROP TABLE t1;
-
-
---echo #
---echo # Testing READONLY tables
---echo #
-CREATE TABLE t1
-(
- contact CHAR(10) flag=1,
- c2 CHAR(60)
-) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
-INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
-SELECT * FROM t1;
-ALTER TABLE t1 READONLY=1;
-SHOW CREATE TABLE t1;
---error ER_OPEN_AS_READONLY
-INSERT INTO t1 VALUES ('US',40);
---error ER_OPEN_AS_READONLY
-UPDATE t1 SET c2=20 WHERE c2=10;
---error ER_OPEN_AS_READONLY
-DELETE FROM t1 WHERE c2=10;
---error ER_OPEN_AS_READONLY
-TRUNCATE TABLE t1;
-ALTER TABLE t1 READONLY=0;
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES ('US',40);
-SELECT * FROM t1;
-DROP TABLE t1;
---remove_file $MYSQLD_DATADIR/test/t1.ini
-
-
-#
-# Clean up
-#
---remove_file $MYSQLD_DATADIR/test/contact.ini
---remove_file $MYSQLD_DATADIR/test/tmp.ini
-
-
---echo #
---echo # Bug: TABLE_TYPE=ini does not clear memory between CREATE TABLEs
---echo #
-CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
-ENGINE=CONNECT TABLE_TYPE=INI;
-INSERT INTO t1 VALUES ('sec1','val1'),('sec2','val2');
-SELECT sec AS s, val AS v FROM t1;
-DROP TABLE t1;
-CREATE TABLE t1 (sec2 CHAR(10) NOT NULL FLAG=1, val2 CHAR(10) NOT NULL)
-ENGINE=CONNECT TABLE_TYPE=INI;
-INSERT INTO t1 VALUES ('sec1','val11'),('sec2','val22');
-SELECT sec2 AS s, val2 AS v FROM t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.ini
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
-DROP TABLE t1;
-
-CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
-ENGINE=CONNECT TABLE_TYPE=INI;
-CREATE TABLE t2 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
-ENGINE=CONNECT TABLE_TYPE=INI;
-INSERT INTO t1 VALUES('1sec1','1val1'),('1sec2','1val2');
-INSERT INTO t2 VALUES('2sec1','2val1'),('2sec2','2val2');
-SELECT sec AS s, val AS v FROM t1;
---chmod 0777 $MYSQLD_DATADIR/test/t1.ini
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
-SELECT sec AS s, val AS v FROM t2;
---chmod 0777 $MYSQLD_DATADIR/test/t2.ini
---replace_result $MYSQLD_DATADIR DATADIR
---eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.ini'),'\r\n','\n'),'\n\n','\n');
-DROP TABLE t1, t2;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--copy_file $MTR_SUITE_DIR/std_data/contact.ini $MYSQLD_DATADIR/test/contact.ini
+
+--echo #
+--echo # Testing errors
+--echo #
+CREATE TABLE t1
+(
+ ID INT
+) Engine=CONNECT TABLE_TYPE=INI FILE_NAME='nonexistent.txt';
+--replace_regex /on .*test.nonexistent.txt/on DATADIR\/test\/nonexistent.txt/
+# TODO: check why this is needed for Windows
+--replace_result Open(rt) Open(rb)
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Testing examples from the manual
+--echo #
+
+CREATE TABLE t1
+(
+ contact CHAR(16) flag=1,
+ name CHAR(20),
+ forename CHAR(32),
+ hired date date_format='DD/MM/YYYY',
+ address CHAR(64),
+ city CHAR(20),
+ zipcode CHAR(8),
+ tel CHAR(16)
+) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini';
+SELECT contact, name, hired, city, tel FROM t1;
+
+UPDATE t1 SET forename= 'Harry' where contact='UK1';
+SELECT * FROM t1 WHERE contact='UK1';
+INSERT INTO t1 (contact,forename) VALUES ('UK1','Harrison');
+SELECT * FROM t1 WHERE contact='UK1';
+INSERT INTO t1 (contact,forename) VALUES ('UK2','John');
+SELECT * FROM t1 WHERE contact='UK2';
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/contact.ini
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
+
+CREATE TABLE t1
+(
+ section CHAR(16) flag=1,
+ keyname CHAR(16) flag=2,
+ value CHAR(32)
+) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='contact.ini'
+ OPTION_LIST='Layout=Row';
+UPDATE t1 SET value='Paul' WHERE section='UK2' AND keyname='forename';
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/contact.ini
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/contact.ini'),'\r\n','\n'),'\n\n','\n');
+
+
+--echo #
+--echo # Testing that the underlying file is created
+--echo #
+CREATE TABLE t1
+(
+ contact CHAR(12) NOT NULL flag=1,
+ c2 CHAR(12) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='tmp.ini';
+INSERT INTO t1 VALUES (10,10),(20,20),(300,300),(4000,4000), ('a b','c d');
+SELECT * FROM t1;
+DROP TABLE t1;
+--chmod 0777 $MYSQLD_DATADIR/test/tmp.ini
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/tmp.ini'),'\r\n','\n'),'\n\n','\n');
+
+
+--echo #
+--echo # Testing bad table
+--echo #
+CREATE TABLE t1
+(
+ id INT
+) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
+--error ER_GET_ERRMSG
+INSERT INTO t1 VALUES (10);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Testing READONLY tables
+--echo #
+CREATE TABLE t1
+(
+ contact CHAR(10) flag=1,
+ c2 CHAR(60)
+) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.ini';
+INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
+SELECT * FROM t1;
+ALTER TABLE t1 READONLY=1;
+SHOW CREATE TABLE t1;
+--error ER_OPEN_AS_READONLY
+INSERT INTO t1 VALUES ('US',40);
+--error ER_GET_ERRMSG
+UPDATE t1 SET c2=20 WHERE c2=10;
+--error ER_GET_ERRMSG
+DELETE FROM t1 WHERE c2=10;
+--error ER_OPEN_AS_READONLY
+TRUNCATE TABLE t1;
+ALTER TABLE t1 READONLY=0;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES ('US',40);
+SELECT * FROM t1;
+DROP TABLE t1;
+--remove_file $MYSQLD_DATADIR/test/t1.ini
+
+
+#
+# Clean up
+#
+--remove_file $MYSQLD_DATADIR/test/contact.ini
+--remove_file $MYSQLD_DATADIR/test/tmp.ini
+
+
+--echo #
+--echo # Bug: TABLE_TYPE=ini does not clear memory between CREATE TABLEs
+--echo #
+CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE=INI;
+INSERT INTO t1 VALUES ('sec1','val1'),('sec2','val2');
+SELECT sec AS s, val AS v FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1 (sec2 CHAR(10) NOT NULL FLAG=1, val2 CHAR(10) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE=INI;
+INSERT INTO t1 VALUES ('sec1','val11'),('sec2','val22');
+SELECT sec2 AS s, val2 AS v FROM t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.ini
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
+DROP TABLE t1;
+
+CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE=INI;
+CREATE TABLE t2 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL)
+ENGINE=CONNECT TABLE_TYPE=INI;
+INSERT INTO t1 VALUES('1sec1','1val1'),('1sec2','1val2');
+INSERT INTO t2 VALUES('2sec1','2val1'),('2sec2','2val2');
+SELECT sec AS s, val AS v FROM t1;
+--chmod 0777 $MYSQLD_DATADIR/test/t1.ini
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t1.ini'),'\r\n','\n'),'\n\n','\n');
+SELECT sec AS s, val AS v FROM t2;
+--chmod 0777 $MYSQLD_DATADIR/test/t2.ini
+--replace_result $MYSQLD_DATADIR DATADIR
+--eval SELECT REPLACE(REPLACE(LOAD_FILE('$MYSQLD_DATADIR/test/t2.ini'),'\r\n','\n'),'\n\n','\n');
+DROP TABLE t1, t2;
diff --git a/storage/connect/mysql-test/connect/t/vec.test b/storage/connect/mysql-test/connect/t/vec.test
index aca78987a97..c88a857761d 100644
--- a/storage/connect/mysql-test/connect/t/vec.test
+++ b/storage/connect/mysql-test/connect/t/vec.test
@@ -1,80 +1,80 @@
-let $MYSQLD_DATADIR= `select @@datadir`;
-
-CREATE TABLE dir1 (
- spath VARCHAR(256) NOT NULL flag=1,
- fname VARCHAR(256) NOT NULL,
- ftype CHAR(4) NOT NULL,
- size DOUBLE(12,0) NOT NULL flag=5
-) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*vec*';
-
-
-CREATE TABLE t1
-(
- a INT NOT NULL,
- b CHAR(10) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec';
-SHOW CREATE TABLE t1;
-# Testing SELECT on empty file
---replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
-SELECT * FROM t1;
-INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
-SELECT * FROM t1;
-SELECT a FROM t1;
-SELECT b FROM t1;
---replace_result $MYSQLD_DATADIR DATADIR/
-SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
-DROP TABLE t1;
---remove_file $MYSQLD_DATADIR/test/t1vec1
---remove_file $MYSQLD_DATADIR/test/t1vec2
-
-
-CREATE TABLE t1
-(
- a INT NOT NULL,
- b CHAR(10) NOT NULL
-) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec' MAX_ROWS=10;
-SHOW CREATE TABLE t1;
-# Testing SELECTs on empty file
---replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
-SELECT * FROM t1;
---replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
-SELECT a FROM t1;
---replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
-SELECT b FROM t1;
-INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
-SELECT * FROM t1;
-SELECT a FROM t1;
-SELECT b FROM t1;
---replace_result $MYSQLD_DATADIR DATADIR/
-SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
---echo #
---echo # Testing READONLY
---echo #
-ALTER TABLE t1 READONLY=yes;
-SHOW CREATE TABLE t1;
---error ER_OPEN_AS_READONLY
-INSERT INTO t1 VALUES (4,'test04');
---error ER_OPEN_AS_READONLY
-UPDATE t1 SET b='test04' WHERE a=3;
---error ER_OPEN_AS_READONLY
-DELETE FROM t1 WHERE a=3;
---error ER_OPEN_AS_READONLY
-TRUNCATE TABLE t1;
-ALTER TABLE t1 READONLY=no;
-SHOW CREATE TABLE t1;
-INSERT INTO t1 VALUES (4,'test04');
-UPDATE t1 SET b='test04a' WHERE a=4;
-DELETE FROM t1 WHERE a=0;
-SELECT * FROM t1;
-TRUNCATE TABLE t1;
-SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
-SELECT * FROM t1;
-DROP TABLE t1;
---remove_file $MYSQLD_DATADIR/test/t1vec
---remove_file $MYSQLD_DATADIR/test/t1vec.blk
-
-
---echo #
---echo # Clean up
---echo #
-DROP TABLE dir1;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+CREATE TABLE dir1 (
+ spath VARCHAR(256) NOT NULL flag=1,
+ fname VARCHAR(256) NOT NULL,
+ ftype CHAR(4) NOT NULL,
+ size DOUBLE(12,0) NOT NULL flag=5
+) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*vec*';
+
+
+CREATE TABLE t1
+(
+ a INT NOT NULL,
+ b CHAR(10) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec';
+SHOW CREATE TABLE t1;
+# Testing SELECT on empty file
+--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
+SELECT * FROM t1;
+INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
+SELECT * FROM t1;
+SELECT a FROM t1;
+SELECT b FROM t1;
+--replace_result $MYSQLD_DATADIR DATADIR/
+SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
+DROP TABLE t1;
+--remove_file $MYSQLD_DATADIR/test/t1vec1
+--remove_file $MYSQLD_DATADIR/test/t1vec2
+
+
+CREATE TABLE t1
+(
+ a INT NOT NULL,
+ b CHAR(10) NOT NULL
+) ENGINE=CONNECT TABLE_TYPE=VEC FILE_NAME='t1vec' MAX_ROWS=10;
+SHOW CREATE TABLE t1;
+# Testing SELECTs on empty file
+--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
+SELECT * FROM t1;
+--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
+SELECT a FROM t1;
+--replace_regex /Open.rb. error 2 on .*\/test\/t1vec/Open(rb) error 2 on DATADIR\/test\/t1vec/
+SELECT b FROM t1;
+INSERT INTO t1 VALUES (0,'test01'), (1,'test01'), (2,'test02'), (3,'test03');
+SELECT * FROM t1;
+SELECT a FROM t1;
+SELECT b FROM t1;
+--replace_result $MYSQLD_DATADIR DATADIR/
+SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
+--echo #
+--echo # Testing READONLY
+--echo #
+ALTER TABLE t1 READONLY=yes;
+SHOW CREATE TABLE t1;
+--error ER_OPEN_AS_READONLY
+INSERT INTO t1 VALUES (4,'test04');
+--error ER_GET_ERRMSG
+UPDATE t1 SET b='test04' WHERE a=3;
+--error ER_GET_ERRMSG
+DELETE FROM t1 WHERE a=3;
+--error ER_OPEN_AS_READONLY
+TRUNCATE TABLE t1;
+ALTER TABLE t1 READONLY=no;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (4,'test04');
+UPDATE t1 SET b='test04a' WHERE a=4;
+DELETE FROM t1 WHERE a=0;
+SELECT * FROM t1;
+TRUNCATE TABLE t1;
+SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
+SELECT * FROM t1;
+DROP TABLE t1;
+--remove_file $MYSQLD_DATADIR/test/t1vec
+--remove_file $MYSQLD_DATADIR/test/t1vec.blk
+
+
+--echo #
+--echo # Clean up
+--echo #
+DROP TABLE dir1;
diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h
index 6f6853d9f17..29e4bf77f44 100644
--- a/storage/connect/reldef.h
+++ b/storage/connect/reldef.h
@@ -195,6 +195,8 @@ class DllExport COLDEF : public COLCRT { /* Column description block
int GetPoff(void) {return Poff;}
int Define(PGLOBAL g, void *memp, PCOLINFO cfp, int poff);
void Define(PGLOBAL g, PCOL colp);
+ bool IsSpecial(void) {return (Flags & U_SPECIAL) ? true : false;}
+ bool IsVirtual(void) {return (Flags & U_VIRTUAL) ? true : false;}
protected:
int Buf_Type; /* Internal data type */
diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp
index 86ce92160ab..e66a84f2fa4 100644
--- a/storage/connect/tabdos.cpp
+++ b/storage/connect/tabdos.cpp
@@ -924,10 +924,12 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
Long = cdp->GetLong();
To_Val = NULL;
OldVal = NULL; // Currently used only in MinMax
+ Dsp = 0;
Ldz = false;
Nod = false;
Dcm = -1;
p = cdp->GetFmt();
+ Buf = NULL;
if (p && IsTypeNum(Buf_Type)) {
// Formatted numeric value
@@ -939,6 +941,9 @@ DOSCOL::DOSCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
case 'N': // Have no decimal point
Nod = true;
break;
+ case 'D': // Decimal separator
+ Dsp = *(++p);
+ break;
} // endswitch p
// Set number of decimal digits
@@ -960,6 +965,7 @@ DOSCOL::DOSCOL(DOSCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
Long = col1->Long;
To_Val = col1->To_Val;
Ldz = col1->Ldz;
+ Dsp = col1->Dsp;
Nod = col1->Nod;
Dcm = col1->Dcm;
OldVal = col1->OldVal;
@@ -1003,7 +1009,7 @@ bool DOSCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
} // endif's Value, Buf_Type
// Allocate the buffer used in WriteColumn for numeric columns
- if (IsTypeNum(Buf_Type))
+ if (!Buf && IsTypeNum(Buf_Type))
Buf = (char*)PlugSubAlloc(g, NULL, MY_MAX(32, Long + Dcm + 1));
// Because Colblk's have been made from a copy of the original TDB in
@@ -1048,14 +1054,18 @@ void DOSCOL::ReadColumn(PGLOBAL g)
p = tdbp->To_Line + Deplac;
field = Long;
+ /*********************************************************************/
+ /* For a variable length file, check if the field exists. */
+ /*********************************************************************/
+ if (tdbp->Ftype == RECFM_VAR && strlen(tdbp->To_Line) < (unsigned)Deplac)
+ field = 0;
+ else if (Dsp)
+ for(i = 0; i < field; i++)
+ if (p[i] == Dsp)
+ p[i] = '.';
+
switch (tdbp->Ftype) {
case RECFM_VAR:
- /*****************************************************************/
- /* For a variable length file, check if the field exists. */
- /*****************************************************************/
- if (strlen(tdbp->To_Line) < (unsigned)Deplac)
- field = 0;
-
case RECFM_FIX: // Fixed length text file
case RECFM_DBF: // Fixed length DBase file
if (Nod) switch (Buf_Type) {
@@ -1184,6 +1194,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
len = sprintf(Buf, fmt, field - i, Value->GetTinyValue());
break;
case TYPE_DOUBLE:
+ case TYPE_DECIM:
strcpy(fmt, (Ldz) ? "%0*.*lf" : "%*.*lf");
sprintf(Buf, fmt, field + ((Nod && Dcm) ? 1 : 0),
Dcm, Value->GetFloatValue());
@@ -1192,7 +1203,7 @@ void DOSCOL::WriteColumn(PGLOBAL g)
if (Nod && Dcm)
for (i = k = 0; i < len; i++, k++)
if (Buf[i] != ' ') {
- if (Buf[i] == '.' || Buf[i] == ',')
+ if (Buf[i] == '.')
k++;
Buf[i] = Buf[k];
@@ -1200,10 +1211,13 @@ void DOSCOL::WriteColumn(PGLOBAL g)
len = strlen(Buf);
break;
+ default:
+ sprintf(g->Message, "Invalid field format for column %s", Name);
+ longjmp(g->jumper[g->jump_level], 31);
} // endswitch BufType
p2 = Buf;
- } else // Standard PlugDB format
+ } else // Standard CONNECT format
p2 = Value->ShowValue(Buf, field);
if (trace)
@@ -1212,7 +1226,10 @@ void DOSCOL::WriteColumn(PGLOBAL g)
if ((len = strlen(p2)) > field) {
sprintf(g->Message, MSG(VALUE_TOO_LONG), p2, Name, field);
longjmp(g->jumper[g->jump_level], 31);
- } // endif
+ } else if (Dsp)
+ for (i = 0; i < len; i++)
+ if (p2[i] == '.')
+ p2[i] = Dsp;
if (trace > 1)
htrc("buffer=%s\n", p2);
diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h
index d6cbc8f8d92..79a2659fb70 100644
--- a/storage/connect/tabdos.h
+++ b/storage/connect/tabdos.h
@@ -193,7 +193,8 @@ class DllExport DOSCOL : public COLBLK {
// Members
PVAL To_Val; // To value used for Update/Insert
PVAL OldVal; // The previous value of the object.
- char *Buf; // Buffer used in write operations
+ char *Buf; // Buffer used in read/write operations
+ char Dsp; // The decimal separator
bool Ldz; // True if field contains leading zeros
bool Nod; // True if no decimal point
int Dcm; // Last Dcm digits are decimals
diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp
index b15d5c201c9..7665395167d 100644
--- a/storage/connect/tabfmt.cpp
+++ b/storage/connect/tabfmt.cpp
@@ -406,7 +406,7 @@ bool CSVDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
// Double check correctness of offset values
if (Catfunc == FNC_NO)
for (PCOLDEF cdp = To_Cols; cdp; cdp = cdp->GetNext())
- if (cdp->GetOffset() < 1) {
+ if (cdp->GetOffset() < 1 && !cdp->IsSpecial()) {
strcpy(g->Message, MSG(BAD_OFFSET_VAL));
return true;
} // endif Offset
@@ -598,7 +598,7 @@ int TDBCSV::EstimatedLength(PGLOBAL g)
PCSVCOL colp;
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
- if (!colp->IsSpecial()) // Not a pseudo column
+ if (!colp->IsSpecial() && !colp->IsVirtual()) // A true column
Fields = MY_MAX(Fields, (int)colp->Fldnum);
if (Columns)
@@ -641,7 +641,7 @@ bool TDBCSV::OpenDB(PGLOBAL g)
if (!Fields) // May have been set in TABFMT::OpenDB
if (Mode != MODE_UPDATE && Mode != MODE_INSERT) {
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
- if (!colp->IsSpecial()) // Not a pseudo column
+ if (!colp->IsSpecial() && !colp->IsVirtual())
Fields = MY_MAX(Fields, (int)colp->Fldnum);
if (Columns)
@@ -649,7 +649,8 @@ bool TDBCSV::OpenDB(PGLOBAL g)
} else
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
- Fields++;
+ if (!cdp->IsVirtual())
+ Fields++;
Offset = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
Fldlen = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
@@ -672,25 +673,27 @@ bool TDBCSV::OpenDB(PGLOBAL g)
if (Field)
// Prepare writing fields
- if (Mode != MODE_UPDATE)
- for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next) {
- i = colp->Fldnum;
- len = colp->GetLength();
- Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
- Field[i][len] = '\0';
- Fldlen[i] = len;
- Fldtyp[i] = IsTypeNum(colp->GetResultType());
- } // endfor colp
-
- else // MODE_UPDATE
- for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext()) {
- i = cdp->GetOffset() - 1;
- len = cdp->GetLength();
- Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
- Field[i][len] = '\0';
- Fldlen[i] = len;
- Fldtyp[i] = IsTypeNum(cdp->GetType());
- } // endfor colp
+ if (Mode != MODE_UPDATE) {
+ for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
+ if (!colp->IsSpecial() && !colp->IsVirtual()) {
+ i = colp->Fldnum;
+ len = colp->GetLength();
+ Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
+ Field[i][len] = '\0';
+ Fldlen[i] = len;
+ Fldtyp[i] = IsTypeNum(colp->GetResultType());
+ } // endif colp
+
+ } else // MODE_UPDATE
+ for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
+ if (!cdp->IsVirtual()) {
+ i = cdp->GetOffset() - 1;
+ len = cdp->GetLength();
+ Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
+ Field[i][len] = '\0';
+ Fldlen[i] = len;
+ Fldtyp[i] = IsTypeNum(cdp->GetType());
+ } // endif cdp
} // endif Use
@@ -1101,7 +1104,7 @@ bool TDBFMT::OpenDB(PGLOBAL g)
PDOSDEF tdp = (PDOSDEF)To_Def;
for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
- if (!colp->IsSpecial()) // Not a pseudo column
+ if (!colp->IsSpecial() && !colp->IsVirtual()) // a true column
Fields = MY_MAX(Fields, (int)colp->Fldnum);
if (Columns)
@@ -1115,7 +1118,7 @@ bool TDBFMT::OpenDB(PGLOBAL g)
// Get the column formats
for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
- if ((i = cdp->GetOffset() - 1) < Fields) {
+ if (!cdp->IsVirtual() && (i = cdp->GetOffset() - 1) < Fields) {
if (!(pfm = cdp->GetFmt())) {
sprintf(g->Message, MSG(NO_FLD_FORMAT), i + 1, Name);
return true;
@@ -1318,6 +1321,11 @@ void CSVCOL::ReadColumn(PGLOBAL g)
// Field have been copied in TDB Field array
PSZ fp = tdbp->Field[Fldnum];
+ if (Dsp)
+ for (int i = 0; fp[i]; i++)
+ if (fp[i] == Dsp)
+ fp[i] = '.';
+
Value->SetValue_psz(fp);
// Set null when applicable
@@ -1365,7 +1373,10 @@ void CSVCOL::WriteColumn(PGLOBAL g)
sprintf(g->Message, MSG(BAD_FLD_LENGTH), Name, p, flen,
tdbp->RowNumber(g), tdbp->GetFile(g));
longjmp(g->jumper[g->jump_level], 34);
- } // endif
+ } else if (Dsp)
+ for (int i = 0; p[i]; i++)
+ if (p[i] == '.')
+ p[i] = Dsp;
if (trace > 1)
htrc("buffer=%s\n", p);
diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp
index dea6978f73e..37c72501840 100644
--- a/storage/connect/tabmysql.cpp
+++ b/storage/connect/tabmysql.cpp
@@ -191,8 +191,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b)
} else
// Otherwise, straight server name,
- // use tablename of federatedx table as remote table name
- Tabname= Name;
+ Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL;
if (trace)
htrc("server: %s Tabname: %s", url, Tabname);
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 24eb37ee776..1d2ef7f4c98 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -355,10 +355,14 @@ ha_innobase::check_if_supported_inplace_alter(
Don't do online ALTER if mtype/unsigned_flag are wrong.
*/
- for (ulint i = 0; i < table->s->fields; i++) {
+ for (ulint i = 0, icol= 0; i < table->s->fields; i++) {
const Field* field = table->field[i];
- const dict_col_t* col = dict_table_get_nth_col(prebuilt->table, i);
+ const dict_col_t* col = dict_table_get_nth_col(prebuilt->table, icol);
ulint unsigned_flag;
+ if (!field->stored_in_db)
+ continue;
+ icol++;
+
if (col->mtype != get_innobase_type_from_mysql_type(&unsigned_flag, field)) {
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index 98d18b2f420..e4adf5fbccd 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -230,8 +230,8 @@ static int really_execute_checkpoint(void)
sizeof(checkpoint_start_log_horizon_char);
for (i= 0; i < (sizeof(record_pieces)/sizeof(record_pieces[0])); i++)
{
- log_array[TRANSLOG_INTERNAL_PARTS + 1 + i]=
- *(LEX_CUSTRING *)&record_pieces[i];
+ log_array[TRANSLOG_INTERNAL_PARTS + 1 + i].str= record_pieces[i].str;
+ log_array[TRANSLOG_INTERNAL_PARTS + 1 + i].length= record_pieces[i].length;
total_rec_length+= (translog_size_t) record_pieces[i].length;
}
if (unlikely(translog_write_record(&lsn, LOGREC_CHECKPOINT,
diff --git a/storage/maria/ma_rnext.c b/storage/maria/ma_rnext.c
index d3fab041d75..b4c1692d77d 100644
--- a/storage/maria/ma_rnext.c
+++ b/storage/maria/ma_rnext.c
@@ -71,7 +71,7 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx)
Normally SQL layer would never request "search next" if
"search first" failed. But HANDLER may do anything.
- As mi_rnext() without preceeding mi_rkey()/mi_rfirst()
+ As mi_rnext() without preceding mi_rkey()/mi_rfirst()
equals to mi_rfirst(), we must restore original state
as if failing mi_rfirst() was not called.
*/
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 623d3c6c92e..9235d5ee96a 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -432,7 +432,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
- printf("%s Ver 1.2 for %s at %s\n", my_progname, SYSTEM_TYPE,
+ printf("%s Ver 1.2 for %s on %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
}
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index 7f351bb35a6..7da960011ca 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -20,8 +20,15 @@
#include "fulltext.h"
+#ifndef HAVE_PSI_INTERFACE
+#define PSI_file_key int
+#define mi_key_file_kfile 0
+#define mi_key_file_dfile 0
+#endif
+
static int delete_one_file(const char *name, const char *ext,
- PSI_file_key pskey, myf flags)
+ PSI_file_key pskey __attribute__((unused)),
+ myf flags)
{
char from[FN_REFLEN];
DBUG_ENTER("delete_one_file");
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index c6af5195f82..060017f10ad 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -475,13 +475,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->blobs[j].offset=offset;
j++;
}
-#if MYSQL_VERSION_ID <= 60100
- /* This is to detect old checksum option */
+ /* This is to detect how to calculate checksums */
if (share->rec[i].null_bit)
share->has_null_fields= 1;
if (share->rec[i].type == FIELD_VARCHAR)
share->has_varchar_fields= 1;
-#endif
offset+=share->rec[i].length;
}
share->rec[i].type=(int) FIELD_LAST; /* End marker */
@@ -775,7 +773,8 @@ void mi_setup_functions(register MYISAM_SHARE *share)
share->read_record=_mi_read_pack_record;
share->read_rnd=_mi_read_rnd_pack_record;
if ((share->options &
- (HA_OPTION_PACK_RECORD | HA_OPTION_NULL_FIELDS)))
+ (HA_OPTION_PACK_RECORD | HA_OPTION_NULL_FIELDS)) ||
+ share->has_varchar_fields)
share->calc_checksum= mi_checksum;
else
share->calc_checksum= mi_static_checksum;
diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c
index ee5c74f8da1..509cd75fbab 100644
--- a/storage/myisam/mi_rnext.c
+++ b/storage/myisam/mi_rnext.c
@@ -66,7 +66,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx)
Normally SQL layer would never request "search next" if
"search first" failed. But HANDLER may do anything.
- As mi_rnext() without preceeding mi_rkey()/mi_rfirst()
+ As mi_rnext() without preceding mi_rkey()/mi_rfirst()
equals to mi_rfirst(), we must restore original state
as if failing mi_rfirst() was not called.
*/
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index 8854a85c3d3..966edc877cd 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -417,6 +417,11 @@ static MI_INFO *open_isam_file(char *name,int mode)
if (verbose)
puts("Recompressing already compressed table");
share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
+
+ /* We want to use the new checksums if we have null fields */
+ if (share->has_null_fields)
+ share->options|= HA_OPTION_NULL_FIELDS;
+
}
if (! force_pack && share->state.state.records != 0 &&
(share->state.state.records <= 1 ||
@@ -2966,7 +2971,8 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
uint key;
DBUG_ENTER("save_state");
- options|= HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA;
+ options|= (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
+ (share->options & HA_OPTION_NULL_FIELDS));
mi_int2store(share->state.header.options,options);
share->state.state.data_file_length=new_length;
@@ -3015,7 +3021,8 @@ static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length,
state= isam_file->s->state;
options= (mi_uint2korr(state.header.options) | HA_OPTION_COMPRESS_RECORD |
- HA_OPTION_READ_ONLY_DATA);
+ HA_OPTION_READ_ONLY_DATA |
+ (isam_file->s->options & HA_OPTION_NULL_FIELDS));
mi_int2store(state.header.options,options);
state.state.data_file_length=new_length;
state.state.del=0;
diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc
index 016a50abbe5..58db8dc0031 100644
--- a/storage/perfschema/ha_perfschema.cc
+++ b/storage/perfschema/ha_perfschema.cc
@@ -206,7 +206,7 @@ maria_declare_plugin(perfschema)
pfs_status_vars,
NULL,
"0.1",
- MariaDB_PLUGIN_MATURITY_GAMMA /* because MySQL-5.5 is RC */
+ MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc
index 5db626314a2..473f4edce7a 100644
--- a/storage/perfschema/pfs_digest.cc
+++ b/storage/perfschema/pfs_digest.cc
@@ -47,7 +47,7 @@
/**
Token array :
- Token array is an array of bytes to store tokens recieved during parsing.
+ Token array is an array of bytes to store tokens received during parsing.
Following is the way token array is formed.
...<non-id-token><non-id-token><id-token><id_len><id_text>...
@@ -207,7 +207,7 @@ find_or_create_digest(PFS_thread *thread,
PFS_statements_digest_stat **entry;
PFS_statements_digest_stat *pfs= NULL;
- ulonglong now= microsecond_interval_timer();
+ ulonglong now= my_hrtime().val;
search:
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index 664df62e586..c5b9292e8f2 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -54,6 +54,10 @@
extern handlerton *spider_hton_ptr;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+extern HASH spider_open_tables;
+#endif
+extern pthread_mutex_t spider_lgtm_tblhnd_share_mutex;
ha_spider::ha_spider(
) : handler(spider_hton_ptr, NULL)
@@ -152,6 +156,7 @@ ha_spider::ha_spider(
result_list.tmp_pos_row_first = NULL;
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
result_list.direct_aggregate = FALSE;
+ result_list.snap_direct_aggregate = FALSE;
#endif
result_list.casual_read = NULL;
result_list.use_both_key = FALSE;
@@ -257,6 +262,7 @@ ha_spider::ha_spider(
result_list.tmp_pos_row_first = NULL;
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
result_list.direct_aggregate = FALSE;
+ result_list.snap_direct_aggregate = FALSE;
#endif
result_list.casual_read = NULL;
result_list.use_both_key = FALSE;
@@ -1236,13 +1242,13 @@ int ha_spider::external_lock(
#ifdef HA_CAN_BULK_ACCESS
external_lock_cnt++;
#endif
- if (store_error_num)
- DBUG_RETURN(store_error_num);
if (
lock_type == F_UNLCK &&
sql_command != SQLCOM_UNLOCK_TABLES
)
DBUG_RETURN(0);
+ if (store_error_num)
+ DBUG_RETURN(store_error_num);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if ((conn_kinds & SPIDER_CONN_KIND_MYSQL))
{
@@ -1577,6 +1583,7 @@ int ha_spider::reset()
direct_aggregate_item_current = direct_aggregate_item_current->next;
}
result_list.direct_aggregate = FALSE;
+ result_list.snap_direct_aggregate = FALSE;
#endif
store_error_num = 0;
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -1716,6 +1723,7 @@ int ha_spider::reset()
insert_delayed = FALSE;
use_pre_call = FALSE;
use_pre_records = FALSE;
+ pre_bitmap_checked = FALSE;
bulk_insert = FALSE;
clone_bitmap_init = FALSE;
result_list.tmp_table_join = FALSE;
@@ -1877,25 +1885,29 @@ int ha_spider::index_init(
init_index_handler = FALSE;
use_spatial_index = FALSE;
- if (result_list.lock_type == F_WRLCK)
- {
- pk_update = FALSE;
+ if (pre_bitmap_checked)
+ pre_bitmap_checked = FALSE;
+ else {
+ if (result_list.lock_type == F_WRLCK)
+ {
+ pk_update = FALSE;
/*
- check_and_start_bulk_update(SPD_BU_START_BY_INDEX_OR_RND_INIT);
+ check_and_start_bulk_update(SPD_BU_START_BY_INDEX_OR_RND_INIT);
*/
- if (
- update_request &&
- share->have_recovery_link &&
- (pk_update = spider_check_pk_update(table))
- ) {
- bitmap_set_all(table->read_set);
- if (is_clone)
- memset(searched_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ if (
+ update_request &&
+ share->have_recovery_link &&
+ (pk_update = spider_check_pk_update(table))
+ ) {
+ bitmap_set_all(table->read_set);
+ if (is_clone)
+ memset(searched_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ }
}
- }
- if (!is_clone)
- set_select_column_mode();
+ if (!is_clone)
+ set_select_column_mode();
+ }
if ((error_num = reset_sql_sql(
SPIDER_SQL_TYPE_SELECT_SQL | SPIDER_SQL_TYPE_HANDLER)))
@@ -4199,6 +4211,31 @@ ha_rows ha_spider::multi_range_read_info_const(
{
DBUG_ENTER("ha_spider::multi_range_read_info_const");
DBUG_PRINT("info",("spider this=%p", this));
+ if (!pre_bitmap_checked)
+ {
+ if (result_list.lock_type == F_WRLCK)
+ {
+ pk_update = FALSE;
+ if (
+ update_request &&
+ share->have_recovery_link &&
+ (pk_update = spider_check_pk_update(table))
+ ) {
+ bitmap_set_all(table->read_set);
+ if (is_clone)
+ memset(searched_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ }
+ }
+
+ if (!is_clone)
+ set_select_column_mode();
+
+ pre_bitmap_checked = TRUE;
+ }
+/*
+ multi_range_num = n_ranges;
+ mrr_have_range = FALSE;
+*/
ha_rows rows =
handler::multi_range_read_info_const(
keyno,
@@ -4238,6 +4275,31 @@ ha_rows ha_spider::multi_range_read_info(
{
DBUG_ENTER("ha_spider::multi_range_read_info");
DBUG_PRINT("info",("spider this=%p", this));
+ if (!pre_bitmap_checked)
+ {
+ if (result_list.lock_type == F_WRLCK)
+ {
+ pk_update = FALSE;
+ if (
+ update_request &&
+ share->have_recovery_link &&
+ (pk_update = spider_check_pk_update(table))
+ ) {
+ bitmap_set_all(table->read_set);
+ if (is_clone)
+ memset(searched_bitmap, 0xFF, no_bytes_in_map(table->read_set));
+ }
+ }
+
+ if (!is_clone)
+ set_select_column_mode();
+
+ pre_bitmap_checked = TRUE;
+ }
+/*
+ multi_range_num = n_ranges;
+ mrr_have_range = FALSE;
+*/
ha_rows rows =
handler::multi_range_read_info(
keyno,
@@ -4266,6 +4328,7 @@ int ha_spider::multi_range_read_init(
DBUG_PRINT("info",("spider this=%p", this));
DBUG_PRINT("info",("spider n_ranges=%u", n_ranges));
multi_range_num = n_ranges;
+ mrr_have_range = FALSE;
DBUG_RETURN(
handler::multi_range_read_init(
seq,
@@ -4360,6 +4423,9 @@ int ha_spider::read_multi_range_first_internal(
#endif
result_list.key_info = &table->key_info[active_index];
if (
+#ifdef HA_MRR_USE_DEFAULT_IMPL
+ multi_range_num == 1 ||
+#endif
result_list.multi_split_read <= 1 ||
(sql_kinds & SPIDER_SQL_KIND_HANDLER)
) {
@@ -4380,6 +4446,7 @@ int ha_spider::read_multi_range_first_internal(
DBUG_RETURN(error_num);
set_where_pos_sql(SPIDER_SQL_TYPE_SELECT_SQL);
#ifdef HA_MRR_USE_DEFAULT_IMPL
+ error_num = HA_ERR_END_OF_FILE;
while (!(range_res = mrr_funcs.next(mrr_iter, &mrr_cur_range)))
#else
for (
@@ -4663,6 +4730,8 @@ int ha_spider::read_multi_range_first_internal(
#ifndef WITHOUT_SPIDER_BG_SEARCH
}
#endif
+ if (error_num)
+ break;
}
if (error_num)
{
@@ -5749,12 +5818,23 @@ int ha_spider::read_multi_range_next(
pt_clone_source_handler->pt_clone_last_searcher = this;
}
if (
+#ifdef HA_MRR_USE_DEFAULT_IMPL
+ multi_range_num == 1 ||
+#endif
result_list.multi_split_read <= 1 ||
(sql_kinds & SPIDER_SQL_KIND_HANDLER)
) {
if (!(error_num = spider_db_seek_next(table->record[0], this,
search_link_idx, table)))
- DBUG_RETURN(check_ha_range_eof());
+ {
+#ifdef HA_MRR_USE_DEFAULT_IMPL
+ *range_info = (char *) mrr_cur_range.ptr;
+#else
+ *found_range_p = multi_range_curr;
+#endif
+ DBUG_RETURN(0);
+ }
+
#ifdef HA_MRR_USE_DEFAULT_IMPL
range_res = mrr_funcs.next(mrr_iter, &mrr_cur_range);
DBUG_PRINT("info",("spider range_res1=%d", range_res));
@@ -6073,6 +6153,8 @@ int ha_spider::read_multi_range_next(
#ifndef WITHOUT_SPIDER_BG_SEARCH
}
#endif
+ if (error_num)
+ break;
}
if (error_num)
{
@@ -7526,7 +7608,7 @@ void ha_spider::position(
if (select_column_mode)
{
spider_db_handler *dbton_hdl =
- dbton_handler[result_list.current->result->dbton_id];
+ dbton_handler[result_list.current->dbton_id];
dbton_hdl->copy_minimum_select_bitmap(position_bitmap);
}
position_bitmap_init = TRUE;
@@ -8102,14 +8184,19 @@ int ha_spider::info(
#endif
sql_command = thd_sql_command(thd);
if (
+/*
sql_command == SQLCOM_DROP_TABLE ||
sql_command == SQLCOM_ALTER_TABLE ||
sql_command == SQLCOM_SHOW_CREATE
+*/
+ sql_command == SQLCOM_DROP_TABLE ||
+ sql_command == SQLCOM_ALTER_TABLE
) {
if (flag & HA_STATUS_AUTO)
{
- if (share->auto_increment_value)
- stats.auto_increment_value = share->auto_increment_value;
+ if (share->lgtm_tblhnd_share->auto_increment_value)
+ stats.auto_increment_value =
+ share->lgtm_tblhnd_share->auto_increment_value;
else {
stats.auto_increment_value = 1;
#ifdef HANDLER_HAS_CAN_USE_FOR_AUTO_INC_INIT
@@ -8174,7 +8261,7 @@ int ha_spider::info(
share->partition_share &&
#endif
tmp_auto_increment_mode == 1 &&
- !share->auto_increment_init
+ !share->lgtm_tblhnd_share->auto_increment_init
) {
sts_interval = 0;
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -8339,23 +8426,30 @@ int ha_spider::info(
)
) {
get_auto_increment(0, 0, 0, &first_value, &nb_reserved_values);
- share->auto_increment_value = first_value;
- share->auto_increment_lclval = first_value;
- share->auto_increment_init = TRUE;
+ share->lgtm_tblhnd_share->auto_increment_value = first_value;
+ share->lgtm_tblhnd_share->auto_increment_lclval = first_value;
+ share->lgtm_tblhnd_share->auto_increment_init = TRUE;
DBUG_PRINT("info",("spider init auto_increment_lclval=%llu",
- share->auto_increment_lclval));
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
stats.auto_increment_value = first_value;
- } else if (tmp_auto_increment_mode == 1 && !share->auto_increment_init)
+ } else if (tmp_auto_increment_mode == 1 &&
+ !share->lgtm_tblhnd_share->auto_increment_init)
{
- share->auto_increment_lclval = share->auto_increment_value;
- share->auto_increment_init = TRUE;
- stats.auto_increment_value = share->auto_increment_value;
+ share->lgtm_tblhnd_share->auto_increment_lclval =
+ share->lgtm_tblhnd_share->auto_increment_value;
+ share->lgtm_tblhnd_share->auto_increment_init = TRUE;
+ stats.auto_increment_value =
+ share->lgtm_tblhnd_share->auto_increment_value;
} else {
- stats.auto_increment_value = share->auto_increment_value;
+ stats.auto_increment_value =
+ share->lgtm_tblhnd_share->auto_increment_value;
}
} else {
#endif
- stats.auto_increment_value = share->auto_increment_value;
+ stats.auto_increment_value =
+ share->lgtm_tblhnd_share->auto_increment_value;
#ifdef WITH_PARTITION_STORAGE_ENGINE
}
#endif
@@ -8774,6 +8868,10 @@ int ha_spider::pre_records()
{
DBUG_RETURN(0);
}
+ if (!(share->additional_table_flags & HA_HAS_RECORDS))
+ {
+ DBUG_RETURN(0);
+ }
THD *thd = trx->thd;
if (
spider_param_sync_autocommit(thd) &&
@@ -8801,6 +8899,10 @@ ha_rows ha_spider::records()
use_pre_records = FALSE;
DBUG_RETURN(0);
}
+ if (!(share->additional_table_flags & HA_HAS_RECORDS))
+ {
+ DBUG_RETURN(handler::records());
+ }
if (!use_pre_records)
{
THD *thd = trx->thd;
@@ -8851,7 +8953,6 @@ ulonglong ha_spider::table_flags() const
HA_NO_COPY_ON_ALTER |
HA_BINLOG_ROW_CAPABLE |
HA_BINLOG_STMT_CAPABLE |
- HA_HAS_RECORDS |
HA_PARTIAL_COLUMN_READ |
#ifdef HA_CAN_BULK_ACCESS
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -9011,25 +9112,28 @@ int ha_spider::update_auto_increment()
)
) {
lock_here = TRUE;
- pthread_mutex_lock(&share->auto_increment_mutex);
- next_insert_id = share->auto_increment_value;
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
+ next_insert_id = share->lgtm_tblhnd_share->auto_increment_value;
}
if ((error_num = handler::update_auto_increment()))
{
if (lock_here)
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
DBUG_RETURN(check_error_mode(error_num));
}
if (lock_here)
{
if (insert_id_for_cur_row)
{
- share->auto_increment_lclval = insert_id_for_cur_row + 1;
- share->auto_increment_value = next_insert_id;
+ share->lgtm_tblhnd_share->auto_increment_lclval =
+ insert_id_for_cur_row + 1;
+ share->lgtm_tblhnd_share->auto_increment_value = next_insert_id;
DBUG_PRINT("info",("spider after auto_increment_lclval=%llu",
- share->auto_increment_lclval));
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
}
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
if (!store_last_insert_id)
{
@@ -9085,15 +9189,16 @@ error_index_init:
DBUG_VOID_RETURN;
} else {
if (auto_increment_mode != 1)
- pthread_mutex_lock(&share->auto_increment_mutex);
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
DBUG_PRINT("info",("spider before auto_increment_lclval=%llu",
- share->auto_increment_lclval));
- *first_value = share->auto_increment_lclval;
- share->auto_increment_lclval += nb_desired_values * increment;
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ *first_value = share->lgtm_tblhnd_share->auto_increment_lclval;
+ share->lgtm_tblhnd_share->auto_increment_lclval +=
+ nb_desired_values * increment;
DBUG_PRINT("info",("spider after auto_increment_lclval=%llu",
- share->auto_increment_lclval));
+ share->lgtm_tblhnd_share->auto_increment_lclval));
if (auto_increment_mode != 1)
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
DBUG_VOID_RETURN;
}
@@ -9105,12 +9210,12 @@ int ha_spider::reset_auto_increment(
DBUG_PRINT("info",("spider this=%p", this));
if (table->next_number_field)
{
- pthread_mutex_lock(&share->auto_increment_mutex);
- share->auto_increment_lclval = value;
- share->auto_increment_init = TRUE;
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
+ share->lgtm_tblhnd_share->auto_increment_lclval = value;
+ share->lgtm_tblhnd_share->auto_increment_init = TRUE;
DBUG_PRINT("info",("spider init auto_increment_lclval=%llu",
- share->auto_increment_lclval));
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
DBUG_RETURN(0);
}
@@ -9245,18 +9350,19 @@ int ha_spider::write_row(
force_auto_increment = FALSE;
table->file->insert_id_for_cur_row = 0;
} else {
- if (!share->auto_increment_init)
+ if (!share->lgtm_tblhnd_share->auto_increment_init)
{
- pthread_mutex_lock(&share->auto_increment_mutex);
- if (!share->auto_increment_init)
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
+ if (!share->lgtm_tblhnd_share->auto_increment_init)
{
info(HA_STATUS_AUTO);
- share->auto_increment_lclval = stats.auto_increment_value;
- share->auto_increment_init = TRUE;
+ share->lgtm_tblhnd_share->auto_increment_lclval =
+ stats.auto_increment_value;
+ share->lgtm_tblhnd_share->auto_increment_init = TRUE;
DBUG_PRINT("info",("spider init auto_increment_lclval=%llu",
- share->auto_increment_lclval));
+ share->lgtm_tblhnd_share->auto_increment_lclval));
}
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
if ((error_num = update_auto_increment()))
DBUG_RETURN(error_num);
@@ -9451,14 +9557,15 @@ int ha_spider::update_row(
new_data == table->record[0] &&
!table->s->next_number_keypart
) {
- pthread_mutex_lock(&share->auto_increment_mutex);
- if (!share->auto_increment_init)
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
+ if (!share->lgtm_tblhnd_share->auto_increment_init)
{
info(HA_STATUS_AUTO);
- share->auto_increment_lclval = stats.auto_increment_value;
- share->auto_increment_init = TRUE;
+ share->lgtm_tblhnd_share->auto_increment_lclval =
+ stats.auto_increment_value;
+ share->lgtm_tblhnd_share->auto_increment_init = TRUE;
DBUG_PRINT("info",("spider init auto_increment_lclval=%llu",
- share->auto_increment_lclval));
+ share->lgtm_tblhnd_share->auto_increment_lclval));
}
ulonglong tmp_auto_increment;
if (((Field_num *) table->found_next_number_field)->unsigned_flag)
@@ -9473,14 +9580,16 @@ int ha_spider::update_row(
else
tmp_auto_increment = 0;
}
- if (tmp_auto_increment >= share->auto_increment_lclval)
+ if (tmp_auto_increment >= share->lgtm_tblhnd_share->auto_increment_lclval)
{
- share->auto_increment_lclval = tmp_auto_increment + 1;
- share->auto_increment_value = tmp_auto_increment + 1;
+ share->lgtm_tblhnd_share->auto_increment_lclval = tmp_auto_increment + 1;
+ share->lgtm_tblhnd_share->auto_increment_value = tmp_auto_increment + 1;
DBUG_PRINT("info",("spider after auto_increment_lclval=%llu",
- share->auto_increment_lclval));
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
}
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
DBUG_RETURN(0);
}
@@ -10013,13 +10122,15 @@ int ha_spider::delete_all_rows()
if (sql_command == SQLCOM_TRUNCATE && table->found_next_number_field)
{
DBUG_PRINT("info",("spider reset auto increment"));
- pthread_mutex_lock(&share->auto_increment_mutex);
- share->auto_increment_lclval = 1;
- share->auto_increment_init = FALSE;
- share->auto_increment_value = 1;
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
+ share->lgtm_tblhnd_share->auto_increment_lclval = 1;
+ share->lgtm_tblhnd_share->auto_increment_init = FALSE;
+ share->lgtm_tblhnd_share->auto_increment_value = 1;
DBUG_PRINT("info",("spider init auto_increment_lclval=%llu",
- share->auto_increment_lclval));
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
DBUG_RETURN(0);
}
@@ -10053,13 +10164,15 @@ int ha_spider::truncate()
if (sql_command == SQLCOM_TRUNCATE && table->found_next_number_field)
{
DBUG_PRINT("info",("spider reset auto increment"));
- pthread_mutex_lock(&share->auto_increment_mutex);
- share->auto_increment_lclval = 1;
- share->auto_increment_init = FALSE;
- share->auto_increment_value = 1;
+ pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex);
+ share->lgtm_tblhnd_share->auto_increment_lclval = 1;
+ share->lgtm_tblhnd_share->auto_increment_init = FALSE;
+ share->lgtm_tblhnd_share->auto_increment_value = 1;
DBUG_PRINT("info",("spider init auto_increment_lclval=%llu",
- share->auto_increment_lclval));
- pthread_mutex_unlock(&share->auto_increment_mutex);
+ share->lgtm_tblhnd_share->auto_increment_lclval));
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
+ pthread_mutex_unlock(&share->lgtm_tblhnd_share->auto_increment_mutex);
}
DBUG_RETURN(0);
}
@@ -10223,6 +10336,20 @@ int ha_spider::create(
memset(&tmp_share, 0, sizeof(SPIDER_SHARE));
tmp_share.table_name = (char*) name;
tmp_share.table_name_length = strlen(name);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ tmp_share.table_name_hash_value = my_calc_hash(&trx->trx_alter_table_hash,
+ (uchar*) tmp_share.table_name, tmp_share.table_name_length);
+ tmp_share.lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ name, tmp_share.table_name_length, tmp_share.table_name_hash_value,
+ FALSE, TRUE, &error_num);
+#else
+ tmp_share.lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ name, tmp_share.table_name_length, FALSE, TRUE, &error_num);
+#endif
+ if (!tmp_share.lgtm_tblhnd_share)
+ {
+ goto error;
+ }
if (form->s->keys > 0 &&
!(tmp_share.key_hint = new spider_string[form->s->keys])
) {
@@ -10269,8 +10396,6 @@ int ha_spider::create(
trx->query_id = thd->query_id;
}
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
- tmp_share.table_name_hash_value = my_calc_hash(&trx->trx_alter_table_hash,
- (uchar*) tmp_share.table_name, tmp_share.table_name_length);;
if (!(alter_table =
(SPIDER_ALTER_TABLE*) my_hash_search_using_hash_value(
&trx->trx_alter_table_hash, tmp_share.table_name_hash_value,
@@ -10318,6 +10443,23 @@ int ha_spider::create(
}
}
+ if (
+ (
+ (info->used_fields & HA_CREATE_USED_AUTO) ||
+ sql_command == SQLCOM_ALTER_TABLE ||
+ sql_command == SQLCOM_CREATE_INDEX ||
+ sql_command == SQLCOM_RENAME_TABLE
+ ) &&
+ info->auto_increment_value > 0
+ ) {
+ pthread_mutex_lock(&tmp_share.lgtm_tblhnd_share->auto_increment_mutex);
+ tmp_share.lgtm_tblhnd_share->auto_increment_value =
+ info->auto_increment_value;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ tmp_share.lgtm_tblhnd_share->auto_increment_value));
+ pthread_mutex_unlock(&tmp_share.lgtm_tblhnd_share->auto_increment_mutex);
+ }
+
spider_free_share_alloc(&tmp_share);
DBUG_RETURN(0);
@@ -10325,6 +10467,8 @@ error:
if (table_tables)
spider_close_sys_table(current_thd, table_tables,
&open_tables_backup, need_lock);
+ if (tmp_share.lgtm_tblhnd_share)
+ spider_free_lgtm_tblhnd_share_alloc(tmp_share.lgtm_tblhnd_share, FALSE);
spider_free_share_alloc(&tmp_share);
error_alter_before_unlock:
error_get_trx:
@@ -10334,6 +10478,7 @@ error_get_trx:
void ha_spider::update_create_info(
HA_CREATE_INFO* create_info
) {
+ THD *thd = ha_thd();
DBUG_ENTER("ha_spider::update_create_info");
DBUG_PRINT("info",("spider this=%p", this));
if (!create_info->connect_string.str)
@@ -10344,6 +10489,19 @@ void ha_spider::update_create_info(
DBUG_PRINT("info",
("spider create_info->connect_string=%s",
create_info->connect_string.str));
+ if (
+ !(create_info->used_fields & HA_CREATE_USED_AUTO)
+ ) {
+ info(HA_STATUS_AUTO);
+ create_info->auto_increment_value = stats.auto_increment_value;
+ }
+ if (
+ thd->is_error() &&
+ thd_sql_command(thd) == SQLCOM_SHOW_CREATE
+ ) {
+ DBUG_PRINT("info", ("spider clear_error"));
+ thd->clear_error();
+ }
DBUG_VOID_RETURN;
}
@@ -10351,12 +10509,20 @@ int ha_spider::rename_table(
const char *from,
const char *to
) {
- int error_num, roop_count, old_link_count, from_len = strlen(from);
+ int error_num, roop_count, old_link_count, from_len = strlen(from),
+ to_len = strlen(to), tmp_error_num;
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ my_hash_value_type from_hash_value = my_calc_hash(&spider_open_tables,
+ (uchar*) from, from_len);
+ my_hash_value_type to_hash_value = my_calc_hash(&spider_open_tables,
+ (uchar*) to, to_len);
+#endif
THD *thd = ha_thd();
uint sql_command = thd_sql_command(thd);
SPIDER_TRX *trx;
TABLE *table_tables = NULL;
SPIDER_ALTER_TABLE *alter_table_from, *alter_table_to;
+ SPIDER_LGTM_TBLHND_SHARE *from_lgtm_tblhnd_share, *to_lgtm_tblhnd_share;
#if MYSQL_VERSION_ID < 50500
Open_tables_state open_tables_backup;
#else
@@ -10414,7 +10580,6 @@ int ha_spider::rename_table(
spider_release_ping_table_mon_list(from, from_len, roop_count);
} else if (sql_command == SQLCOM_ALTER_TABLE)
{
- int to_len = strlen(to);
DBUG_PRINT("info",("spider alter_table_from=%p", alter_table_from));
if ((alter_table_to =
(SPIDER_ALTER_TABLE*) my_hash_search(&trx->trx_alter_table_hash,
@@ -10496,6 +10661,37 @@ int ha_spider::rename_table(
*/
}
+ pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ from_lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ from, from_len, from_hash_value, TRUE, FALSE, &error_num);
+#else
+ from_lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ from, from_len, TRUE, FALSE, &error_num);
+#endif
+ if (from_lgtm_tblhnd_share)
+ {
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ to_lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ to, to_len, to_hash_value, TRUE, TRUE, &error_num);
+#else
+ to_lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ to, to_len, TRUE, TRUE, &error_num);
+#endif
+ if (!to_lgtm_tblhnd_share)
+ {
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
+ goto error;
+ }
+ to_lgtm_tblhnd_share->auto_increment_init =
+ from_lgtm_tblhnd_share->auto_increment_init;
+ to_lgtm_tblhnd_share->auto_increment_lclval =
+ from_lgtm_tblhnd_share->auto_increment_lclval;
+ to_lgtm_tblhnd_share->auto_increment_value =
+ from_lgtm_tblhnd_share->auto_increment_value;
+ spider_free_lgtm_tblhnd_share_alloc(from_lgtm_tblhnd_share, TRUE);
+ }
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
spider_delete_init_error_table(from);
DBUG_RETURN(0);
@@ -10503,6 +10699,17 @@ error:
if (table_tables)
spider_close_sys_table(current_thd, table_tables,
&open_tables_backup, need_lock);
+ pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ to_lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ to, to_len, to_hash_value, TRUE, FALSE, &tmp_error_num);
+#else
+ to_lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ to, to_len, TRUE, FALSE, &tmp_error_num);
+#endif
+ if (to_lgtm_tblhnd_share)
+ spider_free_lgtm_tblhnd_share_alloc(to_lgtm_tblhnd_share, TRUE);
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
DBUG_RETURN(error_num);
}
@@ -10549,12 +10756,24 @@ int ha_spider::delete_table(
sql_command == SQLCOM_ALTER_TABLE ||
sql_command == SQLCOM_CREATE_TABLE)
{
+ SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
int roop_count, old_link_count = 0, name_len = strlen(name);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ my_hash_value_type hash_value = my_calc_hash(&spider_open_tables,
+ (uchar*) name, name_len);
+#endif
if (
sql_command == SQLCOM_ALTER_TABLE &&
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ (alter_table =
+ (SPIDER_ALTER_TABLE*) my_hash_search_using_hash_value(
+ &trx->trx_alter_table_hash,
+ hash_value, (uchar*) name, name_len)) &&
+#else
(alter_table =
(SPIDER_ALTER_TABLE*) my_hash_search(&trx->trx_alter_table_hash,
(uchar*) name, name_len)) &&
+#endif
alter_table->now_create
)
DBUG_RETURN(0);
@@ -10594,6 +10813,18 @@ int ha_spider::delete_table(
/* release table mon list */
for (roop_count = 0; roop_count < old_link_count; roop_count++)
spider_release_ping_table_mon_list(name, name_len, roop_count);
+
+ pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ name, name_len, hash_value, TRUE, FALSE, &error_num);
+#else
+ lgtm_tblhnd_share = spider_get_lgtm_tblhnd_share(
+ name, name_len, TRUE, FALSE, &error_num);
+#endif
+ if (lgtm_tblhnd_share)
+ spider_free_lgtm_tblhnd_share_alloc(lgtm_tblhnd_share, TRUE);
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
}
spider_delete_init_error_table(name);
@@ -10973,7 +11204,9 @@ int ha_spider::info_push(
case INFO_KIND_FORCE_LIMIT_BEGIN:
DBUG_PRINT("info",("spider INFO_KIND_FORCE_LIMIT_BEGIN"));
info_limit = *((longlong *) info);
+/*
trx->direct_aggregate_count++;
+*/
break;
case INFO_KIND_FORCE_LIMIT_END:
DBUG_PRINT("info",("spider INFO_KIND_FORCE_LIMIT_END"));
@@ -13357,6 +13590,7 @@ int ha_spider::append_sum_select_sql_part(
DBUG_RETURN(error_num);
}
}
+ trx->direct_aggregate_count++;
DBUG_RETURN(0);
}
#endif
diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h
index 2eb469c691a..08918021e21 100644
--- a/storage/spider/ha_spider.h
+++ b/storage/spider/ha_spider.h
@@ -167,6 +167,7 @@ public:
bool insert_delayed;
bool use_pre_call;
bool use_pre_records;
+ bool pre_bitmap_checked;
enum thr_lock_type lock_type;
int lock_mode;
uint sql_command;
diff --git a/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result b/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result
index 5cc5760257d..3a9c7be3076 100644
--- a/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result
+++ b/storage/spider/mysql-test/spider/bg/r/direct_aggregate.result
@@ -48,31 +48,31 @@ COUNT(*)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l;
MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
deinit
DROP DATABASE IF EXISTS auto_test_local;
diff --git a/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result b/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result
index 9625519a53f..bbdc943601b 100644
--- a/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result
+++ b/storage/spider/mysql-test/spider/bg/r/direct_aggregate_part.result
@@ -39,31 +39,31 @@ COUNT(*)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l2;
MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l2;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l2 WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l2 WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
deinit
DROP DATABASE IF EXISTS auto_test_local;
diff --git a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result
index 2673c633f77..6db61fa93d2 100644
--- a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result
+++ b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result
@@ -414,7 +414,6 @@ id
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
-Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
INSERT INTO t1 (id) VALUES (1);
Warnings:
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
diff --git a/storage/spider/mysql-test/spider/r/direct_aggregate.result b/storage/spider/mysql-test/spider/r/direct_aggregate.result
index 5cc5760257d..3a9c7be3076 100644
--- a/storage/spider/mysql-test/spider/r/direct_aggregate.result
+++ b/storage/spider/mysql-test/spider/r/direct_aggregate.result
@@ -48,31 +48,31 @@ COUNT(*)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l;
MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 1
+Spider_direct_aggregate 0
deinit
DROP DATABASE IF EXISTS auto_test_local;
diff --git a/storage/spider/mysql-test/spider/r/direct_aggregate_part.result b/storage/spider/mysql-test/spider/r/direct_aggregate_part.result
index 9625519a53f..bbdc943601b 100644
--- a/storage/spider/mysql-test/spider/r/direct_aggregate_part.result
+++ b/storage/spider/mysql-test/spider/r/direct_aggregate_part.result
@@ -39,31 +39,31 @@ COUNT(*)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l2;
MAX(a)
5
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l2;
MIN(a)
1
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MAX(a) FROM ta_l2 WHERE a < 5;
MAX(a)
4
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
SELECT MIN(a) FROM ta_l2 WHERE a > 1;
MIN(a)
2
SHOW STATUS LIKE 'Spider_direct_aggregate';
Variable_name Value
-Spider_direct_aggregate 2
+Spider_direct_aggregate 0
deinit
DROP DATABASE IF EXISTS auto_test_local;
diff --git a/storage/spider/mysql-test/spider/r/spider_fixes.result b/storage/spider/mysql-test/spider/r/spider_fixes.result
index 2673c633f77..6db61fa93d2 100644
--- a/storage/spider/mysql-test/spider/r/spider_fixes.result
+++ b/storage/spider/mysql-test/spider/r/spider_fixes.result
@@ -414,7 +414,6 @@ id
Warnings:
Error 12702 Remote table 'auto_test_remote.ter1_1' is not found
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
-Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
INSERT INTO t1 (id) VALUES (1);
Warnings:
Error 1146 Table 'auto_test_remote.ter1_1' doesn't exist
diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc
index 5360946d482..3cdb6ef5f29 100644
--- a/storage/spider/spd_conn.cc
+++ b/storage/spider/spd_conn.cc
@@ -62,6 +62,7 @@ extern PSI_cond_key spd_key_cond_bg_sts_sync;
extern PSI_cond_key spd_key_cond_bg_crd;
extern PSI_cond_key spd_key_cond_bg_crd_sync;
extern PSI_cond_key spd_key_cond_bg_mon;
+extern PSI_cond_key spd_key_cond_bg_mon_sleep;
extern PSI_thread_key spd_key_thd_bg;
extern PSI_thread_key spd_key_thd_bg_sts;
extern PSI_thread_key spd_key_thd_bg_crd;
@@ -3425,6 +3426,8 @@ int spider_create_mon_threads(
&share->bg_mon_mutexes, sizeof(pthread_mutex_t) *
share->all_link_count,
&share->bg_mon_conds, sizeof(pthread_cond_t) * share->all_link_count,
+ &share->bg_mon_sleep_conds,
+ sizeof(pthread_cond_t) * share->all_link_count,
NullS))
) {
error_num = HA_ERR_OUT_OF_MEM;
@@ -3463,6 +3466,22 @@ int spider_create_mon_threads(
goto error_cond_init;
}
}
+ for (roop_count = 0; roop_count < (int) share->all_link_count;
+ roop_count++)
+ {
+ if (
+ share->monitoring_bg_kind[roop_count] &&
+#if MYSQL_VERSION_ID < 50500
+ pthread_cond_init(&share->bg_mon_sleep_conds[roop_count], NULL)
+#else
+ mysql_cond_init(spd_key_cond_bg_mon_sleep,
+ &share->bg_mon_sleep_conds[roop_count], NULL)
+#endif
+ ) {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_sleep_cond_init;
+ }
+ }
link_pack.share = share;
for (roop_count = 0; roop_count < (int) share->all_link_count;
roop_count++)
@@ -3514,6 +3533,13 @@ error_thread_create:
}
share->bg_mon_kill = FALSE;
roop_count = share->all_link_count;
+error_sleep_cond_init:
+ for (roop_count--; roop_count >= 0; roop_count--)
+ {
+ if (share->monitoring_bg_kind[roop_count])
+ pthread_cond_destroy(&share->bg_mon_sleep_conds[roop_count]);
+ }
+ roop_count = share->all_link_count;
error_cond_init:
for (roop_count--; roop_count >= 0; roop_count--)
{
@@ -3543,6 +3569,16 @@ void spider_free_mon_threads(
for (roop_count = 0; roop_count < (int) share->all_link_count;
roop_count++)
{
+ if (
+ share->monitoring_bg_kind[roop_count] &&
+ share->bg_mon_thds[roop_count]
+ ) {
+ share->bg_mon_thds[roop_count]->killed = SPIDER_THD_KILL_CONNECTION;
+ }
+ }
+ for (roop_count = 0; roop_count < (int) share->all_link_count;
+ roop_count++)
+ {
if (share->monitoring_bg_kind[roop_count])
pthread_mutex_lock(&share->bg_mon_mutexes[roop_count]);
}
@@ -3552,11 +3588,13 @@ void spider_free_mon_threads(
{
if (share->monitoring_bg_kind[roop_count])
{
+ pthread_cond_signal(&share->bg_mon_sleep_conds[roop_count]);
pthread_cond_wait(&share->bg_mon_conds[roop_count],
&share->bg_mon_mutexes[roop_count]);
pthread_mutex_unlock(&share->bg_mon_mutexes[roop_count]);
pthread_join(share->bg_mon_threads[roop_count], NULL);
pthread_cond_destroy(&share->bg_mon_conds[roop_count]);
+ pthread_cond_destroy(&share->bg_mon_sleep_conds[roop_count]);
pthread_mutex_destroy(&share->bg_mon_mutexes[roop_count]);
}
}
@@ -3614,7 +3652,9 @@ void *spider_bg_mon_action(
}
share->bg_mon_thds[link_idx] = thd;
pthread_cond_signal(&share->bg_mon_conds[link_idx]);
+/*
pthread_mutex_unlock(&share->bg_mon_mutexes[link_idx]);
+*/
/* init end */
while (TRUE)
@@ -3622,12 +3662,23 @@ void *spider_bg_mon_action(
DBUG_PRINT("info",("spider bg mon sleep %lld",
share->monitoring_bg_interval[link_idx]));
if (!share->bg_mon_kill)
+ {
+ struct timespec abstime;
+ set_timespec_nsec(abstime,
+ share->monitoring_bg_interval[link_idx] * 1000);
+ pthread_cond_timedwait(&share->bg_mon_sleep_conds[link_idx],
+ &share->bg_mon_mutexes[link_idx], &abstime);
+/*
my_sleep((ulong) share->monitoring_bg_interval[link_idx]);
+*/
+ }
DBUG_PRINT("info",("spider bg mon roop start"));
if (share->bg_mon_kill)
{
DBUG_PRINT("info",("spider bg mon kill start"));
+/*
pthread_mutex_lock(&share->bg_mon_mutexes[link_idx]);
+*/
pthread_cond_signal(&share->bg_mon_conds[link_idx]);
pthread_mutex_unlock(&share->bg_mon_mutexes[link_idx]);
spider_free_trx(trx, TRUE);
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index 0e0c8f01b02..7dd0249bddb 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -2490,6 +2490,7 @@ int spider_db_fetch_for_item_sum_func(
) {
int error_num;
SPIDER_SHARE *share = spider->share;
+ THD *thd = spider->trx->thd;
DBUG_ENTER("spider_db_fetch_for_item_sum_func");
DBUG_PRINT("info",("spider Sumfunctype = %d", item_sum->sum_func()));
switch (item_sum->sum_func())
@@ -2556,10 +2557,12 @@ int spider_db_fetch_for_item_sum_func(
}
if (!spider->direct_aggregate_item_current->item)
{
+ Item *free_list = thd->free_list;
spider->direct_aggregate_item_current->item =
new Item_string(share->access_charset);
if (!spider->direct_aggregate_item_current->item)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ thd->free_list = free_list;
}
Item_sum_hybrid *item_hybrid = (Item_sum_hybrid *) item_sum;
@@ -3678,6 +3681,7 @@ int spider_db_store_result(
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
current->record_num = current->result->num_rows();
+ current->dbton_id = current->result->dbton_id;
result_list->record_num += current->record_num;
DBUG_PRINT("info",("spider current->record_num=%lld",
current->record_num));
@@ -3754,6 +3758,7 @@ int spider_db_store_result(
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
}
+ current->dbton_id = current->result->dbton_id;
SPIDER_DB_ROW *row;
if (!(row = current->result->fetch_row()))
{
@@ -5861,8 +5866,10 @@ int spider_db_update_auto_increment(
}
#endif
DBUG_PRINT("info",("spider last_insert_id=%llu", last_insert_id));
- share->auto_increment_value =
+ share->lgtm_tblhnd_share->auto_increment_value =
last_insert_id + affected_rows;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
/*
thd->record_first_successful_insert_id_in_cur_stmt(last_insert_id);
*/
@@ -8047,11 +8054,10 @@ int spider_db_open_item_string(
tmp_str.mem_calc();
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
if (
- str->get_str()->append_for_single_quote(tmp_str2) ||
+ str->append_for_single_quote(tmp_str2) ||
str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN)
)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- str->mem_calc();
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
}
DBUG_RETURN(0);
@@ -9033,11 +9039,13 @@ int spider_db_udf_ping_table(
uint tmp_conn_link_idx = 0;
ha_spider spider;
uchar db_request_phase = 0;
+ ulonglong db_request_id = 0;
spider.share = share;
spider.trx = trx;
spider.need_mons = &need_mon;
spider.conn_link_idx = &tmp_conn_link_idx;
spider.db_request_phase = &db_request_phase;
+ spider.db_request_id = &db_request_id;
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
@@ -9192,8 +9200,7 @@ int spider_db_udf_ping_table_append_mon_next(
str->q_append(SPIDER_SQL_SELECT_STR, SPIDER_SQL_SELECT_LEN);
str->q_append(SPIDER_SQL_PING_TABLE_STR, SPIDER_SQL_PING_TABLE_LEN);
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
- str->get_str()->append_for_single_quote(child_table_name_str.get_str());
- str->mem_calc();
+ str->append_for_single_quote(child_table_name_str.get_str());
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
str->qs_append(link_id);
@@ -9203,8 +9210,7 @@ int spider_db_udf_ping_table_append_mon_next(
str->q_append(limit_str, limit_str_length);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
- str->get_str()->append_for_single_quote(where_clause_str.get_str());
- str->mem_calc();
+ str->append_for_single_quote(where_clause_str.get_str());
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
str->q_append(sid_str, sid_str_length);
@@ -9255,9 +9261,11 @@ int spider_db_udf_ping_table_append_select(
SPIDER_SQL_LIMIT_LEN + limit_str_length
))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
- if (use_where)
- str->get_str()->append_for_single_quote(where_str->get_str());
- str->mem_calc();
+ if (
+ use_where &&
+ str->append_for_single_quote(where_str->get_str())
+ )
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(SPIDER_SQL_LIMIT_STR, SPIDER_SQL_LIMIT_LEN);
str->q_append(limit_str, limit_str_length);
DBUG_RETURN(0);
diff --git a/storage/spider/spd_db_handlersocket.cc b/storage/spider/spd_db_handlersocket.cc
index bf2a0bae419..f7f974a0142 100644
--- a/storage/spider/spd_db_handlersocket.cc
+++ b/storage/spider/spd_db_handlersocket.cc
@@ -820,6 +820,16 @@ int spider_db_handlersocket_result::fetch_index_for_discover_table_structure(
DBUG_PRINT("info",("spider this=%p", this));
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
+
+int spider_db_handlersocket_result::fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+) {
+ DBUG_ENTER("spider_db_handlersocket_result::fetch_table_for_discover_table_structure");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+}
#endif
spider_db_handlersocket::spider_db_handlersocket(
@@ -963,8 +973,11 @@ int spider_db_handlersocket::connect(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
while (hs_conn->get_error_code())
{
- if (!connect_retry_count)
- {
+ THD *thd = current_thd;
+ if (
+ !connect_retry_count ||
+ (thd && thd->killed)
+ ) {
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
conn->tgt_host);
DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
@@ -3481,8 +3494,8 @@ int spider_db_handlersocket_util::append_escaped_util(
) {
DBUG_ENTER("spider_db_handlersocket_util::append_escaped_util");
DBUG_PRINT("info",("spider this=%p", this));
- append_escaped(to->get_str(), from);
- to->mem_calc();
+ if (to->append_for_single_quote(from))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
DBUG_RETURN(0);
}
@@ -4088,7 +4101,9 @@ int spider_handlersocket_handler::append_minimum_select_without_quote(
{
if (minimum_select_bit_is_set((*field)->field_index))
{
+/*
spider_set_bit(minimum_select_bitmap, (*field)->field_index);
+*/
field_length =
handlersocket_share->column_name_str[(*field)->field_index].length();
if (str->reserve(field_length + SPIDER_SQL_COMMA_LEN))
@@ -5283,6 +5298,7 @@ int spider_handlersocket_handler::show_table_status(
) {
spider_db_handlersocket_result res;
SPIDER_SHARE *share = spider->share;
+ ulonglong auto_increment_value = 0;
DBUG_ENTER("spider_handlersocket_show_table_status");
res.fetch_table_status(
sts_mode,
@@ -5291,11 +5307,17 @@ int spider_handlersocket_handler::show_table_status(
share->data_file_length,
share->max_data_file_length,
share->index_file_length,
- share->auto_increment_value,
+ auto_increment_value,
share->create_time,
share->update_time,
share->check_time
);
+ if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value)
+ {
+ share->lgtm_tblhnd_share->auto_increment_value = auto_increment_value;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
+ }
DBUG_RETURN(0);
}
diff --git a/storage/spider/spd_db_handlersocket.h b/storage/spider/spd_db_handlersocket.h
index 5f359d57bd8..1cc1476c83a 100644
--- a/storage/spider/spd_db_handlersocket.h
+++ b/storage/spider/spd_db_handlersocket.h
@@ -220,6 +220,11 @@ public:
spider_string *str,
CHARSET_INFO *access_charset
);
+ int fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+ );
#endif
};
diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h
index 40f547df35e..7741ffcdb16 100644
--- a/storage/spider/spd_db_include.h
+++ b/storage/spider/spd_db_include.h
@@ -159,6 +159,8 @@ typedef st_spider_result SPIDER_RESULT;
#define SPIDER_SQL_CREATE_TABLE_LEN (sizeof(SPIDER_SQL_CREATE_TABLE_STR) - 1)
#define SPIDER_SQL_DEFAULT_CHARSET_STR " default charset "
#define SPIDER_SQL_DEFAULT_CHARSET_LEN (sizeof(SPIDER_SQL_DEFAULT_CHARSET_STR) - 1)
+#define SPIDER_SQL_CHARACTER_SET_STR " character set "
+#define SPIDER_SQL_CHARACTER_SET_LEN (sizeof(SPIDER_SQL_CHARACTER_SET_STR) - 1)
#define SPIDER_SQL_COLLATE_STR " collate "
#define SPIDER_SQL_COLLATE_LEN (sizeof(SPIDER_SQL_COLLATE_STR) - 1)
#define SPIDER_SQL_COMMENT_STR " comment "
@@ -496,6 +498,12 @@ public:
const char *st,
uint len
);
+ bool append_for_single_quote(
+ const String *s
+ );
+ bool append_for_single_quote(
+ const char *st
+ );
#endif
void print(
String *print
@@ -778,6 +786,11 @@ public:
spider_string *str,
CHARSET_INFO *access_charset
) = 0;
+ virtual int fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+ ) = 0;
#endif
};
@@ -1538,6 +1551,7 @@ typedef struct st_spider_condition
typedef struct st_spider_result
{
+ uint dbton_id;
SPIDER_DB_RESULT *result;
#ifndef WITHOUT_SPIDER_BG_SEARCH
volatile
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 5f770e2b124..76c89d4138a 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -46,6 +46,7 @@
#include "spd_table.h"
extern struct charset_info_st *spd_charset_utf8_bin;
+extern bool volatile *spd_abort_loop;
extern handlerton *spider_hton_ptr;
extern pthread_mutex_t spider_open_conn_mutex;
@@ -115,6 +116,19 @@ static const char *name_quote_str = SPIDER_SQL_NAME_QUOTE_STR;
#ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE
#define SPIDER_SQL_SHOW_COLUMNS_STR "show columns from "
#define SPIDER_SQL_SHOW_COLUMNS_LEN sizeof(SPIDER_SQL_SHOW_COLUMNS_STR) - 1
+#define SPIDER_SQL_SELECT_COLUMNS_STR "select `column_name`,`column_default`,`is_nullable`,`character_set_name`,`collation_name`,`column_type`,`extra` from `information_schema`.`columns` where `table_schema` = "
+#define SPIDER_SQL_SELECT_COLUMNS_LEN sizeof(SPIDER_SQL_SELECT_COLUMNS_STR) - 1
+
+#define SPIDER_SQL_AUTO_INCREMENT_STR " auto_increment"
+#define SPIDER_SQL_AUTO_INCREMENT_LEN sizeof(SPIDER_SQL_AUTO_INCREMENT_STR) - 1
+#define SPIDER_SQL_ORDINAL_POSITION_STR "ordinal_position"
+#define SPIDER_SQL_ORDINAL_POSITION_LEN sizeof(SPIDER_SQL_ORDINAL_POSITION_STR) - 1
+#define SPIDER_SQL_FULLTEXT_STR "fulltext"
+#define SPIDER_SQL_FULLTEXT_LEN sizeof(SPIDER_SQL_FULLTEXT_STR) - 1
+#define SPIDER_SQL_SPATIAL_STR "spatial"
+#define SPIDER_SQL_SPATIAL_LEN sizeof(SPIDER_SQL_SPATIAL_STR) - 1
+#define SPIDER_SQL_USING_HASH_STR " using hash"
+#define SPIDER_SQL_USING_HASH_LEN sizeof(SPIDER_SQL_USING_HASH_STR) - 1
#endif
#define SPIDER_SQL_LIKE_STR " like "
@@ -1051,9 +1065,9 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
DBUG_PRINT("info",("spider fetch row is null"));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- if (num_fields() != 6)
+ if (num_fields() != 7)
{
- DBUG_PRINT("info",("spider num_fields != 6"));
+ DBUG_PRINT("info",("spider num_fields != 7"));
my_printf_error(ER_SPIDER_UNKNOWN_NUM, ER_SPIDER_UNKNOWN_STR, MYF(0));
DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM);
}
@@ -1073,10 +1087,28 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
}
str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
- if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset))
+ if (str->append(mysql_row[5], strlen(mysql_row[5]), access_charset))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
+ if (mysql_row[3])
+ {
+ if (str->reserve(SPIDER_SQL_CHARACTER_SET_LEN))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ str->q_append(SPIDER_SQL_CHARACTER_SET_STR, SPIDER_SQL_CHARACTER_SET_LEN);
+ str->q_append(mysql_row[3], strlen(mysql_row[3]));
+ }
+ if (mysql_row[4])
+ {
+ if (str->reserve(SPIDER_SQL_COLLATE_LEN))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ str->q_append(SPIDER_SQL_COLLATE_STR, SPIDER_SQL_COLLATE_LEN);
+ str->q_append(mysql_row[4], strlen(mysql_row[4]));
+ }
if (!strcmp(mysql_row[2], "NO"))
{
if (str->reserve(SPIDER_SQL_NOT_NULL_LEN))
@@ -1084,7 +1116,7 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_NOT_NULL_STR, SPIDER_SQL_NOT_NULL_LEN);
- if (mysql_row[4])
+ if (mysql_row[1])
{
if (str->reserve(SPIDER_SQL_DEFAULT_LEN))
{
@@ -1094,7 +1126,7 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
- if (str->append(mysql_row[4], strlen(mysql_row[4]), access_charset))
+ if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
@@ -1108,12 +1140,12 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_DEFAULT_STR, SPIDER_SQL_DEFAULT_LEN);
- if (mysql_row[4])
+ if (mysql_row[1])
{
if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
- if (str->append(mysql_row[4], strlen(mysql_row[4]), access_charset))
+ if (str->append(mysql_row[1], strlen(mysql_row[1]), access_charset))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
@@ -1128,6 +1160,12 @@ int spider_db_mysql_result::fetch_columns_for_discover_table_structure(
str->q_append(SPIDER_SQL_NULL_STR, SPIDER_SQL_NULL_LEN);
}
}
+ if (mysql_row[6] && !strcmp(mysql_row[6], "auto_increment"))
+ {
+ if (str->reserve(SPIDER_SQL_AUTO_INCREMENT_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_AUTO_INCREMENT_STR, SPIDER_SQL_AUTO_INCREMENT_LEN);
+ }
if (str->reserve(SPIDER_SQL_COMMA_LEN))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -1147,7 +1185,11 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
if (!(mysql_row = mysql_fetch_row(db_result)))
{
DBUG_PRINT("info",("spider fetch row is null"));
- DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ if (mysql_errno(db_result->handle))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ DBUG_RETURN(0);
}
if (num_fields() != 13)
{
@@ -1156,18 +1198,24 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM);
}
bool first = TRUE;
+ bool without_size = FALSE;
+ bool using_hash = FALSE;
do {
if (!strcmp(mysql_row[3], "1"))
{
+ without_size = FALSE;
if (first)
{
first = FALSE;
} else {
- if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_COMMA_LEN))
+ if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_COMMA_LEN +
+ (using_hash ? SPIDER_SQL_USING_HASH_LEN : 0)))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN);
+ if (using_hash)
+ str->q_append(SPIDER_SQL_USING_HASH_STR, SPIDER_SQL_USING_HASH_LEN);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
/* new index */
@@ -1189,6 +1237,25 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
}
str->q_append(SPIDER_DB_UNIQUE_NAME_STR, SPIDER_DB_UNIQUE_NAME_LEN);
str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
+ } else if (mysql_row[10] && !strcmp(mysql_row[10], "FULLTEXT"))
+ {
+ /* fulltext key */
+ if (str->reserve(SPIDER_SQL_FULLTEXT_LEN + SPIDER_SQL_SPACE_LEN))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ str->q_append(SPIDER_SQL_FULLTEXT_STR, SPIDER_SQL_FULLTEXT_LEN);
+ str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
+ } else if (mysql_row[10] && !strcmp(mysql_row[10], "SPATIAL"))
+ {
+ /* spatial key */
+ without_size = TRUE;
+ if (str->reserve(SPIDER_SQL_SPATIAL_LEN + SPIDER_SQL_SPACE_LEN))
+ {
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ str->q_append(SPIDER_SQL_SPATIAL_STR, SPIDER_SQL_SPATIAL_LEN);
+ str->q_append(SPIDER_SQL_SPACE_STR, SPIDER_SQL_SPACE_LEN);
}
if (str->reserve(SPIDER_DB_KEY_NAME_LEN + SPIDER_SQL_SPACE_LEN))
{
@@ -1232,7 +1299,7 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
- if (mysql_row[7])
+ if (mysql_row[7] && !without_size)
{
if (str->reserve(SPIDER_SQL_OPEN_PAREN_LEN))
{
@@ -1265,7 +1332,7 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
- if (mysql_row[7])
+ if (mysql_row[7] && !without_size)
{
if (str->reserve(SPIDER_SQL_OPEN_PAREN_LEN))
{
@@ -1283,18 +1350,58 @@ int spider_db_mysql_result::fetch_index_for_discover_table_structure(
str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN);
}
}
+ if (mysql_row[10] && !strcmp(mysql_row[10], "HASH"))
+ using_hash = TRUE;
+ else
+ using_hash = FALSE;
} while ((mysql_row = mysql_fetch_row(db_result)));
if (!first)
{
- if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_COMMA_LEN))
+ if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_COMMA_LEN +
+ (using_hash ? SPIDER_SQL_USING_HASH_LEN : 0)))
{
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN);
+ if (using_hash)
+ str->q_append(SPIDER_SQL_USING_HASH_STR, SPIDER_SQL_USING_HASH_LEN);
str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN);
}
DBUG_RETURN(0);
}
+
+int spider_db_mysql_result::fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+) {
+ MYSQL_ROW mysql_row;
+ DBUG_ENTER("spider_db_mysql_result::fetch_table_for_discover_table_structure");
+ DBUG_PRINT("info",("spider this=%p", this));
+ if (!(mysql_row = mysql_fetch_row(db_result)))
+ {
+ DBUG_PRINT("info",("spider fetch row is null"));
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+ if (num_fields() != 18)
+ {
+ DBUG_PRINT("info",("spider num_fields != 18"));
+ my_printf_error(ER_SPIDER_UNKNOWN_NUM, ER_SPIDER_UNKNOWN_STR, MYF(0));
+ DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM);
+ }
+ if (!mysql_row[14])
+ {
+ DBUG_PRINT("info",("spider mysql_row[14] is null"));
+ my_printf_error(ER_SPIDER_UNKNOWN_NUM, ER_SPIDER_UNKNOWN_STR, MYF(0));
+ DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM);
+ }
+ DBUG_PRINT("info",("spider mysql_row[14]=%s", mysql_row[14]));
+ if (!spider_share->table_share->table_charset)
+ {
+ spider_share->table_share->table_charset = get_charset_by_name(mysql_row[14], MYF(MY_WME));
+ }
+ DBUG_RETURN(0);
+}
#endif
spider_db_mysql::spider_db_mysql(
@@ -1394,6 +1501,18 @@ int spider_db_mysql::connect(
DBUG_PRINT("info",("spider this=%p", this));
while (TRUE)
{
+ THD *thd = current_thd;
+ DBUG_PRINT("info",("spider thd->killed=%s",
+ thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
+ DBUG_PRINT("info",("spider abort_loop=%s",
+ *spd_abort_loop ? "TRUE" : "FALSE"));
+ if (
+ (thd && thd->killed) ||
+ *spd_abort_loop
+ ) {
+ DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
+ }
+
if (!db_conn)
{
if (!(db_conn = mysql_init(NULL)))
@@ -1460,6 +1579,16 @@ int spider_db_mysql::connect(
pthread_mutex_unlock(&spider_open_conn_mutex);
error_num = mysql_errno(db_conn);
disconnect();
+ DBUG_PRINT("info",("spider thd->killed=%s",
+ thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
+ DBUG_PRINT("info",("spider abort_loop=%s",
+ *spd_abort_loop ? "TRUE" : "FALSE"));
+ if (
+ (thd && thd->killed) ||
+ *spd_abort_loop
+ ) {
+ DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
+ }
if (
(
error_num != CR_CONN_HOST_ERROR &&
@@ -3868,8 +3997,8 @@ int spider_db_mysql_util::append_escaped_util(
) {
DBUG_ENTER("spider_db_mysql_util::append_escaped_util");
DBUG_PRINT("info",("spider this=%p", this));
- to->get_str()->append_for_single_quote(from);
- to->mem_calc();
+ if (to->append_for_single_quote(from))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
DBUG_RETURN(0);
}
@@ -4628,22 +4757,54 @@ int spider_mysql_share::discover_table_structure(
str->length(strlen);
sql_str.length(0);
if (sql_str.reserve(
- SPIDER_SQL_SHOW_COLUMNS_LEN + db_names_str[roop_count].length() +
- SPIDER_SQL_DOT_LEN + table_names_str[roop_count].length() +
- /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 +
+ SPIDER_SQL_SELECT_COLUMNS_LEN + db_names_str[roop_count].length() +
+ SPIDER_SQL_AND_LEN + SPIDER_SQL_TABLE_NAME_LEN + SPIDER_SQL_EQUAL_LEN +
+ table_names_str[roop_count].length() + SPIDER_SQL_ORDER_LEN +
+ SPIDER_SQL_ORDINAL_POSITION_LEN +
+ /* SPIDER_SQL_VALUE_QUOTE_LEN */ 8 +
SPIDER_SQL_SEMICOLON_LEN +
SPIDER_SQL_SHOW_INDEX_LEN + db_names_str[roop_count].length() +
SPIDER_SQL_DOT_LEN + table_names_str[roop_count].length() +
+ /* SPIDER_SQL_NAME_QUOTE_LEN */ 4 +
+ SPIDER_SQL_SEMICOLON_LEN +
+ SPIDER_SQL_SHOW_TABLE_STATUS_LEN + db_names_str[roop_count].length() +
+ SPIDER_SQL_LIKE_LEN + table_names_str[roop_count].length() +
/* SPIDER_SQL_NAME_QUOTE_LEN */ 4
)) {
DBUG_PRINT("info",("spider alloc sql_str error"));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
- sql_str.q_append(SPIDER_SQL_SHOW_COLUMNS_STR, SPIDER_SQL_SHOW_COLUMNS_LEN);
- append_table_name(&sql_str, roop_count);
+ sql_str.q_append(SPIDER_SQL_SELECT_COLUMNS_STR,
+ SPIDER_SQL_SELECT_COLUMNS_LEN);
+ sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ sql_str.q_append(db_names_str[roop_count].ptr(),
+ db_names_str[roop_count].length());
+ sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ sql_str.q_append(SPIDER_SQL_AND_STR, SPIDER_SQL_AND_LEN);
+ sql_str.q_append(SPIDER_SQL_TABLE_NAME_STR, SPIDER_SQL_TABLE_NAME_LEN);
+ sql_str.q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN);
+ sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ sql_str.q_append(table_names_str[roop_count].ptr(),
+ table_names_str[roop_count].length());
+ sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ sql_str.q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN);
+ sql_str.q_append(SPIDER_SQL_ORDINAL_POSITION_STR,
+ SPIDER_SQL_ORDINAL_POSITION_LEN);
sql_str.q_append(SPIDER_SQL_SEMICOLON_STR, SPIDER_SQL_SEMICOLON_LEN);
sql_str.q_append(SPIDER_SQL_SHOW_INDEX_STR, SPIDER_SQL_SHOW_INDEX_LEN);
append_table_name(&sql_str, roop_count);
+ sql_str.q_append(SPIDER_SQL_SEMICOLON_STR, SPIDER_SQL_SEMICOLON_LEN);
+ sql_str.q_append(
+ SPIDER_SQL_SHOW_TABLE_STATUS_STR, SPIDER_SQL_SHOW_TABLE_STATUS_LEN);
+ sql_str.q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
+ sql_str.q_append(db_names_str[roop_count].ptr(),
+ db_names_str[roop_count].length());
+ sql_str.q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN);
+ sql_str.q_append(SPIDER_SQL_LIKE_STR, SPIDER_SQL_LIKE_LEN);
+ sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ sql_str.q_append(table_names_str[roop_count].ptr(),
+ table_names_str[roop_count].length());
+ sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
SPIDER_CONN *conn;
int need_mon;
@@ -4765,6 +4926,49 @@ int spider_mysql_share::discover_table_structure(
}
res->free_result();
delete res;
+ if (conn->db_conn->next_result())
+ {
+ DBUG_PRINT("info",("spider dual result error"));
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ continue;
+ }
+ /* get table info */
+ if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
+ {
+ if (error_num || (error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info",("spider table store error"));
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ continue;
+ }
+ /* no record */
+ DBUG_PRINT("info",("spider table no record error"));
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ continue;
+ }
+ if ((error_num = res->fetch_table_for_discover_table_structure(str,
+ spider_share, spider_share->access_charset)))
+ {
+ DBUG_PRINT("info",("spider table fetch error"));
+ res->free_result();
+ delete res;
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ continue;
+ }
+ res->free_result();
+ delete res;
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6037,7 +6241,23 @@ int spider_mysql_handler::append_select(
if (result_list->lock_type != F_WRLCK && spider->lock_mode < 1)
{
/* no lock */
- if (spider->share->query_cache == 1)
+ st_select_lex *select_lex = &spider->trx->thd->lex->select_lex;
+ if (
+ select_lex->sql_cache == SELECT_LEX::SQL_CACHE &&
+ (spider->share->query_cache_sync & 1)
+ ) {
+ if (str->reserve(SPIDER_SQL_SQL_CACHE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_SQL_CACHE_STR, SPIDER_SQL_SQL_CACHE_LEN);
+ } else if (
+ select_lex->sql_cache == SELECT_LEX::SQL_NO_CACHE &&
+ (spider->share->query_cache_sync & 2)
+ ) {
+ if (str->reserve(SPIDER_SQL_SQL_NO_CACHE_LEN))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ str->q_append(SPIDER_SQL_SQL_NO_CACHE_STR,
+ SPIDER_SQL_SQL_NO_CACHE_LEN);
+ } else if (spider->share->query_cache == 1)
{
if (str->reserve(SPIDER_SQL_SQL_CACHE_LEN))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -6154,7 +6374,9 @@ int spider_mysql_handler::append_minimum_select(
{
if (minimum_select_bit_is_set((*field)->field_index))
{
+/*
spider_set_bit(minimum_select_bitmap, (*field)->field_index);
+*/
field_length =
mysql_share->column_name_str[(*field)->field_index].length();
if (str->reserve(field_length +
@@ -6241,7 +6463,9 @@ int spider_mysql_handler::append_minimum_select_with_alias(
{
if (minimum_select_bit_is_set((*field)->field_index))
{
+/*
spider_set_bit(minimum_select_bitmap, (*field)->field_index);
+*/
field_length =
mysql_share->column_name_str[(*field)->field_index].length();
if (str->reserve(alias_length + field_length +
@@ -9839,6 +10063,7 @@ int spider_mysql_handler::show_table_status(
SPIDER_DB_RESULT *res;
SPIDER_SHARE *share = spider->share;
uint pos = (2 * spider->conn_link_idx[link_idx]);
+ ulonglong auto_increment_value = 0;
DBUG_ENTER("spider_mysql_handler::show_table_status");
DBUG_PRINT("info",("spider sts_mode=%d", sts_mode));
if (sts_mode == 1)
@@ -9945,7 +10170,7 @@ int spider_mysql_handler::show_table_status(
share->data_file_length,
share->max_data_file_length,
share->index_file_length,
- share->auto_increment_value,
+ auto_increment_value,
share->create_time,
share->update_time,
share->check_time
@@ -10072,7 +10297,7 @@ int spider_mysql_handler::show_table_status(
share->data_file_length,
share->max_data_file_length,
share->index_file_length,
- share->auto_increment_value,
+ auto_increment_value,
share->create_time,
share->update_time,
share->check_time
@@ -10103,6 +10328,12 @@ int spider_mysql_handler::show_table_status(
DBUG_RETURN(error_num);
}
}
+ if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value)
+ {
+ share->lgtm_tblhnd_share->auto_increment_value = auto_increment_value;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
+ }
DBUG_RETURN(0);
}
diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h
index e536e2dd214..48942d701dc 100644
--- a/storage/spider/spd_db_mysql.h
+++ b/storage/spider/spd_db_mysql.h
@@ -214,6 +214,11 @@ public:
spider_string *str,
CHARSET_INFO *access_charset
);
+ int fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+ );
#endif
};
diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc
index 9ebf42859a7..870bd849265 100644
--- a/storage/spider/spd_db_oracle.cc
+++ b/storage/spider/spd_db_oracle.cc
@@ -1075,6 +1075,16 @@ int spider_db_oracle_result::fetch_index_for_discover_table_structure(
DBUG_PRINT("info",("spider this=%p", this));
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
+
+int spider_db_oracle_result::fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+) {
+ DBUG_ENTER("spider_db_oracle_result::fetch_table_for_discover_table_structure");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+}
#endif
spider_db_oracle::spider_db_oracle(
@@ -6022,7 +6032,9 @@ int spider_oracle_handler::append_minimum_select(
{
if (minimum_select_bit_is_set((*field)->field_index))
{
+/*
spider_set_bit(minimum_select_bitmap, (*field)->field_index);
+*/
field_length =
oracle_share->column_name_str[(*field)->field_index].length();
if (str->reserve(field_length +
@@ -6109,7 +6121,9 @@ int spider_oracle_handler::append_minimum_select_with_alias(
{
if (minimum_select_bit_is_set((*field)->field_index))
{
+/*
spider_set_bit(minimum_select_bitmap, (*field)->field_index);
+*/
field_length =
oracle_share->column_name_str[(*field)->field_index].length();
if (str->reserve(alias_length + field_length +
@@ -10193,6 +10207,7 @@ int spider_oracle_handler::show_table_status(
SPIDER_DB_RESULT *res;
SPIDER_SHARE *share = spider->share;
uint pos = (2 * spider->conn_link_idx[link_idx]);
+ ulonglong auto_increment_value = 0;
DBUG_ENTER("spider_oracle_handler::show_table_status");
DBUG_PRINT("info",("spider sts_mode=%d", sts_mode));
if (
@@ -10301,7 +10316,7 @@ int spider_oracle_handler::show_table_status(
share->data_file_length,
share->max_data_file_length,
share->index_file_length,
- share->auto_increment_value,
+ auto_increment_value,
share->create_time,
share->update_time,
share->check_time
@@ -10317,9 +10332,6 @@ int spider_oracle_handler::show_table_status(
share->data_file_length = 65535;
share->max_data_file_length = 65535;
share->index_file_length = 65535;
-/*
- share->auto_increment_value = 0;
-*/
share->create_time = (time_t) 0;
share->update_time = (time_t) 0;
share->check_time = (time_t) 0;
@@ -10412,7 +10424,7 @@ int spider_oracle_handler::show_table_status(
share->data_file_length,
share->max_data_file_length,
share->index_file_length,
- share->auto_increment_value,
+ auto_increment_value,
share->create_time,
share->update_time,
share->check_time
@@ -10422,6 +10434,12 @@ int spider_oracle_handler::show_table_status(
if (error_num)
DBUG_RETURN(error_num);
}
+ if (auto_increment_value > share->lgtm_tblhnd_share->auto_increment_value)
+ {
+ share->lgtm_tblhnd_share->auto_increment_value = auto_increment_value;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
+ }
DBUG_RETURN(0);
}
@@ -10914,9 +10932,13 @@ int spider_oracle_handler::show_autoinc(
DBUG_PRINT("info", ("spider error_num=%d 7", error_num));
DBUG_RETURN(error_num);
}
- if (auto_increment_value >= share->auto_increment_value)
+ if (auto_increment_value >=
+ share->lgtm_tblhnd_share->auto_increment_value)
{
- share->auto_increment_value = auto_increment_value + 1;
+ share->lgtm_tblhnd_share->auto_increment_value =
+ auto_increment_value + 1;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
}
DBUG_RETURN(0);
}
diff --git a/storage/spider/spd_db_oracle.h b/storage/spider/spd_db_oracle.h
index 122effd4762..05bea4d33ab 100644
--- a/storage/spider/spd_db_oracle.h
+++ b/storage/spider/spd_db_oracle.h
@@ -248,6 +248,11 @@ public:
spider_string *str,
CHARSET_INFO *access_charset
);
+ int fetch_table_for_discover_table_structure(
+ spider_string *str,
+ SPIDER_SHARE *spider_share,
+ CHARSET_INFO *access_charset
+ );
#endif
/* for oracle */
int set_column_info();
diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h
index 700631f9ab0..85ceae0f54b 100644
--- a/storage/spider/spd_include.h
+++ b/storage/spider/spd_include.h
@@ -13,7 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define SPIDER_DETAIL_VERSION "3.2.0"
+#define SPIDER_DETAIL_VERSION "3.2.4"
#define SPIDER_HEX_VERSION 0x0302
#if MYSQL_VERSION_ID < 50500
@@ -47,6 +47,10 @@
#undef pthread_cond_wait
#endif
#define pthread_cond_wait mysql_cond_wait
+#ifdef pthread_cond_timedwait
+#undef pthread_cond_timedwait
+#endif
+#define pthread_cond_timedwait mysql_cond_timedwait
#ifdef pthread_cond_signal
#undef pthread_cond_signal
#endif
@@ -75,6 +79,7 @@
#define SPIDER_ALTER_REBUILD_PARTITION Alter_info::ALTER_REBUILD_PARTITION
#define SPIDER_WARN_LEVEL_WARN Sql_condition::WARN_LEVEL_WARN
#define SPIDER_WARN_LEVEL_NOTE Sql_condition::WARN_LEVEL_NOTE
+#define SPIDER_THD_KILL_CONNECTION KILL_CONNECTION
#else
#if MYSQL_VERSION_ID < 50500
#define spider_stmt_da_message(A) (A)->main_da.message()
@@ -97,6 +102,7 @@
#define SPIDER_ALTER_REBUILD_PARTITION ALTER_REBUILD_PARTITION
#define SPIDER_WARN_LEVEL_WARN MYSQL_ERROR::WARN_LEVEL_WARN
#define SPIDER_WARN_LEVEL_NOTE MYSQL_ERROR::WARN_LEVEL_NOTE
+#define SPIDER_THD_KILL_CONNECTION THD::KILL_CONNECTION
#endif
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100009
@@ -132,7 +138,7 @@
#define SPIDER_TMP_SHARE_LONG_COUNT 15
#define SPIDER_TMP_SHARE_LONGLONG_COUNT 3
-#define SPIDER_MEM_CALC_LIST_NUM 244
+#define SPIDER_MEM_CALC_LIST_NUM 246
#define SPIDER_BACKUP_DASTATUS \
bool da_status; if (thd) da_status = thd->is_error(); else da_status = FALSE;
@@ -426,6 +432,19 @@ typedef struct st_spider_conn
#endif
} SPIDER_CONN;
+typedef struct st_spider_lgtm_tblhnd_share
+{
+ char *table_name;
+ uint table_name_length;
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ my_hash_value_type table_path_hash_value;
+#endif
+ pthread_mutex_t auto_increment_mutex;
+ volatile bool auto_increment_init;
+ volatile ulonglong auto_increment_lclval;
+ ulonglong auto_increment_value;
+} SPIDER_LGTM_TBLHND_SHARE;
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
typedef struct st_spider_patition_handler_share
{
@@ -614,9 +633,12 @@ typedef struct st_spider_share
pthread_mutex_t mutex;
pthread_mutex_t sts_mutex;
pthread_mutex_t crd_mutex;
+/*
pthread_mutex_t auto_increment_mutex;
+*/
THR_LOCK lock;
TABLE_SHARE *table_share;
+ SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
#ifdef SPIDER_HAS_HASH_VALUE_TYPE
my_hash_value_type table_name_hash_value;
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -669,13 +691,18 @@ typedef struct st_spider_share
pthread_t *bg_mon_threads;
pthread_mutex_t *bg_mon_mutexes;
pthread_cond_t *bg_mon_conds;
+ pthread_cond_t *bg_mon_sleep_conds;
#endif
+/*
volatile bool auto_increment_init;
volatile ulonglong auto_increment_lclval;
+*/
ulonglong data_file_length;
ulonglong max_data_file_length;
ulonglong index_file_length;
+/*
ulonglong auto_increment_value;
+*/
ha_rows records;
ulong mean_rec_length;
time_t check_time;
@@ -721,6 +748,7 @@ typedef struct st_spider_share
int semi_table_lock_conn;
int selupd_lock_mode;
int query_cache;
+ int query_cache_sync;
int internal_delayed;
int bulk_size;
int bulk_update_mode;
diff --git a/storage/spider/spd_malloc.cc b/storage/spider/spd_malloc.cc
index e152bd8f152..57b4fb915bc 100644
--- a/storage/spider/spd_malloc.cc
+++ b/storage/spider/spd_malloc.cc
@@ -1221,7 +1221,6 @@ bool spider_string::append(
DBUG_RETURN(res);
}
-#ifdef SPIDER_HAS_APPEND_FOR_SINGLE_QUOTE
bool spider_string::append_for_single_quote(
const char *st,
uint len
@@ -1231,11 +1230,50 @@ bool spider_string::append_for_single_quote(
DBUG_ASSERT(mem_calc_inited);
DBUG_ASSERT((!current_alloc_mem && !str.is_alloced()) ||
current_alloc_mem == str.alloced_length());
+#ifdef SPIDER_HAS_APPEND_FOR_SINGLE_QUOTE
bool res = str.append_for_single_quote(st, len);
+#else
+ String ststr(st, len, str.charset());
+ bool res = append_escaped(&str, &ststr);
+#endif
+ SPIDER_STRING_CALC_MEM;
+ DBUG_RETURN(res);
+}
+
+bool spider_string::append_for_single_quote(
+ const String *s
+) {
+ DBUG_ENTER("spider_string::append_for_single_quote");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(mem_calc_inited);
+ DBUG_ASSERT((!current_alloc_mem && !str.is_alloced()) ||
+ current_alloc_mem == str.alloced_length());
+#ifdef SPIDER_HAS_APPEND_FOR_SINGLE_QUOTE
+ bool res = str.append_for_single_quote(s);
+#else
+ bool res = append_escaped(&str, s);
+#endif
SPIDER_STRING_CALC_MEM;
DBUG_RETURN(res);
}
+
+bool spider_string::append_for_single_quote(
+ const char *st
+) {
+ DBUG_ENTER("spider_string::append_for_single_quote");
+ DBUG_PRINT("info",("spider this=%p", this));
+ DBUG_ASSERT(mem_calc_inited);
+ DBUG_ASSERT((!current_alloc_mem && !str.is_alloced()) ||
+ current_alloc_mem == str.alloced_length());
+#ifdef SPIDER_HAS_APPEND_FOR_SINGLE_QUOTE
+ bool res = str.append_for_single_quote(st);
+#else
+ String ststr(st, str.charset());
+ bool res = append_escaped(&str, &ststr);
#endif
+ SPIDER_STRING_CALC_MEM;
+ DBUG_RETURN(res);
+}
void spider_string::swap(
spider_string &s
diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc
index 193b60271c2..d32dbec2421 100644
--- a/storage/spider/spd_ping_table.cc
+++ b/storage/spider/spd_ping_table.cc
@@ -40,6 +40,8 @@
#include "spd_udf.h"
#include "spd_malloc.h"
+extern bool volatile *spd_abort_loop;
+
extern handlerton *spider_hton_ptr;
#ifdef HAVE_PSI_INTERFACE
@@ -1273,6 +1275,16 @@ int spider_ping_table_mon_from_table(
ER_SPIDER_MON_AT_ALTER_TABLE_STR, MYF(0));
DBUG_RETURN(ER_SPIDER_MON_AT_ALTER_TABLE_NUM);
}
+ DBUG_PRINT("info",("spider thd->killed=%s",
+ thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
+ DBUG_PRINT("info",("spider abort_loop=%s",
+ *spd_abort_loop ? "TRUE" : "FALSE"));
+ if (
+ (thd && thd->killed) ||
+ *spd_abort_loop
+ ) {
+ DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
+ }
link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d",
link_idx));
@@ -1325,126 +1337,158 @@ int spider_ping_table_mon_from_table(
current_mon_count = 1;
while (TRUE)
{
- if (!table_mon)
- table_mon = table_mon_list->first;
+ DBUG_PRINT("info",("spider thd->killed=%s",
+ thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
+ DBUG_PRINT("info",("spider abort_loop=%s",
+ *spd_abort_loop ? "TRUE" : "FALSE"));
if (
- current_mon_count > table_mon_list->list_size ||
- (current_mon_count > 1 && table_mon->server_id == first_sid)
+ (thd && thd->killed) ||
+ *spd_abort_loop
) {
- table_mon_list->last_caller_result = SPIDER_LINK_MON_DRAW_FEW_MON;
- mon_table_result.result_status = SPIDER_LINK_MON_DRAW_FEW_MON;
- DBUG_PRINT("info",(
- "spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW_FEW_MON 1"));
- error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
+ error_num = ER_SPIDER_COND_SKIP_NUM;
break;
- }
- thd->clear_error();
- if ((mon_conn = spider_get_ping_table_tgt_conn(trx,
- table_mon->share, &error_num))
- ) {
- if (!spider_db_udf_ping_table_mon_next(
- thd, table_mon, mon_conn, &mon_table_result, conv_name,
- conv_name_length, link_idx,
- where_clause, where_clause_length, -1, table_mon_list->list_size,
- 0, 0, 0, flags, monitoring_limit))
+ } else {
+ if (!table_mon)
+ table_mon = table_mon_list->first;
+ if (
+ current_mon_count > table_mon_list->list_size ||
+ (current_mon_count > 1 && table_mon->server_id == first_sid)
+ ) {
+ table_mon_list->last_caller_result = SPIDER_LINK_MON_DRAW_FEW_MON;
+ mon_table_result.result_status = SPIDER_LINK_MON_DRAW_FEW_MON;
+ DBUG_PRINT("info",(
+ "spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW_FEW_MON 1"));
+ error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
+ }
+ int prev_error = 0;
+ char prev_error_msg[MYSQL_ERRMSG_SIZE];
+ if (thd->is_error())
{
- if (
- mon_table_result.result_status == SPIDER_LINK_MON_NG &&
- table_mon_list->mon_status != SPIDER_LINK_MON_NG
- ) {
- pthread_mutex_lock(&table_mon_list->update_status_mutex);
- if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
+ prev_error = spider_stmt_da_sql_errno(thd);
+ strmov(prev_error_msg, spider_stmt_da_message(thd));
+ thd->clear_error();
+ }
+ if ((mon_conn = spider_get_ping_table_tgt_conn(trx,
+ table_mon->share, &error_num))
+ ) {
+ if (!spider_db_udf_ping_table_mon_next(
+ thd, table_mon, mon_conn, &mon_table_result, conv_name,
+ conv_name_length, link_idx,
+ where_clause, where_clause_length, -1, table_mon_list->list_size,
+ 0, 0, 0, flags, monitoring_limit))
+ {
+ if (
+ mon_table_result.result_status == SPIDER_LINK_MON_NG &&
+ table_mon_list->mon_status != SPIDER_LINK_MON_NG
+ ) {
+ pthread_mutex_lock(&table_mon_list->update_status_mutex);
+ if (table_mon_list->mon_status != SPIDER_LINK_MON_NG)
+ {
+ table_mon_list->mon_status = SPIDER_LINK_MON_NG;
+ table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG;
+ DBUG_PRINT("info", (
+ "spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG",
+ link_idx));
+ share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG;
+ spider_sys_update_tables_link_status(thd, conv_name,
+ conv_name_length, link_idx, SPIDER_LINK_STATUS_NG, need_lock);
+ spider_sys_log_tables_link_failed(thd, conv_name,
+ conv_name_length, link_idx, need_lock);
+ }
+ pthread_mutex_unlock(&table_mon_list->update_status_mutex);
+ }
+ table_mon_list->last_caller_result = mon_table_result.result_status;
+ if (mon_table_result.result_status == SPIDER_LINK_MON_OK)
{
- table_mon_list->mon_status = SPIDER_LINK_MON_NG;
- table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG;
- DBUG_PRINT("info", (
- "spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG",
- link_idx));
- share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG;
- spider_sys_update_tables_link_status(thd, conv_name,
- conv_name_length, link_idx, SPIDER_LINK_STATUS_NG, need_lock);
- spider_sys_log_tables_link_failed(thd, conv_name,
- conv_name_length, link_idx, need_lock);
+ if (prev_error)
+ my_message(prev_error, prev_error_msg, MYF(0));
+ error_num = ER_SPIDER_LINK_MON_OK_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_OK_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
}
- pthread_mutex_unlock(&table_mon_list->update_status_mutex);
- }
- table_mon_list->last_caller_result = mon_table_result.result_status;
- if (mon_table_result.result_status == SPIDER_LINK_MON_OK)
- {
- error_num = ER_SPIDER_LINK_MON_OK_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_OK_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
- break;
- }
- if (mon_table_result.result_status == SPIDER_LINK_MON_NG)
- {
- error_num = ER_SPIDER_LINK_MON_NG_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_NG_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
- break;
- }
- if (mon_table_result.result_status ==
- SPIDER_LINK_MON_DRAW_FEW_MON)
- {
- error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
+ if (mon_table_result.result_status == SPIDER_LINK_MON_NG)
+ {
+ error_num = ER_SPIDER_LINK_MON_NG_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_NG_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
+ }
+ if (mon_table_result.result_status ==
+ SPIDER_LINK_MON_DRAW_FEW_MON)
+ {
+ error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
+ }
+ error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
my_printf_error(error_num,
- ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
+ ER_SPIDER_LINK_MON_DRAW_STR, MYF(0),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
}
+ }
+ table_mon = table_mon->next;
+ current_mon_count++;
+ }
+ }
+ pthread_mutex_unlock(&table_mon_list->caller_mutex);
+ } else {
+ pthread_mutex_lock(&table_mon_list->caller_mutex);
+ DBUG_PRINT("info",("spider thd->killed=%s",
+ thd ? (thd->killed ? "TRUE" : "FALSE") : "NULL"));
+ DBUG_PRINT("info",("spider abort_loop=%s",
+ *spd_abort_loop ? "TRUE" : "FALSE"));
+ if (
+ (thd && thd->killed) ||
+ *spd_abort_loop
+ ) {
+ error_num = ER_SPIDER_COND_SKIP_NUM;
+ } else {
+ switch (table_mon_list->last_caller_result)
+ {
+ case SPIDER_LINK_MON_OK:
+ error_num = ER_SPIDER_LINK_MON_OK_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_OK_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
+ case SPIDER_LINK_MON_NG:
+ error_num = ER_SPIDER_LINK_MON_NG_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_NG_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
+ case SPIDER_LINK_MON_DRAW_FEW_MON:
+ error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
+ my_printf_error(error_num,
+ ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
+ table_mon_list->share->tgt_dbs[0],
+ table_mon_list->share->tgt_table_names[0]);
+ break;
+ default:
error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
my_printf_error(error_num,
ER_SPIDER_LINK_MON_DRAW_STR, MYF(0),
table_mon_list->share->tgt_dbs[0],
table_mon_list->share->tgt_table_names[0]);
break;
- }
}
- table_mon = table_mon->next;
- current_mon_count++;
- }
- pthread_mutex_unlock(&table_mon_list->caller_mutex);
- } else {
- pthread_mutex_lock(&table_mon_list->caller_mutex);
- switch (table_mon_list->last_caller_result)
- {
- case SPIDER_LINK_MON_OK:
- error_num = ER_SPIDER_LINK_MON_OK_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_OK_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
- break;
- case SPIDER_LINK_MON_NG:
- error_num = ER_SPIDER_LINK_MON_NG_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_NG_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
- break;
- case SPIDER_LINK_MON_DRAW_FEW_MON:
- error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
- break;
- default:
- error_num = ER_SPIDER_LINK_MON_DRAW_NUM;
- my_printf_error(error_num,
- ER_SPIDER_LINK_MON_DRAW_STR, MYF(0),
- table_mon_list->share->tgt_dbs[0],
- table_mon_list->share->tgt_table_names[0]);
- break;
}
pthread_mutex_unlock(&table_mon_list->caller_mutex);
}
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index ff7e7dbfb11..2eb852e61a8 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -51,6 +51,7 @@ HASH *spd_db_att_xid_cache;
struct charset_info_st *spd_charset_utf8_bin;
const char **spd_defaults_extra_file;
const char **spd_defaults_file;
+bool volatile *spd_abort_loop;
handlerton *spider_hton_ptr;
SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
@@ -68,6 +69,7 @@ PSI_mutex_key spd_key_mutex_init_error_tbl;
#ifdef WITH_PARTITION_STORAGE_ENGINE
PSI_mutex_key spd_key_mutex_pt_share;
#endif
+PSI_mutex_key spd_key_mutex_lgtm_tblhnd_share;
PSI_mutex_key spd_key_mutex_conn;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
PSI_mutex_key spd_key_mutex_hs_r_conn;
@@ -114,6 +116,7 @@ static PSI_mutex_info all_spider_mutexes[]=
#ifdef WITH_PARTITION_STORAGE_ENGINE
{ &spd_key_mutex_pt_share, "pt_share", PSI_FLAG_GLOBAL},
#endif
+ { &spd_key_mutex_lgtm_tblhnd_share, "lgtm_tblhnd_share", PSI_FLAG_GLOBAL},
{ &spd_key_mutex_conn, "conn", PSI_FLAG_GLOBAL},
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
{ &spd_key_mutex_hs_r_conn, "hs_r_conn", PSI_FLAG_GLOBAL},
@@ -162,6 +165,7 @@ PSI_cond_key spd_key_cond_bg_sts_sync;
PSI_cond_key spd_key_cond_bg_crd;
PSI_cond_key spd_key_cond_bg_crd_sync;
PSI_cond_key spd_key_cond_bg_mon;
+PSI_cond_key spd_key_cond_bg_mon_sleep;
PSI_cond_key spd_key_cond_bg_direct_sql;
#endif
PSI_cond_key spd_key_cond_udf_table_mon;
@@ -175,6 +179,7 @@ static PSI_cond_info all_spider_conds[] = {
{&spd_key_cond_bg_crd, "bg_crd", 0},
{&spd_key_cond_bg_crd_sync, "bg_crd_sync", 0},
{&spd_key_cond_bg_mon, "bg_mon", 0},
+ {&spd_key_cond_bg_mon_sleep, "bg_mon_sleep", 0},
{&spd_key_cond_bg_direct_sql, "bg_direct_sql", 0},
#endif
{&spd_key_cond_udf_table_mon, "udf_table_mon", 0},
@@ -257,6 +262,13 @@ ulong spider_open_pt_share_line_no;
pthread_mutex_t spider_pt_share_mutex;
#endif
+HASH spider_lgtm_tblhnd_share_hash;
+uint spider_lgtm_tblhnd_share_hash_id;
+const char *spider_lgtm_tblhnd_share_hash_func_name;
+const char *spider_lgtm_tblhnd_share_hash_file_name;
+ulong spider_lgtm_tblhnd_share_hash_line_no;
+pthread_mutex_t spider_lgtm_tblhnd_share_mutex;
+
HASH spider_allocated_thds;
uint spider_allocated_thds_id;
const char *spider_allocated_thds_func_name;
@@ -317,6 +329,16 @@ uchar *spider_pt_handler_share_get_key(
}
#endif
+uchar *spider_lgtm_tblhnd_share_hash_get_key(
+ SPIDER_LGTM_TBLHND_SHARE *share,
+ size_t *length,
+ my_bool not_used __attribute__ ((unused))
+) {
+ DBUG_ENTER("spider_lgtm_tblhnd_share_hash_get_key");
+ *length = share->table_name_length;
+ DBUG_RETURN((uchar*) share->table_name);
+}
+
uchar *spider_link_get_key(
SPIDER_LINK_FOR_HASH *link_for_hash,
size_t *length,
@@ -1748,6 +1770,7 @@ int spider_parse_connect_info(
share->semi_table_lock_conn = -1;
share->selupd_lock_mode = -1;
share->query_cache = -1;
+ share->query_cache_sync = -1;
share->internal_delayed = -1;
share->bulk_size = -1;
share->bulk_update_mode = -1;
@@ -1983,6 +2006,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_STR_LIST("pkn", tgt_pk_names);
SPIDER_PARAM_LONGLONG("prt", priority, 0);
SPIDER_PARAM_INT_WITH_MAX("qch", query_cache, 0, 2);
+ SPIDER_PARAM_INT_WITH_MAX("qcs", query_cache_sync, 0, 3);
SPIDER_PARAM_INT_WITH_MAX("qmd", quick_mode, 0, 3);
SPIDER_PARAM_LONGLONG("qps", quick_page_size, 0);
SPIDER_PARAM_INT_WITH_MAX("rom", read_only_mode, 0, 1);
@@ -2015,7 +2039,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX("stl", semi_table_lock, 0, 1);
SPIDER_PARAM_LONG_LIST_WITH_MAX("svc", tgt_ssl_vscs, 0, 1);
SPIDER_PARAM_STR_LIST("tbl", tgt_table_names);
- SPIDER_PARAM_INT_WITH_MAX("tcm", table_count_mode, 0, 1);
+ SPIDER_PARAM_INT_WITH_MAX("tcm", table_count_mode, 0, 3);
SPIDER_PARAM_LONG_LIST_WITH_MAX("uhd", use_handlers, 0, 3);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
SPIDER_PARAM_LONG_LIST_WITH_MAX(
@@ -2191,7 +2215,7 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX(
"internal_delayed", internal_delayed, 0, 1);
SPIDER_PARAM_INT_WITH_MAX(
- "table_count_mode", table_count_mode, 0, 1);
+ "table_count_mode", table_count_mode, 0, 3);
SPIDER_PARAM_INT_WITH_MAX(
"use_pushdown_udf", use_pushdown_udf, 0, 1);
SPIDER_PARAM_LONGLONG_LIST_WITH_MAX(
@@ -2211,6 +2235,8 @@ int spider_parse_connect_info(
SPIDER_PARAM_INT_WITH_MAX(
"bulk_access_free", bulk_access_free, 0, 1);
#endif
+ SPIDER_PARAM_INT_WITH_MAX(
+ "query_cache_sync", query_cache_sync, 0, 3);
error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
MYF(0), tmp_ptr);
@@ -3367,6 +3393,8 @@ int spider_set_connect_info_default(
share->selupd_lock_mode = 1;
if (share->query_cache == -1)
share->query_cache = 0;
+ if (share->query_cache_sync == -1)
+ share->query_cache_sync = 0;
if (share->internal_delayed == -1)
share->internal_delayed = 0;
if (share->bulk_size == -1)
@@ -3991,7 +4019,7 @@ SPIDER_SHARE *spider_create_share(
use_table_charset = spider_param_use_table_charset(
share->use_table_charset);
- if (use_table_charset)
+ if (table_share->table_charset && use_table_charset)
share->access_charset = table_share->table_charset;
else
share->access_charset = system_charset_info;
@@ -3999,8 +4027,10 @@ SPIDER_SHARE *spider_create_share(
if ((*error_num = spider_create_conn_keys(share)))
goto error_create_conn_keys;
- if (share->table_count_mode)
+ if (share->table_count_mode & 1)
share->additional_table_flags |= HA_STATS_RECORDS_IS_EXACT;
+ if (share->table_count_mode & 2)
+ share->additional_table_flags |= HA_HAS_RECORDS;
#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST))
@@ -4035,19 +4065,20 @@ SPIDER_SHARE *spider_create_share(
goto error_init_crd_mutex;
}
-#if MYSQL_VERSION_ID < 50500
- if (pthread_mutex_init(&share->auto_increment_mutex, MY_MUTEX_INIT_FAST))
+ thr_lock_init(&share->lock);
+
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ if (!(share->lgtm_tblhnd_share =
+ spider_get_lgtm_tblhnd_share(tmp_name, length, hash_value, FALSE, TRUE,
+ error_num)))
#else
- if (mysql_mutex_init(spd_key_mutex_share_auto_increment,
- &share->auto_increment_mutex, MY_MUTEX_INIT_FAST))
+ if (!(share->lgtm_tblhnd_share =
+ spider_get_lgtm_tblhnd_share(tmp_name, length, FALSE, TRUE, error_num)))
#endif
{
- *error_num = HA_ERR_OUT_OF_MEM;
- goto error_init_auto_increment_mutex;
+ goto error_get_lgtm_tblhnd_share;
}
- thr_lock_init(&share->lock);
-
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (!(share->partition_share =
spider_get_pt_share(share, table_share, error_num)))
@@ -4085,11 +4116,11 @@ error_init_dbton:
}
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
+ spider_free_pt_share(share->partition_share);
error_get_pt_share:
#endif
+error_get_lgtm_tblhnd_share:
thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->auto_increment_mutex);
-error_init_auto_increment_mutex:
pthread_mutex_destroy(&share->crd_mutex);
error_init_crd_mutex:
pthread_mutex_destroy(&share->sts_mutex);
@@ -5104,7 +5135,6 @@ void spider_free_share_resource_only(
DBUG_ENTER("spider_free_share_resource_only");
spider_free_share_alloc(share);
thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->auto_increment_mutex);
pthread_mutex_destroy(&share->crd_mutex);
pthread_mutex_destroy(&share->sts_mutex);
pthread_mutex_destroy(&share->mutex);
@@ -5132,7 +5162,6 @@ int spider_free_share(
my_hash_delete(&spider_open_tables, (uchar*) share);
#endif
thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->auto_increment_mutex);
pthread_mutex_destroy(&share->crd_mutex);
pthread_mutex_destroy(&share->sts_mutex);
pthread_mutex_destroy(&share->mutex);
@@ -5142,6 +5171,129 @@ int spider_free_share(
DBUG_RETURN(0);
}
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+SPIDER_LGTM_TBLHND_SHARE *spider_get_lgtm_tblhnd_share(
+ const char *table_name,
+ uint table_name_length,
+ my_hash_value_type hash_value,
+ bool locked,
+ bool need_to_create,
+ int *error_num
+)
+#else
+SPIDER_LGTM_TBLHND_SHARE *spider_get_lgtm_tblhnd_share(
+ const char *table_name,
+ uint table_name_length,
+ bool locked,
+ bool need_to_create,
+ int *error_num
+)
+#endif
+{
+ SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
+ char *tmp_name;
+ DBUG_ENTER("spider_get_lgtm_tblhnd_share");
+
+ if (!locked)
+ pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ if (!(lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE*)
+ my_hash_search_using_hash_value(
+ &spider_lgtm_tblhnd_share_hash, hash_value,
+ (uchar*) table_name, table_name_length)))
+#else
+ if (!(lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE*) my_hash_search(
+ &spider_lgtm_tblhnd_share_hash,
+ (uchar*) table_name, table_name_length)))
+#endif
+ {
+ DBUG_PRINT("info",("spider create new lgtm tblhnd share"));
+ if (!(lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE *)
+ spider_bulk_malloc(spider_current_trx, 244, MYF(MY_WME | MY_ZEROFILL),
+ &lgtm_tblhnd_share, sizeof(*lgtm_tblhnd_share),
+ &tmp_name, table_name_length + 1,
+ NullS))
+ ) {
+ *error_num = HA_ERR_OUT_OF_MEM;
+ goto error_alloc_share;
+ }
+
+ lgtm_tblhnd_share->table_name_length = table_name_length;
+ lgtm_tblhnd_share->table_name = tmp_name;
+ memcpy(lgtm_tblhnd_share->table_name, table_name,
+ lgtm_tblhnd_share->table_name_length);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+ lgtm_tblhnd_share->table_path_hash_value = hash_value;
+#endif
+
+#if MYSQL_VERSION_ID < 50500
+ if (pthread_mutex_init(&lgtm_tblhnd_share->auto_increment_mutex,
+ MY_MUTEX_INIT_FAST))
+#else
+ if (mysql_mutex_init(spd_key_mutex_share_auto_increment,
+ &lgtm_tblhnd_share->auto_increment_mutex, MY_MUTEX_INIT_FAST))
+#endif
+ {
+ *error_num = HA_ERR_OUT_OF_MEM;
+ goto error_init_auto_increment_mutex;
+ }
+
+ uint old_elements = spider_lgtm_tblhnd_share_hash.array.max_element;
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ if (my_hash_insert_with_hash_value(&spider_lgtm_tblhnd_share_hash,
+ hash_value, (uchar*) lgtm_tblhnd_share))
+#else
+ if (my_hash_insert(&spider_lgtm_tblhnd_share_hash,
+ (uchar*) lgtm_tblhnd_share))
+#endif
+ {
+ *error_num = HA_ERR_OUT_OF_MEM;
+ goto error_hash_insert;
+ }
+ if (spider_lgtm_tblhnd_share_hash.array.max_element > old_elements)
+ {
+ spider_alloc_calc_mem(spider_current_trx,
+ spider_lgtm_tblhnd_share_hash,
+ (spider_lgtm_tblhnd_share_hash.array.max_element - old_elements) *
+ spider_lgtm_tblhnd_share_hash.array.size_of_element);
+ }
+ }
+ if (!locked)
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
+
+ DBUG_PRINT("info",("spider lgtm_tblhnd_share=%p", lgtm_tblhnd_share));
+ DBUG_RETURN(lgtm_tblhnd_share);
+
+error_hash_insert:
+ pthread_mutex_destroy(&lgtm_tblhnd_share->auto_increment_mutex);
+error_init_auto_increment_mutex:
+ spider_free(spider_current_trx, lgtm_tblhnd_share, MYF(0));
+error_alloc_share:
+ if (!locked)
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
+ DBUG_RETURN(NULL);
+}
+
+void spider_free_lgtm_tblhnd_share_alloc(
+ SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share,
+ bool locked
+) {
+ DBUG_ENTER("spider_free_lgtm_tblhnd_share");
+ if (!locked)
+ pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
+#ifdef HASH_UPDATE_WITH_HASH_VALUE
+ my_hash_delete_with_hash_value(&spider_lgtm_tblhnd_share_hash,
+ lgtm_tblhnd_share->table_path_hash_value, (uchar*) lgtm_tblhnd_share);
+#else
+ my_hash_delete(&spider_lgtm_tblhnd_share_hash, (uchar*) lgtm_tblhnd_share);
+#endif
+ pthread_mutex_destroy(&lgtm_tblhnd_share->auto_increment_mutex);
+ spider_free(spider_current_trx, lgtm_tblhnd_share, MYF(0));
+ if (!locked)
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
+ DBUG_VOID_RETURN;
+}
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
SPIDER_PARTITION_SHARE *spider_get_pt_share(
SPIDER_SHARE *share,
@@ -5321,7 +5473,8 @@ void spider_copy_sts_to_pt_share(
partition_share->data_file_length = share->data_file_length;
partition_share->max_data_file_length = share->max_data_file_length;
partition_share->index_file_length = share->index_file_length;
- partition_share->auto_increment_value = share->auto_increment_value;
+ partition_share->auto_increment_value =
+ share->lgtm_tblhnd_share->auto_increment_value;
partition_share->records = share->records;
partition_share->mean_rec_length = share->mean_rec_length;
partition_share->check_time = share->check_time;
@@ -5343,7 +5496,10 @@ void spider_copy_sts_to_share(
share->data_file_length = partition_share->data_file_length;
share->max_data_file_length = partition_share->max_data_file_length;
share->index_file_length = partition_share->index_file_length;
- share->auto_increment_value = partition_share->auto_increment_value;
+ share->lgtm_tblhnd_share->auto_increment_value =
+ partition_share->auto_increment_value;
+ DBUG_PRINT("info",("spider auto_increment_value=%llu",
+ share->lgtm_tblhnd_share->auto_increment_value));
share->records = partition_share->records;
share->mean_rec_length = partition_share->mean_rec_length;
share->check_time = partition_share->check_time;
@@ -5758,6 +5914,7 @@ int spider_db_done(
SPIDER_CONN *conn;
SPIDER_INIT_ERROR_TABLE *spider_init_error_table;
SPIDER_TABLE_MON_LIST *table_mon_list;
+ SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share;
DBUG_ENTER("spider_db_done");
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -5855,6 +6012,13 @@ int spider_db_done(
spider_free_conn(conn);
}
pthread_mutex_unlock(&spider_conn_mutex);
+ pthread_mutex_lock(&spider_lgtm_tblhnd_share_mutex);
+ while ((lgtm_tblhnd_share = (SPIDER_LGTM_TBLHND_SHARE*) my_hash_element(
+ &spider_lgtm_tblhnd_share_hash, 0)))
+ {
+ spider_free_lgtm_tblhnd_share_alloc(lgtm_tblhnd_share, TRUE);
+ }
+ pthread_mutex_unlock(&spider_lgtm_tblhnd_share_mutex);
spider_free_mem_calc(spider_current_trx,
spider_mon_table_cache_id,
spider_mon_table_cache.max_element *
@@ -5882,6 +6046,11 @@ int spider_db_done(
spider_open_connections.array.max_element *
spider_open_connections.array.size_of_element);
my_hash_free(&spider_open_connections);
+ spider_free_mem_calc(spider_current_trx,
+ spider_lgtm_tblhnd_share_hash_id,
+ spider_lgtm_tblhnd_share_hash.array.max_element *
+ spider_lgtm_tblhnd_share_hash.array.size_of_element);
+ my_hash_free(&spider_lgtm_tblhnd_share_hash);
#ifdef WITH_PARTITION_STORAGE_ENGINE
spider_free_mem_calc(spider_current_trx,
spider_open_pt_share_id,
@@ -5926,6 +6095,7 @@ int spider_db_done(
pthread_mutex_destroy(&spider_hs_r_conn_mutex);
#endif
pthread_mutex_destroy(&spider_conn_mutex);
+ pthread_mutex_destroy(&spider_lgtm_tblhnd_share_mutex);
#ifdef WITH_PARTITION_STORAGE_ENGINE
pthread_mutex_destroy(&spider_pt_share_mutex);
#endif
@@ -6046,6 +6216,8 @@ int spider_db_init(
GetProcAddress(current_module, "my_defaults_extra_file");
spd_defaults_file = (const char **)
GetProcAddress(current_module, "my_defaults_file");
+ spd_abort_loop = (bool volatile *)
+ GetProcAddress(current_module, "?abort_loop@@3_NC");
#else
spd_db_att_thread_id = &thread_id;
#ifdef XID_CACHE_IS_SPLITTED
@@ -6059,6 +6231,7 @@ int spider_db_init(
spd_charset_utf8_bin = &my_charset_utf8_bin;
spd_defaults_extra_file = &my_defaults_extra_file;
spd_defaults_file = &my_defaults_file;
+ spd_abort_loop = &abort_loop;
#endif
#ifdef HAVE_PSI_INTERFACE
@@ -6133,6 +6306,16 @@ int spider_db_init(
}
#endif
#if MYSQL_VERSION_ID < 50500
+ if (pthread_mutex_init(&spider_lgtm_tblhnd_share_mutex, MY_MUTEX_INIT_FAST))
+#else
+ if (mysql_mutex_init(spd_key_mutex_lgtm_tblhnd_share,
+ &spider_lgtm_tblhnd_share_mutex, MY_MUTEX_INIT_FAST))
+#endif
+ {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_lgtm_tblhnd_share_mutex_init;
+ }
+#if MYSQL_VERSION_ID < 50500
if (pthread_mutex_init(&spider_conn_mutex, MY_MUTEX_INIT_FAST))
#else
if (mysql_mutex_init(spd_key_mutex_conn,
@@ -6257,6 +6440,19 @@ int spider_db_init(
spider_open_pt_share.array.size_of_element);
#endif
if(
+ my_hash_init(&spider_lgtm_tblhnd_share_hash, spd_charset_utf8_bin,
+ 32, 0, 0,
+ (my_hash_get_key) spider_lgtm_tblhnd_share_hash_get_key, 0, 0)
+ ) {
+ error_num = HA_ERR_OUT_OF_MEM;
+ goto error_lgtm_tblhnd_share_hash_init;
+ }
+ spider_alloc_calc_mem_init(spider_lgtm_tblhnd_share_hash, 245);
+ spider_alloc_calc_mem(NULL,
+ spider_lgtm_tblhnd_share_hash,
+ spider_lgtm_tblhnd_share_hash.array.max_element *
+ spider_lgtm_tblhnd_share_hash.array.size_of_element);
+ if(
my_hash_init(&spider_open_connections, spd_charset_utf8_bin, 32, 0, 0,
(my_hash_get_key) spider_conn_get_key, 0, 0)
) {
@@ -6476,6 +6672,12 @@ error_hs_r_conn_hash_init:
spider_open_connections.array.size_of_element);
my_hash_free(&spider_open_connections);
error_open_connections_hash_init:
+ spider_free_mem_calc(NULL,
+ spider_lgtm_tblhnd_share_hash_id,
+ spider_lgtm_tblhnd_share_hash.array.max_element *
+ spider_lgtm_tblhnd_share_hash.array.size_of_element);
+ my_hash_free(&spider_lgtm_tblhnd_share_hash);
+error_lgtm_tblhnd_share_hash_init:
#ifdef WITH_PARTITION_STORAGE_ENGINE
spider_free_mem_calc(NULL,
spider_open_pt_share_id,
@@ -6516,6 +6718,8 @@ error_global_trx_mutex_init:
#endif
pthread_mutex_destroy(&spider_conn_mutex);
error_conn_mutex_init:
+ pthread_mutex_destroy(&spider_lgtm_tblhnd_share_mutex);
+error_lgtm_tblhnd_share_mutex_init:
#ifdef WITH_PARTITION_STORAGE_ENGINE
pthread_mutex_destroy(&spider_pt_share_mutex);
error_pt_share_mutex_init:
@@ -7634,6 +7838,8 @@ bool spider_check_direct_order_limit(
DBUG_ENTER("spider_check_direct_order_limit");
DBUG_PRINT("info",("spider SQLCOM_HA_READ=%s",
(spider->sql_command == SQLCOM_HA_READ) ? "TRUE" : "FALSE"));
+ DBUG_PRINT("info",("spider sql_kinds with SPIDER_SQL_KIND_HANDLER=%s",
+ (spider->sql_kinds & SPIDER_SQL_KIND_HANDLER) ? "TRUE" : "FALSE"));
DBUG_PRINT("info",("spider has_clone_for_merge=%s",
spider->has_clone_for_merge ? "TRUE" : "FALSE"));
DBUG_PRINT("info",("spider is_clone=%s",
@@ -7653,6 +7859,11 @@ bool spider_check_direct_order_limit(
) {
spider_get_select_limit(spider, &select_lex, &select_limit, &offset_limit);
bool first_check = TRUE;
+ DBUG_PRINT("info",("spider select_lex=%p", select_lex));
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
+ DBUG_PRINT("info",("spider leaf_tables.elements=%u",
+ select_lex->leaf_tables.elements));
+#endif
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
spider->result_list.direct_aggregate = TRUE;
#endif
@@ -7666,6 +7877,9 @@ bool spider_check_direct_order_limit(
OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) ||
#endif
!select_lex ||
+#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
+ select_lex->leaf_tables.elements != 1 ||
+#endif
select_lex->table_list.elements != 1
) {
DBUG_PRINT("info",("spider first_check is FALSE"));
@@ -7685,6 +7899,10 @@ bool spider_check_direct_order_limit(
) {
DBUG_PRINT("info",("spider this SQL is not aggregate SQL"));
spider->result_list.direct_aggregate = FALSE;
+ } else if (spider->sql_kinds & SPIDER_SQL_KIND_HANDLER)
+ {
+ DBUG_PRINT("info",("spider sql_kinds with SPIDER_SQL_KIND_HANDLER"));
+ spider->result_list.direct_aggregate = FALSE;
} else {
ORDER *group;
for (group = (ORDER *) select_lex->group_list.first; group;
@@ -7846,8 +8064,8 @@ int spider_discover_table_structure_internal(
SPIDER_SHARE *spider_share,
spider_string *str
) {
- int error_num, roop_count;
- DBUG_ENTER("spider_discover_table_structure");
+ int error_num = 0, roop_count;
+ DBUG_ENTER("spider_discover_table_structure_internal");
for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++)
{
if (spider_bit_is_set(spider_share->dbton_bitmap, roop_count))
@@ -7855,11 +8073,12 @@ int spider_discover_table_structure_internal(
if ((error_num = spider_share->dbton_share[roop_count]->
discover_table_structure(trx, spider_share, str)))
{
- DBUG_RETURN(error_num);
+ continue;
}
+ break;
}
}
- DBUG_RETURN(0);
+ DBUG_RETURN(error_num);
}
int spider_discover_table_structure(
@@ -7929,6 +8148,22 @@ int spider_discover_table_structure(
error_num = spider_discover_table_structure_internal(trx, spider_share, &str);
+ if (!error_num)
+ {
+ Open_tables_backup open_tables_backup;
+ TABLE *table_tables;
+ if (
+ (table_tables = spider_open_sys_table(
+ thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
+ SPIDER_SYS_TABLES_TABLE_NAME_LEN, TRUE, &open_tables_backup, FALSE,
+ &error_num))
+ ) {
+ error_num = spider_insert_tables(table_tables, spider_share);
+ spider_close_sys_table(thd, table_tables,
+ &open_tables_backup, FALSE);
+ }
+ }
+
spider_free_share_resource_only(spider_share);
#ifdef WITH_PARTITION_STORAGE_ENGINE
} else {
@@ -7998,8 +8233,15 @@ int spider_discover_table_structure(
DBUG_RETURN(error_num);
str.length(str.length() - SPIDER_SQL_COMMA_LEN);
- uint csnamelen = strlen(share->table_charset->csname);
- uint collatelen = strlen(share->table_charset->name);
+ CHARSET_INFO *table_charset;
+ if (share->table_charset)
+ {
+ table_charset = share->table_charset;
+ } else {
+ table_charset = system_charset_info;
+ }
+ uint csnamelen = strlen(table_charset->csname);
+ uint collatelen = strlen(table_charset->name);
if (str.reserve(SPIDER_SQL_CLOSE_PAREN_LEN + SPIDER_SQL_DEFAULT_CHARSET_LEN +
csnamelen + SPIDER_SQL_COLLATE_LEN + collatelen +
SPIDER_SQL_CONNECTION_LEN + SPIDER_SQL_VALUE_QUOTE_LEN
@@ -8008,9 +8250,9 @@ int spider_discover_table_structure(
}
str.q_append(SPIDER_SQL_CLOSE_PAREN_STR, SPIDER_SQL_CLOSE_PAREN_LEN);
str.q_append(SPIDER_SQL_DEFAULT_CHARSET_STR, SPIDER_SQL_DEFAULT_CHARSET_LEN);
- str.q_append(share->table_charset->csname, csnamelen);
+ str.q_append(table_charset->csname, csnamelen);
str.q_append(SPIDER_SQL_COLLATE_STR, SPIDER_SQL_COLLATE_LEN);
- str.q_append(share->table_charset->name, collatelen);
+ str.q_append(table_charset->name, collatelen);
str.q_append(SPIDER_SQL_COMMENT_STR, SPIDER_SQL_COMMENT_LEN);
str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
if (str.append_for_single_quote(share->comment.str, share->comment.length))
diff --git a/storage/spider/spd_table.h b/storage/spider/spd_table.h
index 1b76aa7dfb8..858421444b1 100644
--- a/storage/spider/spd_table.h
+++ b/storage/spider/spd_table.h
@@ -152,6 +152,30 @@ int spider_create_conn_keys(
SPIDER_SHARE *share
);
+#ifdef SPIDER_HAS_HASH_VALUE_TYPE
+SPIDER_LGTM_TBLHND_SHARE *spider_get_lgtm_tblhnd_share(
+ const char *table_name,
+ uint table_name_length,
+ my_hash_value_type hash_value,
+ bool locked,
+ bool need_to_create,
+ int *error_num
+);
+#else
+SPIDER_LGTM_TBLHND_SHARE *spider_get_lgtm_tblhnd_share(
+ const char *table_name,
+ uint table_name_length,
+ bool locked,
+ bool need_to_create,
+ int *error_num
+);
+#endif
+
+void spider_free_lgtm_tblhnd_share_alloc(
+ SPIDER_LGTM_TBLHND_SHARE *lgtm_tblhnd_share,
+ bool locked
+);
+
SPIDER_SHARE *spider_create_share(
const char *table_name,
TABLE_SHARE *table_share,
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
index 0daa45a89e7..d289229653a 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result
@@ -2,7 +2,7 @@ drop table if exists t;
set session optimizer_switch='extended_keys=on';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
create table t (id int not null, x int not null, y int not null, primary key(id), key(x)) engine=innodb;
insert into t values (0,0,0),(1,1,1),(2,2,2),(3,2,3),(4,2,4);
explain select x,id from t force index (x) where x=0 and id=0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
index afd8bc9826d..0e14eb28c42 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result
@@ -2,7 +2,7 @@ drop table if exists t;
set session optimizer_switch='extended_keys=on';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
create table t (id int not null, x int not null, y int not null, primary key(id), key(x)) engine=tokudb;
insert into t values (0,0,0),(1,1,1),(2,2,2),(3,2,3),(4,2,4);
explain select x,id from t force index (x) where x=0 and id=0;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
index e3e4b5ae536..84fd6ed8ecc 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result
@@ -2,7 +2,7 @@ drop table if exists t;
set session optimizer_switch='extended_keys=on';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=innodb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
index 99f8aeca763..89ca5307525 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
@@ -2,7 +2,7 @@ drop table if exists t;
set session optimizer_switch='extended_keys=on';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=tokudb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
index 658becb0b12..6b4e5d88673 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
@@ -1,7 +1,7 @@
# verify that information_schema.tokudb_locks gets populated with locks, information_schema.tokudb_lock_waits gets
-if (`select @@tokudb_version <= "7.1.0"`)
+if (`select @@tokudb_version <= "7.1.6"`)
{
- --skip Not fixed in TokuDB 7.1.0 or earlier
+ --skip Race condition in the test in TokuDB 7.1.6 or earlier
}
# populated with 1 lock_wait and all transactions are present in information_schema.tokudb_trx for 2 clients
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test
index f3ace4aa63f..ea7eb9a2c89 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test
@@ -1,7 +1,3 @@
-if (`select @@tokudb_version <= "7.1.0"`)
-{
- --skip Not fixed in TokuDB 7.1.0 or earlier
-}
# verify that tokudb_locks and tokudb_lock_waits contents for 2 conflicting transactions with a lock timeout
source include/have_tokudb.inc;
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
index cc393367148..3a1cf2023da 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
@@ -1,6 +1,6 @@
-if (`select @@tokudb_version <= "7.1.0"`)
+if (`select @@tokudb_version <= "7.1.6"`)
{
- --skip Not fixed in TokuDB 7.1.0 or earlier
+ --skip Race condition in the test in TokuDB 7.1.6 or earlier
}
# verify that information_schema.tokudb_locks gets populated with locks for 2 clients
diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/mrr.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/mrr.result
new file mode 100644
index 00000000000..02ede175ce1
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/mrr.result
@@ -0,0 +1,132 @@
+drop table if exists t1,t2,t3;
+#
+# MDEV-5976: TokuDB: Wrong query result using mrr=on
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (
+task_id int(10) unsigned NOT NULL AUTO_INCREMENT,
+`type` tinyint(3) DEFAULT NULL,
+filler1 varchar(256),
+filler2 varchar(256),
+PRIMARY KEY (`task_id`),
+KEY `ymtasks_type` (`type`)
+) ENGINE=TokuDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 `COMPRESSION`=TOKUDB_LZMA;
+INSERT INTO t2 VALUES
+(1,1,'filler-data1','filler-data2'),
+(2,1,'filler-data1','filler-data2');
+CREATE TABLE t3 (
+`task_id` int(10) unsigned NOT NULL DEFAULT '0',
+`field` varchar(256) NOT NULL DEFAULT '',
+`value` varchar(4096) DEFAULT NULL,
+KEY `ymtasksoptions_task` (`task_id`),
+KEY `ymtasksoptions_field` (`field`)
+) ENGINE=TokuDB DEFAULT CHARSET=latin1 `COMPRESSION`=TOKUDB_LZMA;
+INSERT INTO t3
+select 1,
+concat('field-data-', A.a*10 + B.a),
+concat('field-data-', A.a*10 + B.a)
+from t1 A, t1 B
+where
+A.a*10 + B.a < 38;
+explain
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY,ymtasks_type ymtasks_type 2 NULL 2 Using where; Using index
+1 SIMPLE t3 ref ymtasksoptions_task ymtasksoptions_task 4 test.t2.task_id 7
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+task_id field
+1 field-data-0
+1 field-data-10
+1 field-data-20
+1 field-data-30
+1 field-data-1
+1 field-data-11
+1 field-data-21
+1 field-data-31
+1 field-data-2
+1 field-data-12
+1 field-data-22
+1 field-data-32
+1 field-data-3
+1 field-data-13
+1 field-data-23
+1 field-data-33
+1 field-data-4
+1 field-data-14
+1 field-data-24
+1 field-data-34
+1 field-data-5
+1 field-data-15
+1 field-data-25
+1 field-data-35
+1 field-data-6
+1 field-data-16
+1 field-data-26
+1 field-data-36
+1 field-data-7
+1 field-data-17
+1 field-data-27
+1 field-data-37
+1 field-data-8
+1 field-data-18
+1 field-data-28
+1 field-data-9
+1 field-data-19
+1 field-data-29
+set @tmp5976_jcl=@@join_cache_level;
+set @tmp5976_os=@@optimizer_switch;
+set join_cache_level= 6;
+set optimizer_switch='mrr=on,mrr_sort_keys=on';
+explain
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY,ymtasks_type ymtasks_type 2 NULL 2 Using where; Using index
+1 SIMPLE t3 ref ymtasksoptions_task ymtasksoptions_task 4 test.t2.task_id 7 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+task_id field
+1 field-data-0
+1 field-data-10
+1 field-data-20
+1 field-data-30
+1 field-data-1
+1 field-data-11
+1 field-data-21
+1 field-data-31
+1 field-data-2
+1 field-data-12
+1 field-data-22
+1 field-data-32
+1 field-data-3
+1 field-data-13
+1 field-data-23
+1 field-data-33
+1 field-data-4
+1 field-data-14
+1 field-data-24
+1 field-data-34
+1 field-data-5
+1 field-data-15
+1 field-data-25
+1 field-data-35
+1 field-data-6
+1 field-data-16
+1 field-data-26
+1 field-data-36
+1 field-data-7
+1 field-data-17
+1 field-data-27
+1 field-data-37
+1 field-data-8
+1 field-data-18
+1 field-data-28
+1 field-data-9
+1 field-data-19
+1 field-data-29
+drop table t1,t2,t3;
+set join_cache_level=@tmp5976_jcl;
+set optimizer_switch=@tmp5976_os;
diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/t/mrr.test b/storage/tokudb/mysql-test/tokudb_mariadb/t/mrr.test
new file mode 100644
index 00000000000..e1028e80202
--- /dev/null
+++ b/storage/tokudb/mysql-test/tokudb_mariadb/t/mrr.test
@@ -0,0 +1,62 @@
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+--echo #
+--echo # MDEV-5976: TokuDB: Wrong query result using mrr=on
+--echo #
+
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+CREATE TABLE t2 (
+ task_id int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `type` tinyint(3) DEFAULT NULL,
+ filler1 varchar(256),
+ filler2 varchar(256),
+ PRIMARY KEY (`task_id`),
+ KEY `ymtasks_type` (`type`)
+) ENGINE=TokuDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 `COMPRESSION`=TOKUDB_LZMA;
+
+INSERT INTO t2 VALUES
+ (1,1,'filler-data1','filler-data2'),
+ (2,1,'filler-data1','filler-data2');
+
+CREATE TABLE t3 (
+ `task_id` int(10) unsigned NOT NULL DEFAULT '0',
+ `field` varchar(256) NOT NULL DEFAULT '',
+ `value` varchar(4096) DEFAULT NULL,
+ KEY `ymtasksoptions_task` (`task_id`),
+ KEY `ymtasksoptions_field` (`field`)
+) ENGINE=TokuDB DEFAULT CHARSET=latin1 `COMPRESSION`=TOKUDB_LZMA;
+
+INSERT INTO t3
+select 1,
+ concat('field-data-', A.a*10 + B.a),
+ concat('field-data-', A.a*10 + B.a)
+from t1 A, t1 B
+where
+ A.a*10 + B.a < 38;
+
+explain
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+
+set @tmp5976_jcl=@@join_cache_level;
+set @tmp5976_os=@@optimizer_switch;
+
+set join_cache_level= 6;
+set optimizer_switch='mrr=on,mrr_sort_keys=on';
+
+explain
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+SELECT t3.task_id, t3.field FROM
+t3,t2 WHERE t3.task_id=t2.task_id AND t2.type NOT IN (8,11);
+
+drop table t1,t2,t3;
+set join_cache_level=@tmp5976_jcl;
+set optimizer_switch=@tmp5976_os;
+
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index e62a69a78b0..f65716aca0f 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -355,10 +355,14 @@ ha_innobase::check_if_supported_inplace_alter(
Don't do online ALTER if mtype/unsigned_flag are wrong.
*/
- for (ulint i = 0; i < table->s->fields; i++) {
+ for (ulint i = 0, icol= 0; i < table->s->fields; i++) {
const Field* field = table->field[i];
- const dict_col_t* col = dict_table_get_nth_col(prebuilt->table, i);
+ const dict_col_t* col = dict_table_get_nth_col(prebuilt->table, icol);
ulint unsigned_flag;
+ if (!field->stored_in_db)
+ continue;
+ icol++;
+
if (col->mtype != get_innobase_type_from_mysql_type(&unsigned_flag, field)) {
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index 5d1c6c150e1..6734f3c78fb 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -50,8 +50,7 @@ ENDFOREACH()
IF(UNIX)
SET(prefix ${CMAKE_INSTALL_PREFIX})
- FOREACH(script mysqld_multi.server mysql-log-rotate binary-configure
- config.medium.ini config.small.ini config.huge.ini ndb-config-2-node.ini)
+ FOREACH(script mysqld_multi.server mysql-log-rotate binary-configure)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${script}.sh
${CMAKE_CURRENT_BINARY_DIR}/${script} @ONLY )
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index a43caf5b4f3..f32e0270ce4 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -31,6 +31,7 @@ INSTALL(TARGETS mysql_client_test DESTINATION ${INSTALL_BINDIR} COMPONENT Test)
CHECK_INCLUDE_FILE(event.h HAVE_EVENT_H)
FIND_LIBRARY(EVENT_LIBRARY event)
+MARK_AS_ADVANCED(EVENT_LIBRARY)
IF(HAVE_EVENT_H AND EVENT_LIBRARY)
ADD_EXECUTABLE(async_queries async_queries.c)
TARGET_LINK_LIBRARIES(async_queries mysqlclient ${EVENT_LIBRARY})
diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c
index 6dcfb697dbe..990fdb158be 100644
--- a/tests/mysql_client_fw.c
+++ b/tests/mysql_client_fw.c
@@ -59,6 +59,7 @@ static MYSQL *mysql= 0;
static char current_db[]= "client_test_db";
static unsigned int test_count= 0;
static unsigned int opt_count= 0;
+static unsigned int opt_count_read= 0;
static unsigned int iter_count= 0;
static my_bool have_innodb= FALSE;
static char *opt_plugin_dir= 0, *opt_default_auth= 0;
@@ -69,6 +70,9 @@ static const char *opt_vardir= "mysql-test/var";
static longlong opt_getopt_ll_test= 0;
+static char **defaults_argv;
+static int original_argc;
+static char **original_argv;
static int embedded_server_arg_count= 0;
static char *embedded_server_args[MAX_SERVER_ARGS];
@@ -112,6 +116,7 @@ DBUG_PRINT("test", ("name: %s", str)); \
static void print_error(const char *msg);
static void print_st_error(MYSQL_STMT *stmt, const char *msg);
static void client_disconnect(MYSQL* mysql);
+static void get_options(int *argc, char ***argv);
/*
@@ -273,7 +278,7 @@ static my_bool check_have_innodb(MYSQL *conn)
MYSQL_RES *res;
MYSQL_ROW row;
int rc;
- my_bool result;
+ my_bool result= FALSE;
rc= mysql_query(conn,
"SELECT (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') "
@@ -285,7 +290,8 @@ static my_bool check_have_innodb(MYSQL *conn)
row= mysql_fetch_row(res);
DIE_UNLESS(row);
- result= strcmp(row[1], "1") == 0;
+ if (row[0] && row[1])
+ result= strcmp(row[1], "1") == 0;
mysql_free_result(res);
return result;
}
@@ -1181,8 +1187,8 @@ static struct my_option client_test_long_options[] =
{
{"basedir", 'b', "Basedir for tests.", &opt_basedir,
&opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"count", 't', "Number of times test to be executed", &opt_count,
- &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
+ {"count", 't', "Number of times test to be executed", &opt_count_read,
+ &opt_count_read, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
{"database", 'D', "Database to use", &opt_db, &opt_db,
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"do-not-drop-database", 'd', "Do not drop database while disconnecting",
@@ -1338,6 +1344,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
static void get_options(int *argc, char ***argv)
{
int ho_error;
+ /* Copy argv from load_defaults, so we can free it when done. */
+ defaults_argv= *argv;
+ /* reset --silent option */
+ opt_silent= 0;
if ((ho_error= handle_options(argc, argv, client_test_long_options,
get_one_option)))
@@ -1359,9 +1369,12 @@ static void print_test_output()
fprintf(stdout, "\n\n");
fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)",
test_count-1, opt_count);
- fprintf(stdout, "\n Total execution time: %g SECS", total_time);
- if (opt_count > 1)
- fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count);
+ if (!opt_silent)
+ {
+ fprintf(stdout, "\n Total execution time: %g SECS", total_time);
+ if (opt_count > 1)
+ fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count);
+ }
fprintf(stdout, "\n\n!!! SUCCESS !!!\n");
}
@@ -1374,16 +1387,37 @@ static void print_test_output()
int main(int argc, char **argv)
{
+ int i;
+ char **tests_to_run= NULL, **curr_test;
struct my_tests_st *fptr;
my_testlist= get_my_tests();
MY_INIT(argv[0]);
+ /* Copy the original arguments, so it can be reused for restarting. */
+ original_argc= argc;
+ original_argv= malloc(argc * sizeof(char*));
+ if (argc && !original_argv)
+ exit(1);
+ for (i= 0; i < argc; i++)
+ original_argv[i]= strdup(argv[i]);
if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
exit(1);
- defaults_argv= argv;
get_options(&argc, &argv);
+ /* Set main opt_count. */
+ opt_count= opt_count_read;
+
+ /* If there are any arguments left (named tests), save them. */
+ if (argc)
+ {
+ tests_to_run= malloc((argc + 1) * sizeof(char*));
+ if (!tests_to_run)
+ exit(1);
+ for (i= 0; i < argc; i++)
+ tests_to_run[i]= strdup(argv[i]);
+ tests_to_run[i]= NULL;
+ }
if (mysql_server_init(embedded_server_arg_count,
embedded_server_args,
@@ -1399,18 +1433,18 @@ int main(int argc, char **argv)
/* Start of tests */
test_count= 1;
start_time= time((time_t *)0);
- if (!argc)
+ if (!tests_to_run)
{
for (fptr= my_testlist; fptr->name; fptr++)
(*fptr->function)();
}
else
{
- for ( ; *argv ; argv++)
+ for (curr_test= tests_to_run ; *curr_test ; curr_test++)
{
for (fptr= my_testlist; fptr->name; fptr++)
{
- if (!strcmp(fptr->name, *argv))
+ if (!strcmp(fptr->name, *curr_test))
{
(*fptr->function)();
break;
@@ -1423,6 +1457,7 @@ int main(int argc, char **argv)
my_progname);
client_disconnect(mysql);
free_defaults(defaults_argv);
+ mysql_server_end();
exit(1);
}
}
@@ -1446,5 +1481,18 @@ int main(int argc, char **argv)
my_end(0);
+ for (i= 0; i < original_argc; i++)
+ free(original_argv[i]);
+ if (original_argc)
+ free(original_argv);
+ if (tests_to_run)
+ {
+ for (curr_test= tests_to_run ; *curr_test ; curr_test++)
+ free(*curr_test);
+ free(tests_to_run);
+ }
+ my_free(opt_password);
+ my_free(opt_host);
+
exit(0);
}
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 7fd68fec308..898d67c5058 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -6996,6 +6996,118 @@ static void test_set_option()
mysql_stmt_close(stmt);
}
+#ifdef EMBEDDED_LIBRARY
+static void test_embedded_start_stop()
+{
+ MYSQL *mysql_emb=NULL;
+ int i, j;
+ int argc= original_argc; // Start with the original args
+ char **argv, **my_argv;
+ char test_name[]= "test_embedded_start_stop";
+#define EMBEDDED_RESTARTS 64
+
+ myheader("test_embedded_start_stop");
+
+ /* Must stop the main embedded server, since we use the same config. */
+ client_disconnect(mysql); /* disconnect from server */
+ free_defaults(defaults_argv);
+ mysql_server_end();
+ /* Free everything allocated by my_once_alloc */
+ my_end(0);
+
+ /*
+ Use a copy of the original arguments.
+ The arguments will be altered when reading the configs and parsing
+ options.
+ */
+ my_argv= malloc((argc + 1) * sizeof(char*));
+ if (!my_argv)
+ exit(1);
+
+ /* Test restarting the embedded library many times. */
+ for (i= 1; i <= EMBEDDED_RESTARTS; i++)
+ {
+ argv= my_argv;
+ argv[0]= test_name;
+ for (j= 1; j < argc; j++)
+ argv[j]= original_argv[j];
+
+ /* Initialize everything again. */
+ MY_INIT(argv[0]);
+
+ /* Load the client defaults from the .cnf file[s]. */
+ if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
+ {
+ myerror("load_defaults failed");
+ exit(1);
+ }
+
+ /* Parse the options (including the ones given from defaults files). */
+ get_options(&argc, &argv);
+
+ /* mysql_library_init is the same as mysql_server_init. */
+ if (mysql_library_init(embedded_server_arg_count,
+ embedded_server_args,
+ (char**) embedded_server_groups))
+ {
+ myerror("mysql_library_init failed");
+ exit(1);
+ }
+
+ /* Create a client connection. */
+ if (!(mysql_emb= mysql_client_init(NULL)))
+ {
+ myerror("mysql_client_init failed");
+ exit(1);
+ }
+
+ /* Connect it and see if we can use the database. */
+ if (!(mysql_real_connect(mysql_emb, opt_host, opt_user,
+ opt_password, current_db, 0,
+ NULL, 0)))
+ {
+ myerror("mysql_real_connect failed");
+ }
+
+ /* Close the client connection */
+ mysql_close(mysql_emb);
+ mysql_emb = NULL;
+ /* Free arguments allocated for defaults files. */
+ free_defaults(defaults_argv);
+ /* mysql_library_end is a define for mysql_server_end. */
+ mysql_library_end();
+ /* Free everything allocated by my_once_alloc */
+ my_end(0);
+ }
+
+ argc= original_argc;
+ argv= my_argv;
+ argv[0]= test_name;
+ for (j= 1; j < argc; j++)
+ argv[j]= original_argv[j];
+
+ MY_INIT(argv[0]);
+
+ if (load_defaults("my", client_test_load_default_groups, &argc, &argv))
+ {
+ myerror("load_defaults failed \n ");
+ exit(1);
+ }
+
+ get_options(&argc, &argv);
+
+ /* Must start the main embedded server again after the test. */
+ if (mysql_server_init(embedded_server_arg_count,
+ embedded_server_args,
+ (char**) embedded_server_groups))
+ DIE("Can't initialize MySQL server");
+
+ /* connect to server with no flags, default protocol, auto reconnect true */
+ mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
+ free(my_argv);
+}
+#endif /* EMBEDDED_LIBRARY */
+
/*
Test a misc GRANT option
@@ -19148,6 +19260,9 @@ static struct my_tests_st my_tests[]= {
{ "test_view_sp_list_fields", test_view_sp_list_fields },
{ "client_query", client_query },
{ "test_prepare_insert_update", test_prepare_insert_update},
+#ifdef EMBEDDED_LIBRARY
+ { "test_embedded_start_stop", test_embedded_start_stop },
+#endif
#if NOT_YET_WORKING
{ "test_drop_temp", test_drop_temp },
#endif
@@ -19226,6 +19341,7 @@ static struct my_tests_st my_tests[]= {
{ "test_set_option", test_set_option },
#ifndef EMBEDDED_LIBRARY
{ "test_prepare_grant", test_prepare_grant },
+
#endif
{ "test_frm_bug", test_frm_bug },
{ "test_explain_bug", test_explain_bug },
diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake
index 124f85bb87e..e429907cb2e 100644
--- a/win/packaging/heidisql.cmake
+++ b/win/packaging/heidisql.cmake
@@ -1,6 +1,6 @@
-SET(HEIDISQL_BASE_NAME "HeidiSQL_8.0_Portable")
+SET(HEIDISQL_BASE_NAME "HeidiSQL_8.3_Portable")
SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip")
-SET(HEIDISQL_URL "http://heidisql.googlecode.com/files/${HEIDISQL_ZIP}")
+SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}")
SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME})
IF(NOT EXISTS ${HEIDISQL_DOWNLOAD_DIR}/${HEIDISQL_ZIP})