1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-18 10:22:14 +03:00
Files
mariadb/storage/ndb/test/odbc/driver/testOdbcDriver.cpp
unknown 4dabfa5de7 Merge mysql.com:/home/kent/bk/main/mysql-5.0
into  mysql.com:/home/kent/bk/main/mysql-5.1


BUILD/Makefile.am:
  Auto merged
BitKeeper/deleted/.del-ArrayFifoList.hpp~7036ae04dd7e7bd2:
  Auto merged
BitKeeper/deleted/.del-ArrayList.hpp~44695d09b1a02179:
  Auto merged
BitKeeper/deleted/.del-DbtupLCP.cpp~855b1ed3fbc86a42:
  Auto merged
BitKeeper/deleted/.del-DbtupSystemRestart.cpp~15b54d7e4e75d2d:
  Auto merged
BitKeeper/deleted/.del-DbtupUndoLog.cpp~5a2ef6e86b1404e9:
  Auto merged
Makefile.am:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~2:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~ab5c84d46412dc2e:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~abb265028eb9b6a7:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~de166d6fcac3b9b6:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~e5b911533dad2713:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~ead19441cc5ff35c:
  Auto merged
BitKeeper/deleted/.del-Makefile.am~f87185e232d7c4f:
  Auto merged
BitKeeper/deleted/.del-Makefile.in:
  Auto merged
BitKeeper/deleted/.del-MemoryChannelOSE.hpp:
  Auto merged
BitKeeper/deleted/.del-MetaData.cpp~146ae9865dd35829:
  Auto merged
BitKeeper/deleted/.del-MetaData.hpp~538342afcd8ac53c:
  Auto merged
BitKeeper/deleted/.del-NdbCondition.c~ad83464328ab37af:
  Auto merged
BitKeeper/deleted/.del-NdbCondition.c~ee56562abdd718cf:
  Auto merged
BitKeeper/deleted/.del-NdbConditionOSE.h~455dd2c29c2e6344:
  Auto merged
BitKeeper/deleted/.del-NdbDaemon.c~3b8101f376b28df:
  Auto merged
BitKeeper/deleted/.del-NdbEnv.c~207f9ce9754c9e8a:
  Auto merged
BitKeeper/deleted/.del-NdbEnv.c~bb6fe7572d45288a:
  Auto merged
BitKeeper/deleted/.del-NdbErrHnd.cpp:
  Auto merged
BitKeeper/deleted/.del-NdbHost.c~2c29816c77396d7b:
  Auto merged
BitKeeper/deleted/.del-NdbHost.c~cf18d6b3c825180c:
  Auto merged
BitKeeper/deleted/.del-NdbMem.c~6285b159985d46da:
  Auto merged
BitKeeper/deleted/.del-NdbMem.c~6c2b317c1ce230ab:
  Auto merged
BitKeeper/deleted/.del-NdbMem_SoftOse.cpp~9c61e311ec168d44:
  Auto merged
BitKeeper/deleted/.del-NdbMutex.c~768131269bccca10:
  Auto merged
BitKeeper/deleted/.del-NdbMutex.c~f4bdd19be08b84ab:
  Auto merged
BitKeeper/deleted/.del-NdbOut.cpp~8caa99a0d729540c:
  Auto merged
BitKeeper/deleted/.del-NdbSleep.c~b643ea3e7103eb62:
  Auto merged
BitKeeper/deleted/.del-NdbSleep.c~b88fbc5b140de10d:
  Auto merged
BitKeeper/deleted/.del-NdbTCP.c~1e9f416992352f6d:
  Auto merged
BitKeeper/deleted/.del-NdbTCP.c~b09cdcbef3ea2c57:
  Auto merged
BitKeeper/deleted/.del-NdbThread.c~2fe1fa5f47801772:
  Auto merged
BitKeeper/deleted/.del-NdbThread.c~fe71a67b5c3a4724:
  Auto merged
BitKeeper/deleted/.del-NdbTick.c~aa6385567216509d:
  Auto merged
BitKeeper/deleted/.del-NdbTick.c~b76feba2cf1493d1:
  Auto merged
BitKeeper/deleted/.del-OSE_Receiver.cpp:
  Auto merged
BitKeeper/deleted/.del-OSE_Receiver.hpp:
  Auto merged
BitKeeper/deleted/.del-OSE_Signals.hpp:
  Auto merged
BitKeeper/deleted/.del-OSE_Transporter.cpp:
  Auto merged
BitKeeper/deleted/.del-OSE_Transporter.hpp:
  Auto merged
BitKeeper/deleted/.del-TraceNdbApi.hpp~7a7f0ae5b70358bc:
  Auto merged
BitKeeper/deleted/.del-VerifyNdbApi.hpp~f417f78f7cd05935:
  Auto merged
BitKeeper/deleted/.del-bcd.h~81fbfcc1530534da:
  Auto merged
BitKeeper/deleted/.del-config-os2.h~a16b51851ddd317b:
  Auto merged
BitKeeper/deleted/.del-dbGenerator.c~7509c19f70cad0bf:
  Auto merged
BitKeeper/deleted/.del-dbGenerator.h~63f1aeb98260bcb7:
  Auto merged
BitKeeper/deleted/.del-dbGenerator.h~e1aaa6725999d458:
  Auto merged
BitKeeper/deleted/.del-dbPopulate.c~5dcff1c99783d83b:
  Auto merged
BitKeeper/deleted/.del-dbPopulate.h~229a894b59d4da73:
  Auto merged
BitKeeper/deleted/.del-ha_berkeley.cc:
  Auto merged
BitKeeper/deleted/.del-ha_berkeley.h:
  Auto merged
BitKeeper/deleted/.del-localDbPrepare.c~33a2c46afc8fac9a:
  Auto merged
BitKeeper/deleted/.del-macros.h~58097d584e29b5df:
  Auto merged
BitKeeper/deleted/.del-macros.h~742871fab0681964:
  Auto merged
BitKeeper/deleted/.del-mainGenerator.c~2d1c8016f72b2517:
  Auto merged
BitKeeper/deleted/.del-mainPopulate.c~37def9a44980b8ec:
  Auto merged
BitKeeper/deleted/.del-mgmapi_logevent.cpp~f1e7cf3e70edc4:
  Auto merged
BitKeeper/deleted/.del-mmslist.cpp:
  Auto merged
BitKeeper/deleted/.del-my_lread.c:
  Auto merged
BitKeeper/deleted/.del-my_lwrite.c:
  Auto merged
BitKeeper/deleted/.del-my_os2cond.c~e3b520af1c371bb5:
  Auto merged
BitKeeper/deleted/.del-my_os2dirsrch.c~4e2479b2abb2eb5a:
  Auto merged
BitKeeper/deleted/.del-my_os2dirsrch.h~5011cbc657537d0:
  Auto merged
BitKeeper/deleted/.del-my_os2dlfcn.c~6d94b488717683dd:
  Auto merged
BitKeeper/deleted/.del-my_os2dlfcn.h0~eae8edb8555eff87:
  Auto merged
BitKeeper/deleted/.del-my_os2file64.c~251fb8a1e950c31b:
  Auto merged
BitKeeper/deleted/.del-my_os2thread.c~65dca991548cec2a:
  Auto merged
BitKeeper/deleted/.del-my_os2tls.c~58ade7a0f70ad5ea:
  Auto merged
BitKeeper/deleted/.del-mysqlmanager-pwgen.c~d8f5f91ec54432b9:
  Auto merged
BitKeeper/deleted/.del-mysqlmanager.c~e97636d71145a0b:
  Auto merged
BitKeeper/deleted/.del-mysqlmanagerc.c~4f6e3499e68508f6:
  Auto merged
BitKeeper/deleted/.del-ndb_error.hpp~24468bb7f20a0b41:
  Auto merged
BitKeeper/deleted/.del-ndb_error.hpp~45a2fef922beae3:
  Auto merged
BitKeeper/deleted/.del-ndb_schema.hpp~de9c21185d6bfe4e:
  Auto merged
BitKeeper/deleted/.del-ndbapi_async.cpp~319189569fb659ec:
  Auto merged
BitKeeper/deleted/.del-ndbapi_async1.cpp~2995dac9b963a0d:
  Auto merged
BitKeeper/deleted/.del-ndbapi_event.cpp~c5d949802966180:
  Auto merged
BitKeeper/deleted/.del-ndbapi_retries.cpp~7301496d8c1c310a:
  Auto merged
BitKeeper/deleted/.del-ndbapi_scan.cpp~14ed2aa9a5d9e597:
  Auto merged
BitKeeper/deleted/.del-ndbapi_simple.cpp~80962179f3c2f5b8:
  Auto merged
BitKeeper/deleted/.del-ndbapi_simple_index.cpp~4b95a4d71808b5b6:
  Auto merged
BitKeeper/deleted/.del-print-limit-table~b8e808031daa3758:
  Auto merged
BitKeeper/deleted/.del-raid.cc~488f5fa6538394e1:
  Auto merged
BitKeeper/deleted/.del-raid.h~2d2503a66b128ac6:
  Auto merged
BitKeeper/deleted/.del-raid2.c~fe7aea5fb4b9748c:
  Auto merged
BitKeeper/deleted/.del-sql_manager.h:
  Auto merged
BitKeeper/deleted/.del-testData.h~696038ea2623a90b:
  Auto merged
BitKeeper/deleted/.del-testData.h~898b71d7c639319e:
  Auto merged
BitKeeper/deleted/.del-testDefinitions.h~f18a4553579a3725:
  Auto merged
BitKeeper/deleted/.del-userHandle.h~3275bb415e1ca2c2:
  Auto merged
BitKeeper/deleted/.del-userHandle.h~ec22dc7a7ed2f81b:
  Auto merged
BitKeeper/deleted/.del-userInterface.cpp~82ee612ab14b3d48:
  Auto merged
BitKeeper/deleted/.del-userInterface.c~92a20032f7d1e91:
  Auto merged
BitKeeper/deleted/.del-userInterface.h~1f76ad2f28b283fd:
  Auto merged
BitKeeper/deleted/.del-userInterface.h~49139f029bbdaabc:
  Auto merged
BitKeeper/deleted/.del-userTransaction.c~438012ecc761b776:
  Auto merged
BitKeeper/deleted/.del-userTransaction.c~f50661b4f54b0bdd:
  Auto merged
BitKeeper/deleted/.del-utv.h~f64af026b9705ebb:
  Auto merged
BitKeeper/deleted/.del-vcdrfunc.h~85803875180684cd:
  Auto merged
BitKeeper/deleted/.del-waiter.cpp~b188e4bfddf2cf98:
  Auto merged
Docs/Makefile.am:
  Auto merged
client/Makefile.am:
  Auto merged
client/client_priv.h:
  Auto merged
client/get_password.c:
  Auto merged
client/mysql.cc:
  Auto merged
client/mysql_upgrade.c:
  Auto merged
client/mysqladmin.cc:
  Auto merged
client/mysqlbinlog.cc:
  Auto merged
client/mysqlcheck.c:
  Auto merged
client/mysqldump.c:
  Auto merged
client/mysqlimport.c:
  Auto merged
client/mysqlshow.c:
  Auto merged
client/mysqltest.c:
  Auto merged
dbug/Makefile.am:
  Auto merged
extra/Makefile.am:
  Auto merged
extra/comp_err.c:
  Auto merged
extra/perror.c:
  Auto merged
extra/replace.c:
  Auto merged
extra/resolveip.c:
  Auto merged
include/Makefile.am:
  Auto merged
include/base64.h:
  Auto merged
include/config-netware.h:
  Auto merged
include/config-win.h:
  Auto merged
include/decimal.h:
  Auto merged
include/errmsg.h:
  Auto merged
include/ft_global.h:
  Auto merged
include/heap.h:
  Auto merged
include/m_ctype.h:
  Auto merged
include/m_string.h:
  Auto merged
include/my_base.h:
  Auto merged
include/my_bitmap.h:
  Auto merged
include/my_dbug.h:
  Auto merged
include/my_global.h:
  Auto merged
include/my_net.h:
  Auto merged
include/my_no_pthread.h:
  Auto merged
include/my_nosys.h:
  Auto merged
include/my_pthread.h:
  Auto merged
include/my_sys.h:
  Auto merged
include/my_time.h:
  Auto merged
include/my_tree.h:
  Auto merged
include/my_xml.h:
  Auto merged
include/myisam.h:
  Auto merged
include/myisammrg.h:
  Auto merged
include/mysql.h:
  Auto merged
include/mysql_com.h:
  Auto merged
include/mysys_err.h:
  Auto merged
include/queues.h:
  Auto merged
include/thr_alarm.h:
  Auto merged
include/thr_lock.h:
  Auto merged
include/violite.h:
  Auto merged
libmysqld/Makefile.am:
  Auto merged
libmysqld/emb_qcache.cc:
  Auto merged
libmysqld/embedded_priv.h:
  Auto merged
libmysqld/examples/Makefile.am:
  Auto merged
libmysqld/libmysqld.c:
  Auto merged
mysql-test/Makefile.am:
  Auto merged
mysys/Makefile.am:
  Auto merged
mysys/array.c:
  Auto merged
mysys/base64.c:
  Auto merged
mysys/charset-def.c:
  Auto merged
mysys/default.c:
  Auto merged
mysys/default_modify.c:
  Auto merged
mysys/errors.c:
  Auto merged
mysys/hash.c:
  Auto merged
mysys/mf_dirname.c:
  Auto merged
mysys/mf_format.c:
  Auto merged
mysys/mf_iocache.c:
  Auto merged
mysys/mf_iocache2.c:
  Auto merged
mysys/mf_keycache.c:
  Auto merged
mysys/mf_pack.c:
  Auto merged
mysys/mf_path.c:
  Auto merged
mysys/mf_tempdir.c:
  Auto merged
mysys/mf_tempfile.c:
  Auto merged
mysys/my_access.c:
  Auto merged
mysys/my_alloc.c:
  Auto merged
mysys/my_append.c:
  Auto merged
mysys/my_bit.c:
  Auto merged
mysys/my_bitmap.c:
  Auto merged
mysys/my_clock.c:
  Auto merged
mysys/my_compress.c:
  Auto merged
mysys/my_copy.c:
  Auto merged
mysys/my_create.c:
  Auto merged
mysys/my_dup.c:
  Auto merged
mysys/my_error.c:
  Auto merged
mysys/my_file.c:
  Auto merged
mysys/my_gethostbyname.c:
  Auto merged
mysys/my_getopt.c:
  Auto merged
mysys/my_getwd.c:
  Auto merged
mysys/my_handler.c:
  Auto merged
mysys/my_init.c:
  Auto merged
mysys/my_lib.c:
  Auto merged
mysys/my_lock.c:
  Auto merged
mysys/my_malloc.c:
  Auto merged
mysys/my_mkdir.c:
  Auto merged
mysys/my_mmap.c:
  Auto merged
mysys/my_net.c:
  Auto merged
mysys/my_once.c:
  Auto merged
mysys/my_open.c:
  Auto merged
mysys/my_pread.c:
  Auto merged
mysys/my_pthread.c:
  Auto merged
mysys/my_redel.c:
  Auto merged
mysys/my_rename.c:
  Auto merged
mysys/my_seek.c:
  Auto merged
mysys/my_sleep.c:
  Auto merged
mysys/my_static.c:
  Auto merged
mysys/my_symlink2.c:
  Auto merged
mysys/my_thr_init.c:
  Auto merged
mysys/mysys_priv.h:
  Auto merged
mysys/ptr_cmp.c:
  Auto merged
mysys/queues.c:
  Auto merged
mysys/safemalloc.c:
  Auto merged
mysys/string.c:
  Auto merged
mysys/test_dir.c:
  Auto merged
mysys/testhash.c:
  Auto merged
mysys/thr_alarm.c:
  Auto merged
mysys/thr_lock.c:
  Auto merged
mysys/thr_mutex.c:
  Auto merged
regex/Makefile.am:
  Auto merged
scripts/Makefile.am:
  Auto merged
server-tools/instance-manager/Makefile.am:
  Auto merged
server-tools/instance-manager/buffer.cc:
  Auto merged
server-tools/instance-manager/command.cc:
  Auto merged
server-tools/instance-manager/command.h:
  Auto merged
server-tools/instance-manager/commands.cc:
  Auto merged
server-tools/instance-manager/commands.h:
  Auto merged
server-tools/instance-manager/guardian.cc:
  Auto merged
server-tools/instance-manager/guardian.h:
  Auto merged
server-tools/instance-manager/instance.cc:
  Auto merged
server-tools/instance-manager/instance.h:
  Auto merged
server-tools/instance-manager/instance_map.cc:
  Auto merged
server-tools/instance-manager/instance_map.h:
  Auto merged
server-tools/instance-manager/instance_options.cc:
  Auto merged
server-tools/instance-manager/instance_options.h:
  Auto merged
server-tools/instance-manager/listener.cc:
  Auto merged
server-tools/instance-manager/listener.h:
  Auto merged
server-tools/instance-manager/log.cc:
  Auto merged
server-tools/instance-manager/log.h:
  Auto merged
server-tools/instance-manager/manager.cc:
  Auto merged
server-tools/instance-manager/manager.h:
  Auto merged
server-tools/instance-manager/messages.cc:
  Auto merged
server-tools/instance-manager/mysql_connection.cc:
  Auto merged
server-tools/instance-manager/mysql_connection.h:
  Auto merged
server-tools/instance-manager/mysql_manager_error.h:
  Auto merged
server-tools/instance-manager/mysqlmanager.cc:
  Auto merged
server-tools/instance-manager/options.cc:
  Auto merged
server-tools/instance-manager/options.h:
  Auto merged
server-tools/instance-manager/parse.cc:
  Auto merged
server-tools/instance-manager/parse.h:
  Auto merged
server-tools/instance-manager/parse_output.cc:
  Auto merged
server-tools/instance-manager/parse_output.h:
  Auto merged
server-tools/instance-manager/priv.cc:
  Auto merged
server-tools/instance-manager/priv.h:
  Auto merged
server-tools/instance-manager/protocol.cc:
  Auto merged
server-tools/instance-manager/protocol.h:
  Auto merged
server-tools/instance-manager/thread_registry.cc:
  Auto merged
server-tools/instance-manager/thread_registry.h:
  Auto merged
server-tools/instance-manager/user_map.cc:
  Auto merged
server-tools/instance-manager/user_map.h:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/discover.cc:
  Auto merged
sql/field.cc:
  Auto merged
sql/field.h:
  Auto merged
sql/field_conv.cc:
  Auto merged
sql/filesort.cc:
  Auto merged
sql/gen_lex_hash.cc:
  Auto merged
sql/ha_ndbcluster.cc:
  Auto merged
sql/ha_ndbcluster.h:
  Auto merged
sql/handler.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/hostname.cc:
  Auto merged
sql/init.cc:
  Auto merged
sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_cmpfunc.h:
  Auto merged
sql/item_create.cc:
  Auto merged
sql/item_create.h:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_func.h:
  Auto merged
sql/item_geofunc.cc:
  Auto merged
sql/item_geofunc.h:
  Auto merged
sql/item_row.cc:
  Auto merged
sql/item_row.h:
  Auto merged
sql/item_strfunc.cc:
  Auto merged
sql/item_strfunc.h:
  Auto merged
sql/item_subselect.cc:
  Auto merged
sql/item_subselect.h:
  Auto merged
sql/item_sum.cc:
  Auto merged
sql/item_sum.h:
  Auto merged
sql/item_timefunc.cc:
  Auto merged
sql/item_timefunc.h:
  Auto merged
sql/item_uniq.cc:
  Auto merged
sql/key.cc:
  Auto merged
sql/lex.h:
  Auto merged
sql/lex_symbol.h:
  Auto merged
sql/lock.cc:
  Auto merged
sql/log.cc:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/log_event.h:
  Auto merged
sql/my_decimal.cc:
  Auto merged
sql/my_decimal.h:
  Auto merged
sql/my_lock.c:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/net_serv.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/opt_range.h:
  Auto merged
sql/opt_sum.cc:
  Auto merged
sql/parse_file.cc:
  Auto merged
sql/parse_file.h:
  Auto merged
sql/password.c:
  Auto merged
sql/procedure.h:
  Auto merged
sql/protocol.cc:
  Auto merged
sql/protocol.h:
  Auto merged
sql/records.cc:
  Auto merged
sql/repl_failsafe.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/set_var.h:
  Auto merged
sql/slave.cc:
  Auto merged
sql/slave.h:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sp.h:
  Auto merged
sql/sp_cache.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sp_head.h:
  Auto merged
sql/spatial.cc:
  Auto merged
sql/spatial.h:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_acl.h:
  Auto merged
sql/sql_analyse.cc:
  Auto merged
sql/sql_analyse.h:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_bitmap.h:
  Auto merged
sql/sql_cache.cc:
  Auto merged
sql/sql_cache.h:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_crypt.cc:
  Auto merged
sql/sql_cursor.cc:
  Auto merged
sql/sql_db.cc:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_derived.cc:
  Auto merged
sql/sql_do.cc:
  Auto merged
sql/sql_error.cc:
  Auto merged
sql/sql_error.h:
  Auto merged
sql/sql_handler.cc:
  Auto merged
sql/sql_help.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_list.h:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/sql_manager.cc:
  Auto merged
sql/sql_map.cc:
  Auto merged
sql/sql_olap.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_rename.cc:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_repl.h:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_select.h:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_string.cc:
  Auto merged
sql/sql_string.h:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_test.cc:
  Auto merged
sql/sql_trigger.cc:
  Auto merged
sql/sql_trigger.h:
  Auto merged
sql/sql_udf.cc:
  Auto merged
sql/sql_union.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
sql/sql_view.cc:
  Auto merged
sql-bench/Makefile.am:
  Auto merged
sql-bench/as3ap.sh:
  Auto merged
sql-bench/bench-count-distinct.sh:
  Auto merged
sql-bench/bench-init.pl.sh:
  Auto merged
sql-bench/compare-results.sh:
  Auto merged
sql-bench/copy-db.sh:
  Auto merged
sql/share/charsets/Index.xml:
  Auto merged
sql/share/charsets/cp1250.xml:
  Auto merged
sql/sql_view.h:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
sql/stacktrace.c:
  Auto merged
sql/stacktrace.h:
  Auto merged
sql/strfunc.cc:
  Auto merged
sql/structs.h:
  Auto merged
sql/table.cc:
  Auto merged
sql/table.h:
  Auto merged
sql/time.cc:
  Auto merged
sql/tztime.cc:
  Auto merged
sql/tztime.h:
  Auto merged
sql/udf_example.c:
  Auto merged
sql/unireg.cc:
  Auto merged
sql/unireg.h:
  Auto merged
sql-bench/crash-me.sh:
  Auto merged
sql-bench/run-all-tests.sh:
  Auto merged
sql-bench/server-cfg.sh:
  Auto merged
sql-bench/test-ATIS.sh:
  Auto merged
sql-bench/test-alter-table.sh:
  Auto merged
sql-bench/test-big-tables.sh:
  Auto merged
sql-bench/test-connect.sh:
  Auto merged
sql-bench/test-create.sh:
  Auto merged
sql-bench/test-insert.sh:
  Auto merged
sql-bench/test-select.sh:
  Auto merged
sql-bench/test-transactions.sh:
  Auto merged
sql-bench/test-wisconsin.sh:
  Auto merged
sql-common/client.c:
  Auto merged
sql-common/my_time.c:
  Auto merged
storage/archive/ha_archive.cc:
  Auto merged
storage/archive/ha_archive.h:
  Auto merged
storage/blackhole/ha_blackhole.cc:
  Auto merged
storage/blackhole/ha_blackhole.h:
  Auto merged
storage/csv/ha_tina.cc:
  Auto merged
storage/csv/ha_tina.h:
  Auto merged
storage/example/ha_example.cc:
  Auto merged
storage/example/ha_example.h:
  Auto merged
storage/federated/ha_federated.cc:
  Auto merged
storage/federated/ha_federated.h:
  Auto merged
storage/heap/Makefile.am:
  Auto merged
storage/heap/_check.c:
  Auto merged
storage/heap/_rectest.c:
  Auto merged
storage/heap/ha_heap.cc:
  Auto merged
storage/heap/ha_heap.h:
  Auto merged
storage/heap/heapdef.h:
  Auto merged
storage/heap/hp_block.c:
  Auto merged
storage/heap/hp_clear.c:
  Auto merged
storage/heap/hp_close.c:
  Auto merged
storage/heap/hp_create.c:
  Auto merged
storage/heap/hp_delete.c:
  Auto merged
storage/heap/hp_extra.c:
  Auto merged
storage/heap/hp_hash.c:
  Auto merged
storage/heap/hp_info.c:
  Auto merged
storage/heap/hp_open.c:
  Auto merged
storage/heap/hp_panic.c:
  Auto merged
storage/heap/hp_rename.c:
  Auto merged
storage/heap/hp_rfirst.c:
  Auto merged
storage/heap/hp_rkey.c:
  Auto merged
storage/heap/hp_rlast.c:
  Auto merged
storage/heap/hp_rnext.c:
  Auto merged
storage/heap/hp_rprev.c:
  Auto merged
storage/heap/hp_rrnd.c:
  Auto merged
storage/heap/hp_rsame.c:
  Auto merged
storage/heap/hp_scan.c:
  Auto merged
storage/heap/hp_static.c:
  Auto merged
storage/heap/hp_test1.c:
  Auto merged
storage/heap/hp_test2.c:
  Auto merged
storage/heap/hp_update.c:
  Auto merged
storage/heap/hp_write.c:
  Auto merged
storage/innobase/Makefile.am:
  Auto merged
storage/innobase/btr/Makefile.am:
  Auto merged
storage/innobase/buf/Makefile.am:
  Auto merged
storage/innobase/data/Makefile.am:
  Auto merged
storage/innobase/dict/Makefile.am:
  Auto merged
storage/innobase/dyn/Makefile.am:
  Auto merged
storage/innobase/eval/Makefile.am:
  Auto merged
storage/innobase/fil/Makefile.am:
  Auto merged
storage/innobase/fsp/Makefile.am:
  Auto merged
storage/innobase/fut/Makefile.am:
  Auto merged
storage/innobase/ha/Makefile.am:
  Auto merged
storage/innobase/handler/ha_innodb.cc:
  Auto merged
storage/innobase/handler/ha_innodb.h:
  Auto merged
storage/innobase/ibuf/Makefile.am:
  Auto merged
storage/innobase/lock/Makefile.am:
  Auto merged
storage/innobase/log/Makefile.am:
  Auto merged
storage/innobase/mach/Makefile.am:
  Auto merged
storage/innobase/mem/Makefile.am:
  Auto merged
storage/innobase/mtr/Makefile.am:
  Auto merged
storage/innobase/os/Makefile.am:
  Auto merged
storage/innobase/page/Makefile.am:
  Auto merged
storage/innobase/pars/Makefile.am:
  Auto merged
storage/innobase/que/Makefile.am:
  Auto merged
storage/innobase/read/Makefile.am:
  Auto merged
storage/innobase/rem/Makefile.am:
  Auto merged
storage/innobase/row/Makefile.am:
  Auto merged
storage/innobase/srv/Makefile.am:
  Auto merged
storage/innobase/sync/Makefile.am:
  Auto merged
storage/innobase/thr/Makefile.am:
  Auto merged
storage/innobase/trx/Makefile.am:
  Auto merged
storage/innobase/usr/Makefile.am:
  Auto merged
storage/innobase/ut/Makefile.am:
  Auto merged
storage/myisam/Makefile.am:
  Auto merged
storage/myisam/ft_boolean_search.c:
  Auto merged
storage/myisam/ft_eval.c:
  Auto merged
storage/myisam/ft_eval.h:
  Auto merged
storage/myisam/ft_nlq_search.c:
  Auto merged
storage/myisam/ft_parser.c:
  Auto merged
storage/myisam/ft_static.c:
  Auto merged
storage/myisam/ft_stem.c:
  Auto merged
storage/myisam/ft_stopwords.c:
  Auto merged
storage/myisam/ft_test1.c:
  Auto merged
storage/myisam/ft_test1.h:
  Auto merged
storage/myisam/ft_update.c:
  Auto merged
storage/myisam/ftdefs.h:
  Auto merged
storage/myisam/fulltext.h:
  Auto merged
storage/myisam/ha_myisam.cc:
  Auto merged
storage/myisam/ha_myisam.h:
  Auto merged
storage/myisam/mi_cache.c:
  Auto merged
storage/myisam/mi_changed.c:
  Auto merged
storage/myisam/mi_check.c:
  Auto merged
storage/myisam/mi_checksum.c:
  Auto merged
storage/myisam/mi_close.c:
  Auto merged
storage/myisam/mi_create.c:
  Auto merged
storage/myisam/mi_dbug.c:
  Auto merged
storage/myisam/mi_delete.c:
  Auto merged
storage/myisam/mi_delete_all.c:
  Auto merged
storage/myisam/mi_delete_table.c:
  Auto merged
storage/myisam/mi_dynrec.c:
  Auto merged
storage/myisam/mi_extra.c:
  Auto merged
storage/myisam/mi_info.c:
  Auto merged
storage/myisam/mi_key.c:
  Auto merged
storage/myisam/mi_keycache.c:
  Auto merged
storage/myisam/mi_locking.c:
  Auto merged
storage/myisam/mi_log.c:
  Auto merged
storage/myisam/mi_open.c:
  Auto merged
storage/myisam/mi_packrec.c:
  Auto merged
storage/myisam/mi_page.c:
  Auto merged
storage/myisam/mi_panic.c:
  Auto merged
storage/myisam/mi_preload.c:
  Auto merged
storage/myisam/mi_range.c:
  Auto merged
storage/myisam/mi_rename.c:
  Auto merged
storage/myisam/mi_rfirst.c:
  Auto merged
storage/myisam/mi_rkey.c:
  Auto merged
storage/myisam/mi_rlast.c:
  Auto merged
storage/myisam/mi_rnext.c:
  Auto merged
storage/myisam/mi_rnext_same.c:
  Auto merged
storage/myisam/mi_rprev.c:
  Auto merged
storage/myisam/mi_rrnd.c:
  Auto merged
storage/myisam/mi_rsame.c:
  Auto merged
storage/myisam/mi_rsamepos.c:
  Auto merged
storage/myisam/mi_scan.c:
  Auto merged
storage/myisam/mi_search.c:
  Auto merged
storage/myisam/mi_static.c:
  Auto merged
storage/myisam/mi_statrec.c:
  Auto merged
storage/myisam/mi_test1.c:
  Auto merged
storage/myisam/mi_test2.c:
  Auto merged
storage/myisam/mi_test3.c:
  Auto merged
storage/myisam/mi_unique.c:
  Auto merged
storage/myisam/mi_update.c:
  Auto merged
storage/myisam/mi_write.c:
  Auto merged
storage/myisam/myisam_ftdump.c:
  Auto merged
storage/myisam/myisamchk.c:
  Auto merged
storage/myisam/myisamdef.h:
  Auto merged
storage/myisam/myisamlog.c:
  Auto merged
storage/myisam/myisampack.c:
  Auto merged
storage/myisam/rt_index.c:
  Auto merged
storage/myisam/rt_index.h:
  Auto merged
storage/myisam/rt_key.c:
  Auto merged
storage/myisam/rt_key.h:
  Auto merged
storage/myisam/rt_mbr.c:
  Auto merged
storage/myisam/rt_mbr.h:
  Auto merged
storage/myisam/rt_split.c:
  Auto merged
storage/myisam/rt_test.c:
  Auto merged
storage/myisam/sort.c:
  Auto merged
storage/myisam/sp_defs.h:
  Auto merged
storage/myisam/sp_key.c:
  Auto merged
storage/myisam/sp_test.c:
  Auto merged
storage/myisammrg/Makefile.am:
  Auto merged
storage/myisammrg/ha_myisammrg.cc:
  Auto merged
storage/myisammrg/ha_myisammrg.h:
  Auto merged
storage/myisammrg/myrg_close.c:
  Auto merged
storage/myisammrg/myrg_create.c:
  Auto merged
storage/myisammrg/myrg_def.h:
  Auto merged
storage/myisammrg/myrg_delete.c:
  Auto merged
storage/myisammrg/myrg_extra.c:
  Auto merged
storage/myisammrg/myrg_info.c:
  Auto merged
storage/myisammrg/myrg_locking.c:
  Auto merged
storage/myisammrg/myrg_open.c:
  Auto merged
storage/myisammrg/myrg_panic.c:
  Auto merged
storage/myisammrg/myrg_queue.c:
  Auto merged
storage/myisammrg/myrg_range.c:
  Auto merged
storage/myisammrg/myrg_rfirst.c:
  Auto merged
storage/myisammrg/myrg_rkey.c:
  Auto merged
storage/myisammrg/myrg_rlast.c:
  Auto merged
storage/myisammrg/myrg_rnext.c:
  Auto merged
storage/myisammrg/myrg_rnext_same.c:
  Auto merged
storage/myisammrg/myrg_rprev.c:
  Auto merged
storage/myisammrg/myrg_rrnd.c:
  Auto merged
storage/myisammrg/myrg_rsame.c:
  Auto merged
storage/myisammrg/myrg_static.c:
  Auto merged
storage/myisammrg/myrg_update.c:
  Auto merged
storage/myisammrg/myrg_write.c:
  Auto merged
storage/ndb/include/debugger/DebuggerNames.hpp:
  Auto merged
storage/ndb/include/debugger/EventLogger.hpp:
  Auto merged
storage/ndb/include/debugger/GrepError.hpp:
  Auto merged
storage/ndb/include/debugger/SignalLoggerManager.hpp:
  Auto merged
storage/ndb/include/ndb_constants.h:
  Auto merged
storage/ndb/include/ndb_global.h.in:
  Auto merged
storage/ndb/include/ndb_init.h:
  Auto merged
storage/ndb/include/ndb_types.h.in:
  Auto merged
storage/ndb/include/ndb_version.h.in:
  Auto merged
storage/ndb/include/editline/editline.h:
  Auto merged
storage/ndb/include/kernel/AttributeDescriptor.hpp:
  Auto merged
storage/ndb/include/kernel/AttributeHeader.hpp:
  Auto merged
storage/ndb/include/kernel/AttributeList.hpp:
  Auto merged
storage/ndb/include/kernel/BlockNumbers.h:
  Auto merged
storage/ndb/include/kernel/GlobalSignalNumbers.h:
  Auto merged
storage/ndb/include/kernel/GrepEvent.hpp:
  Auto merged
storage/ndb/include/kernel/Interpreter.hpp:
  Auto merged
storage/ndb/include/kernel/LogLevel.hpp:
  Auto merged
storage/ndb/include/kernel/NodeBitmask.hpp:
  Auto merged
storage/ndb/include/kernel/NodeInfo.hpp:
  Auto merged
storage/ndb/include/kernel/NodeState.hpp:
  Auto merged
storage/ndb/include/kernel/RefConvert.hpp:
  Auto merged
storage/ndb/include/kernel/kernel_types.h:
  Auto merged
storage/ndb/include/kernel/ndb_limits.h:
  Auto merged
storage/ndb/include/kernel/signaldata/AbortAll.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AccFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AccLock.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AccScan.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AccSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AlterIndx.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AlterTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AlterTable.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AlterTrig.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ApiBroadcast.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ApiRegSignalData.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ApiVersion.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ArbitSignalData.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/AttrInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/BackupContinueB.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/BackupImpl.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/BackupSignalData.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/BlockCommitOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/BuildIndx.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CheckNodeGroups.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CloseComReqConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CmInit.hpp:
  Auto merged
storage/ndb/include/kernel/trigger_definitions.h:
  Auto merged
storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CmvmiCfgConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CntrMasterConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CntrMasterReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ConfigParamId.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ContinueFragmented.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CopyActive.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CopyFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CopyGCIReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateEvnt.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateFragmentation.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateIndx.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateTable.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/CreateTrig.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DiAddTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DiGetNodes.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DictLock.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DictSchemaInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DictSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DictStart.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DictTabInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DihAddFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DihContinueB.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DihSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DihStartTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DihSwitchReplica.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DisconnectRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DropIndx.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DropTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DropTabFile.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DropTable.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DropTrig.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/EmptyLcp.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/EndTo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/EventReport.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/EventSubscribeReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ExecFragReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FailRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FireTrigOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsAppendReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsCloseReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsOpenReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsReadWriteReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsRef.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/FsRemoveReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/GCPSave.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/GetTabInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/GetTableId.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/GrepImpl.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/HotSpareRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/IndxAttrInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/IndxKeyInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/InvalidateNodeLCPConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/InvalidateNodeLCPReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/KeyInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/LCP.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ListTables.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/LqhFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/LqhKey.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/LqhSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/LqhTransConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ManagementServer.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/MasterGCP.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/MasterLCP.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/NFCompleteRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/NdbSttor.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/NdbfsContinueB.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/NextScan.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/NodeFailRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/NodeStateSignalData.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/PackedSignal.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/PrepDropTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/PrepFailReqRef.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ReadNodesConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/RelTabMem.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/RepImpl.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ResumeReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ScanFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/ScanTab.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SetVarReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SignalData.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SignalDataPrint.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SignalDroppedRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SrFragidConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartFragReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartMe.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartPerm.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartRec.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StartTo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StopMe.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StopPerm.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/StopReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SumaImpl.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/SystemError.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TamperOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcCommit.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcContinueB.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcHbRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcIndx.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcKeyConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcKeyFailConf.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcKeyRef.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcKeyReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcRollbackRep.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TcSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TestOrd.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TransIdAI.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TrigAttrInfo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TupCommit.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TupFrag.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TupKey.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TupSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TuxBound.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TuxContinueB.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TuxMaint.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/TuxSizeAltReq.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UpdateTo.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UtilDelete.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UtilExecute.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UtilLock.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UtilPrepare.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UtilRelease.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/UtilSequence.hpp:
  Auto merged
storage/ndb/include/kernel/signaldata/WaitGCP.hpp:
  Auto merged
storage/ndb/include/logger/ConsoleLogHandler.hpp:
  Auto merged
storage/ndb/include/logger/FileLogHandler.hpp:
  Auto merged
storage/ndb/include/logger/LogHandler.hpp:
  Auto merged
storage/ndb/include/logger/Logger.hpp:
  Auto merged
storage/ndb/include/logger/SysLogHandler.hpp:
  Auto merged
storage/ndb/include/mgmapi/mgmapi.h:
  Auto merged
storage/ndb/include/mgmapi/mgmapi_debug.h:
  Auto merged
storage/ndb/include/mgmapi/ndb_logevent.h:
  Auto merged
storage/ndb/include/mgmapi/ndbd_exit_codes.h:
  Auto merged
storage/ndb/include/mgmcommon/ConfigRetriever.hpp:
  Auto merged
storage/ndb/include/mgmcommon/IPCConfig.hpp:
  Auto merged
storage/ndb/include/mgmcommon/MgmtErrorReporter.hpp:
  Auto merged
storage/ndb/include/ndbapi/Ndb.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbApi.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbBlob.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbDictionary.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbError.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbEventOperation.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbIndexOperation.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbOperation.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbPool.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbRecAttr.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbReceiver.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbScanFilter.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbScanOperation.hpp:
  Auto merged
storage/ndb/include/ndbapi/NdbTransaction.hpp:
  Auto merged
storage/ndb/include/ndbapi/ndb_cluster_connection.hpp:
  Auto merged
storage/ndb/include/ndbapi/ndb_opt_defaults.h:
  Auto merged
storage/ndb/include/ndbapi/ndbapi_limits.h:
  Auto merged
storage/ndb/include/ndbapi/ndberror.h:
  Auto merged
storage/ndb/include/newtonapi/dba.h:
  Auto merged
storage/ndb/include/newtonapi/defs/pcn_types.h:
  Auto merged
storage/ndb/include/portlib/NdbCondition.h:
  Auto merged
storage/ndb/include/portlib/NdbConfig.h:
  Auto merged
storage/ndb/include/portlib/NdbDaemon.h:
  Auto merged
storage/ndb/include/portlib/NdbEnv.h:
  Auto merged
storage/ndb/include/portlib/NdbHost.h:
  Auto merged
storage/ndb/include/portlib/NdbMain.h:
  Auto merged
storage/ndb/include/portlib/NdbMem.h:
  Auto merged
storage/ndb/include/portlib/NdbMutex.h:
  Auto merged
storage/ndb/include/portlib/NdbSleep.h:
  Auto merged
storage/ndb/include/portlib/NdbTCP.h:
  Auto merged
storage/ndb/include/portlib/NdbThread.h:
  Auto merged
storage/ndb/include/portlib/NdbTick.h:
  Auto merged
storage/ndb/include/portlib/PortDefs.h:
  Auto merged
storage/ndb/include/portlib/prefetch.h:
  Auto merged
storage/ndb/include/transporter/TransporterCallback.hpp:
  Auto merged
storage/ndb/include/transporter/TransporterDefinitions.hpp:
  Auto merged
storage/ndb/include/transporter/TransporterRegistry.hpp:
  Auto merged
storage/ndb/include/util/BaseString.hpp:
  Auto merged
storage/ndb/include/util/Bitmask.hpp:
  Auto merged
storage/ndb/include/util/File.hpp:
  Auto merged
storage/ndb/include/util/InputStream.hpp:
  Auto merged
storage/ndb/include/util/NdbAutoPtr.hpp:
  Auto merged
storage/ndb/include/util/NdbOut.hpp:
  Auto merged
storage/ndb/include/util/NdbSqlUtil.hpp:
  Auto merged
storage/ndb/include/util/OutputStream.hpp:
  Auto merged
storage/ndb/include/util/Parser.hpp:
  Auto merged
storage/ndb/include/util/Properties.hpp:
  Auto merged
storage/ndb/include/util/SimpleProperties.hpp:
  Auto merged
storage/ndb/include/util/SocketAuthenticator.hpp:
  Auto merged
storage/ndb/include/util/SocketClient.hpp:
  Auto merged
storage/ndb/include/util/SocketServer.hpp:
  Auto merged
storage/ndb/include/util/UtilBuffer.hpp:
  Auto merged
storage/ndb/include/util/Vector.hpp:
  Auto merged
storage/ndb/include/util/basestring_vsnprintf.h:
  Auto merged
storage/ndb/include/util/md5_hash.hpp:
  Auto merged
storage/ndb/include/util/ndb_opts.h:
  Auto merged
storage/ndb/include/util/random.h:
  Auto merged
storage/ndb/include/util/socket_io.h:
  Auto merged
storage/ndb/include/util/uucode.h:
  Auto merged
storage/ndb/include/util/version.h:
  Auto merged
storage/ndb/src/common/debugger/BlockNames.cpp:
  Auto merged
storage/ndb/src/common/debugger/DebuggerNames.cpp:
  Auto merged
storage/ndb/src/common/debugger/EventLogger.cpp:
  Auto merged
storage/ndb/src/common/debugger/GrepError.cpp:
  Auto merged
storage/ndb/src/common/debugger/SignalLoggerManager.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/AccLock.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/AlterIndx.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/AlterTab.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/AlterTable.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/AlterTrig.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/BackupImpl.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/BackupSignalData.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/CloseComReqConf.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/ContinueB.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/CopyGCI.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/CreateEvnt.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/CreateIndx.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/CreateTrig.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DihContinueB.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DihSwitchReplicaReq.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DisconnectRep.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DropIndx.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DropTab.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/DropTrig.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FailRep.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FireTrigOrd.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FsAppendReq.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FsCloseReq.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FsConf.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FsOpenReq.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FsReadWriteReq.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/FsRef.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/GCPSave.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/IndxAttrInfo.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/IndxKeyInfo.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/LCP.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/LqhFrag.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/LqhKey.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/LqhTrans.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/MasterLCP.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/NFCompleteRep.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/NdbSttor.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/NdbfsContinueB.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/PackedSignal.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/PrepDropTab.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/PrepFailReqRef.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/ScanFrag.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/ScanTab.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/SignalDroppedRep.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/SignalNames.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/StartRec.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/SumaImpl.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/SystemError.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TcIndx.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TcKeyConf.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TcKeyRef.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TcKeyReq.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TcRollbackRep.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TrigAttrInfo.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TupCommit.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TupKey.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/TuxMaint.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/UtilDelete.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/UtilExecute.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/UtilLock.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/UtilPrepare.cpp:
  Auto merged
storage/ndb/src/common/debugger/signaldata/UtilSequence.cpp:
  Auto merged
storage/ndb/src/common/logger/ConsoleLogHandler.cpp:
  Auto merged
storage/ndb/src/common/logger/FileLogHandler.cpp:
  Auto merged
storage/ndb/src/common/logger/LogHandler.cpp:
  Auto merged
storage/ndb/src/common/logger/LogHandlerList.cpp:
  Auto merged
storage/ndb/src/common/logger/LogHandlerList.hpp:
  Auto merged
storage/ndb/src/common/logger/Logger.cpp:
  Auto merged
storage/ndb/src/common/logger/SysLogHandler.cpp:
  Auto merged
storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.cpp:
  Auto merged
storage/ndb/src/common/logger/listtest/LogHandlerListUnitTest.hpp:
  Auto merged
storage/ndb/src/common/logger/loggertest/LoggerUnitTest.cpp:
  Auto merged
storage/ndb/src/common/logger/loggertest/LoggerUnitTest.hpp:
  Auto merged
storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp:
  Auto merged
storage/ndb/src/common/mgmcommon/IPCConfig.cpp:
  Auto merged
storage/ndb/src/common/mgmcommon/printConfig/printConfig.cpp:
  Auto merged
storage/ndb/src/common/portlib/NdbCondition.c:
  Auto merged
storage/ndb/src/common/portlib/NdbConfig.c:
  Auto merged
storage/ndb/src/common/portlib/NdbDaemon.c:
  Auto merged
storage/ndb/src/common/portlib/NdbEnv.c:
  Auto merged
storage/ndb/src/common/portlib/NdbHost.c:
  Auto merged
storage/ndb/src/common/portlib/NdbMem.c:
  Auto merged
storage/ndb/src/common/portlib/NdbMutex.c:
  Auto merged
storage/ndb/src/common/portlib/NdbPortLibTest.cpp:
  Auto merged
storage/ndb/src/common/portlib/NdbSleep.c:
  Auto merged
storage/ndb/src/common/portlib/NdbTCP.cpp:
  Auto merged
storage/ndb/src/common/portlib/NdbThread.c:
  Auto merged
storage/ndb/src/common/portlib/NdbTick.c:
  Auto merged
storage/ndb/src/common/portlib/memtest.c:
  Auto merged
storage/ndb/src/common/portlib/mmstest.cpp:
  Auto merged
storage/ndb/src/common/portlib/munmaptest.cpp:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbCondition.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbDaemon.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbEnv.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbHost.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbMem.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbMutex.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbSleep.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbTCP.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbThread.c:
  Auto merged
storage/ndb/src/common/portlib/win32/NdbTick.c:
  Auto merged
storage/ndb/src/common/transporter/Packer.cpp:
  Auto merged
storage/ndb/src/common/transporter/Packer.hpp:
  Auto merged
storage/ndb/src/common/transporter/SCI_Transporter.cpp:
  Auto merged
storage/ndb/src/common/transporter/SCI_Transporter.hpp:
  Auto merged
storage/ndb/src/common/transporter/SHM_Buffer.hpp:
  Auto merged
storage/ndb/src/common/transporter/SHM_Transporter.cpp:
  Auto merged
storage/ndb/src/common/transporter/SHM_Transporter.hpp:
  Auto merged
storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp:
  Auto merged
storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp:
  Auto merged
storage/ndb/src/common/transporter/SendBuffer.cpp:
  Auto merged
storage/ndb/src/common/transporter/SendBuffer.hpp:
  Auto merged
storage/ndb/src/common/transporter/TCP_Transporter.cpp:
  Auto merged
storage/ndb/src/common/transporter/TCP_Transporter.hpp:
  Auto merged
storage/ndb/src/common/transporter/Transporter.cpp:
  Auto merged
storage/ndb/src/common/transporter/Transporter.hpp:
  Auto merged
storage/ndb/src/common/transporter/TransporterInternalDefinitions.hpp:
  Auto merged
storage/ndb/src/common/transporter/TransporterRegistry.cpp:
  Auto merged
storage/ndb/src/common/transporter/basictest/basicTransporterTest.cpp:
  Auto merged
storage/ndb/src/common/transporter/buddy.cpp:
  Auto merged
storage/ndb/src/common/transporter/buddy.hpp:
  Auto merged
storage/ndb/src/common/transporter/failoverSCI/failoverSCI.cpp:
  Auto merged
storage/ndb/src/common/transporter/perftest/perfTransporterTest.cpp:
  Auto merged
storage/ndb/src/common/transporter/priotest/prioSCI/prioSCI.cpp:
  Auto merged
storage/ndb/src/common/transporter/priotest/prioSHM/prioSHM.cpp:
  Auto merged
storage/ndb/src/common/transporter/priotest/prioTCP/prioTCP.cpp:
  Auto merged
storage/ndb/src/common/transporter/priotest/prioTransporterTest.cpp:
  Auto merged
storage/ndb/src/common/transporter/priotest/prioTransporterTest.hpp:
  Auto merged
storage/ndb/src/common/util/BaseString.cpp:
  Auto merged
storage/ndb/src/common/util/File.cpp:
  Auto merged
storage/ndb/src/common/util/InputStream.cpp:
  Auto merged
storage/ndb/src/common/util/NdbOut.cpp:
  Auto merged
storage/ndb/src/common/util/NdbSqlUtil.cpp:
  Auto merged
storage/ndb/src/common/util/OutputStream.cpp:
  Auto merged
storage/ndb/src/common/util/Parser.cpp:
  Auto merged
storage/ndb/src/common/util/Properties.cpp:
  Auto merged
storage/ndb/src/common/util/SimpleProperties.cpp:
  Auto merged
storage/ndb/src/common/util/SocketAuthenticator.cpp:
  Auto merged
storage/ndb/src/common/util/SocketClient.cpp:
  Auto merged
storage/ndb/src/common/util/SocketServer.cpp:
  Auto merged
storage/ndb/src/common/util/basestring_vsnprintf.c:
  Auto merged
storage/ndb/src/common/util/md5_hash.cpp:
  Auto merged
storage/ndb/src/common/util/ndb_init.c:
  Auto merged
storage/ndb/src/common/util/random.c:
  Auto merged
storage/ndb/src/common/util/socket_io.cpp:
  Auto merged
storage/ndb/src/common/util/strdup.c:
  Auto merged
storage/ndb/src/common/util/filetest/FileUnitTest.cpp:
  Auto merged
storage/ndb/src/common/util/filetest/FileUnitTest.hpp:
  Auto merged
storage/ndb/src/common/util/testProperties/testProperties.cpp:
  Auto merged
storage/ndb/src/common/util/testSimpleProperties/sp_test.cpp:
  Auto merged
storage/ndb/src/common/util/uucode.c:
  Auto merged
storage/ndb/src/common/util/version.c:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.cpp:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/CPC_GUI.h:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/NdbControls.cpp:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/StdAfx.cpp:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/StdAfx.h:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/TreeView.cpp:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/TreeView.h:
  Auto merged
storage/ndb/src/cw/cpcc-win32/C++/resource.h:
  Auto merged
storage/ndb/src/cw/cpcd/APIService.cpp:
  Auto merged
storage/ndb/src/cw/cpcd/APIService.hpp:
  Auto merged
storage/ndb/src/cw/cpcd/CPCD.cpp:
  Auto merged
storage/ndb/src/cw/cpcd/CPCD.hpp:
  Auto merged
storage/ndb/src/cw/cpcd/Monitor.cpp:
  Auto merged
storage/ndb/src/cw/cpcd/Process.cpp:
  Auto merged
storage/ndb/src/cw/cpcd/common.cpp:
  Auto merged
storage/ndb/src/cw/cpcd/common.hpp:
  Auto merged
storage/ndb/src/cw/cpcd/main.cpp:
  Auto merged
storage/ndb/src/cw/test/socketclient/socketClientTest.cpp:
  Auto merged
storage/ndb/src/cw/util/ClientInterface.cpp:
  Auto merged
storage/ndb/src/cw/util/ClientInterface.hpp:
  Auto merged
storage/ndb/src/cw/util/SocketRegistry.cpp:
  Auto merged
storage/ndb/src/cw/util/SocketRegistry.hpp:
  Auto merged
storage/ndb/src/cw/util/SocketService.cpp:
  Auto merged
storage/ndb/src/cw/util/SocketService.hpp:
  Auto merged
storage/ndb/src/kernel/SimBlockList.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/mutexes.hpp:
  Auto merged
storage/ndb/src/kernel/main.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/backup/Backup.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/backup/Backup.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/backup/BackupInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/backup/FsBuffer.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/backup/read.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdih/Sysfile.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbdih/printSysfile/printSysfile.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupBuffer.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupFixAlloc.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupStoredProcDef.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/AsyncFile.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/AsyncFileTest/AsyncFileTest.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/CircularIndex.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannel.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/MemoryChannelTest/MemoryChannelTest.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/Pool.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/ndbfs/VoidFs.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/qmgr/timer.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/suma/Suma.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/suma/Suma.hpp:
  Auto merged
storage/ndb/src/kernel/blocks/suma/SumaInit.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/trix/Trix.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/trix/Trix.hpp:
  Auto merged
storage/ndb/src/kernel/error/ErrorHandlingMacros.hpp:
  Auto merged
storage/ndb/src/kernel/error/ErrorReporter.cpp:
  Auto merged
storage/ndb/src/kernel/error/ErrorReporter.hpp:
  Auto merged
storage/ndb/src/kernel/error/TimeModule.cpp:
  Auto merged
storage/ndb/src/kernel/error/TimeModule.hpp:
  Auto merged
storage/ndb/src/kernel/error/ndbd_exit_codes.c:
  Auto merged
storage/ndb/src/kernel/vm/Array.hpp:
  Auto merged
storage/ndb/src/kernel/vm/ArrayPool.hpp:
  Auto merged
storage/ndb/src/kernel/vm/CArray.hpp:
  Auto merged
storage/ndb/src/kernel/vm/Callback.hpp:
  Auto merged
storage/ndb/src/kernel/vm/ClusterConfiguration.cpp:
  Auto merged
storage/ndb/src/kernel/vm/ClusterConfiguration.hpp:
  Auto merged
storage/ndb/src/kernel/vm/Configuration.cpp:
  Auto merged
storage/ndb/src/kernel/vm/Configuration.hpp:
  Auto merged
storage/ndb/src/kernel/vm/DLFifoList.hpp:
  Auto merged
storage/ndb/src/kernel/vm/DLHashTable.hpp:
  Auto merged
storage/ndb/src/kernel/vm/DLHashTable2.hpp:
  Auto merged
storage/ndb/src/kernel/vm/DLList.hpp:
  Auto merged
storage/ndb/src/kernel/vm/DataBuffer.hpp:
  Auto merged
storage/ndb/src/kernel/vm/Emulator.cpp:
  Auto merged
storage/ndb/src/kernel/vm/Emulator.hpp:
  Auto merged
storage/ndb/src/kernel/vm/FastScheduler.cpp:
  Auto merged
storage/ndb/src/kernel/vm/FastScheduler.hpp:
  Auto merged
storage/ndb/src/kernel/vm/GlobalData.hpp:
  Auto merged
storage/ndb/src/kernel/vm/KeyDescriptor.hpp:
  Auto merged
storage/ndb/src/kernel/vm/KeyTable.hpp:
  Auto merged
storage/ndb/src/kernel/vm/KeyTable2.hpp:
  Auto merged
storage/ndb/src/kernel/vm/LongSignal.hpp:
  Auto merged
storage/ndb/src/kernel/vm/Mutex.cpp:
  Auto merged
storage/ndb/src/kernel/vm/Mutex.hpp:
  Auto merged
storage/ndb/src/kernel/vm/Prio.hpp:
  Auto merged
storage/ndb/src/kernel/vm/RequestTracker.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SLList.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SafeCounter.cpp:
  Auto merged
storage/ndb/src/kernel/vm/SafeCounter.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SectionReader.cpp:
  Auto merged
storage/ndb/src/kernel/vm/SectionReader.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SignalCounter.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SimBlockList.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp:
  Auto merged
storage/ndb/src/kernel/vm/SimulatedBlock.cpp:
  Auto merged
storage/ndb/src/kernel/vm/SimulatedBlock.hpp:
  Auto merged
storage/ndb/src/kernel/vm/SuperPool.cpp:
  Auto merged
storage/ndb/src/kernel/vm/SuperPool.hpp:
  Auto merged
storage/ndb/src/kernel/vm/ThreadConfig.cpp:
  Auto merged
storage/ndb/src/kernel/vm/ThreadConfig.hpp:
  Auto merged
storage/ndb/src/kernel/vm/TimeQueue.cpp:
  Auto merged
storage/ndb/src/kernel/vm/TimeQueue.hpp:
  Auto merged
storage/ndb/src/kernel/vm/TransporterCallback.cpp:
  Auto merged
storage/ndb/src/kernel/vm/VMSignal.cpp:
  Auto merged
storage/ndb/src/kernel/vm/VMSignal.hpp:
  Auto merged
storage/ndb/src/kernel/vm/WaitQueue.hpp:
  Auto merged
storage/ndb/src/kernel/vm/WatchDog.cpp:
  Auto merged
storage/ndb/src/kernel/vm/WatchDog.hpp:
  Auto merged
storage/ndb/src/kernel/vm/al_test/arrayListTest.cpp:
  Auto merged
storage/ndb/src/kernel/vm/al_test/arrayPoolTest.cpp:
  Auto merged
storage/ndb/src/kernel/vm/al_test/main.cpp:
  Auto merged
storage/ndb/src/kernel/vm/ndbd_malloc.cpp:
  Auto merged
storage/ndb/src/kernel/vm/ndbd_malloc.hpp:
  Auto merged
storage/ndb/src/kernel/vm/pc.hpp:
  Auto merged
storage/ndb/src/kernel/vm/testCopy/rr.cpp:
  Auto merged
storage/ndb/src/kernel/vm/testCopy/testCopy.cpp:
  Auto merged
storage/ndb/src/kernel/vm/testDataBuffer/testDataBuffer.cpp:
  Auto merged
storage/ndb/src/kernel/vm/testLongSig/testLongSig.cpp:
  Auto merged
storage/ndb/src/kernel/vm/testSimplePropertiesSection/test.cpp:
  Auto merged
storage/ndb/src/kernel/vm/testSuperPool.cpp:
  Auto merged
storage/ndb/src/mgmapi/LocalConfig.cpp:
  Auto merged
storage/ndb/src/mgmapi/LocalConfig.hpp:
  Auto merged
storage/ndb/src/mgmapi/mgmapi.cpp:
  Auto merged
storage/ndb/src/mgmapi/mgmapi_configuration.hpp:
  Auto merged
storage/ndb/src/mgmapi/mgmapi_internal.h:
  Auto merged
storage/ndb/src/mgmapi/ndb_logevent.cpp:
  Auto merged
storage/ndb/src/mgmapi/ndb_logevent.hpp:
  Auto merged
storage/ndb/src/mgmapi/test/keso.c:
  Auto merged
storage/ndb/src/mgmapi/test/mgmSrvApi.cpp:
  Auto merged
storage/ndb/src/mgmclient/CommandInterpreter.cpp:
  Auto merged
storage/ndb/src/mgmclient/main.cpp:
  Auto merged
storage/ndb/src/mgmclient/ndb_mgmclient.hpp:
  Auto merged
storage/ndb/src/mgmclient/ndb_mgmclient.h:
  Auto merged
storage/ndb/src/mgmclient/test_cpcd/test_cpcd.cpp:
  Auto merged
storage/ndb/src/mgmsrv/Config.cpp:
  Auto merged
storage/ndb/src/mgmsrv/Config.hpp:
  Auto merged
storage/ndb/src/mgmsrv/ConfigInfo.cpp:
  Auto merged
storage/ndb/src/mgmsrv/ConfigInfo.hpp:
  Auto merged
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
  Auto merged
storage/ndb/src/mgmsrv/InitConfigFileParser.hpp:
  Auto merged
storage/ndb/src/mgmsrv/MgmtSrvr.cpp:
  Auto merged
storage/ndb/src/mgmsrv/MgmtSrvr.hpp:
  Auto merged
storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp:
  Auto merged
storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp:
  Auto merged
storage/ndb/src/mgmsrv/Services.cpp:
  Auto merged
storage/ndb/src/mgmsrv/Services.hpp:
  Auto merged
storage/ndb/src/mgmsrv/SignalQueue.cpp:
  Auto merged
storage/ndb/src/mgmsrv/SignalQueue.hpp:
  Auto merged
storage/ndb/src/mgmsrv/convertStrToInt.cpp:
  Auto merged
storage/ndb/src/mgmsrv/convertStrToInt.hpp:
  Auto merged
storage/ndb/src/mgmsrv/main.cpp:
  Auto merged
storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp:
  Auto merged
storage/ndb/src/ndbapi/API.hpp:
  Auto merged
storage/ndb/src/ndbapi/ClusterMgr.cpp:
  Auto merged
storage/ndb/src/ndbapi/ClusterMgr.hpp:
  Auto merged
storage/ndb/src/ndbapi/DictCache.cpp:
  Auto merged
storage/ndb/src/ndbapi/DictCache.hpp:
  Auto merged
storage/ndb/src/ndbapi/Ndb.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbApiSignal.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbApiSignal.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbBlob.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbBlobImpl.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbDictionary.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbErrorOut.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbEventOperation.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbImpl.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbIndexOperation.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbLinHash.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbOperation.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbOperationDefine.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbOperationExec.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbOperationInt.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbOperationScan.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbOperationSearch.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbPool.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbPoolImpl.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbPoolImpl.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbRecAttr.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbReceiver.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbScanFilter.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbScanOperation.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbTransaction.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbTransactionScan.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbUtil.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbUtil.hpp:
  Auto merged
storage/ndb/src/ndbapi/NdbWaiter.hpp:
  Auto merged
storage/ndb/src/ndbapi/Ndberr.cpp:
  Auto merged
storage/ndb/src/ndbapi/Ndbif.cpp:
  Auto merged
storage/ndb/src/ndbapi/Ndbinit.cpp:
  Auto merged
storage/ndb/src/ndbapi/Ndblist.cpp:
  Auto merged
storage/ndb/src/ndbapi/ObjectMap.hpp:
  Auto merged
storage/ndb/src/ndbapi/SignalSender.cpp:
  Auto merged
storage/ndb/src/ndbapi/SignalSender.hpp:
  Auto merged
storage/ndb/src/ndbapi/TransporterFacade.cpp:
  Auto merged
storage/ndb/src/ndbapi/TransporterFacade.hpp:
  Auto merged
storage/ndb/src/ndbapi/ndb_cluster_connection.cpp:
  Auto merged
storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp:
  Auto merged
storage/ndb/src/ndbapi/ndberror.c:
  Auto merged
storage/ndb/src/ndbapi/signal-sender/SignalSender.cpp:
  Auto merged
storage/ndb/src/ndbapi/signal-sender/SignalSender.hpp:
  Auto merged
storage/ndb/test/include/CpcClient.hpp:
  Auto merged
storage/ndb/test/include/HugoAsynchTransactions.hpp:
  Auto merged
storage/ndb/test/include/HugoCalculator.hpp:
  Auto merged
storage/ndb/test/include/HugoOperations.hpp:
  Auto merged
storage/ndb/test/include/HugoTransactions.hpp:
  Auto merged
storage/ndb/test/include/NDBT.hpp:
  Auto merged
storage/ndb/test/include/NDBT_DataSet.hpp:
  Auto merged
storage/ndb/test/include/NDBT_DataSetTransaction.hpp:
  Auto merged
storage/ndb/test/include/NDBT_Error.hpp:
  Auto merged
storage/ndb/test/include/NDBT_Output.hpp:
  Auto merged
storage/ndb/test/include/NDBT_ResultRow.hpp:
  Auto merged
storage/ndb/test/include/NDBT_ReturnCodes.h:
  Auto merged
storage/ndb/test/include/NDBT_Stats.hpp:
  Auto merged
storage/ndb/test/include/NDBT_Table.hpp:
  Auto merged
storage/ndb/test/include/NDBT_Tables.hpp:
  Auto merged
storage/ndb/test/include/NDBT_Test.hpp:
  Auto merged
storage/ndb/test/include/NdbBackup.hpp:
  Auto merged
storage/ndb/test/include/NdbConfig.hpp:
  Auto merged
storage/ndb/test/include/NdbGrep.hpp:
  Auto merged
storage/ndb/test/include/NdbRestarter.hpp:
  Auto merged
storage/ndb/test/include/NdbRestarts.hpp:
  Auto merged
storage/ndb/test/include/NdbSchemaCon.hpp:
  Auto merged
storage/ndb/test/include/NdbSchemaOp.hpp:
  Auto merged
storage/ndb/test/include/NdbTest.hpp:
  Auto merged
storage/ndb/test/include/NdbTimer.hpp:
  Auto merged
storage/ndb/test/include/TestNdbEventOperation.hpp:
  Auto merged
storage/ndb/test/include/UtilTransactions.hpp:
  Auto merged
storage/ndb/test/include/getarg.h:
  Auto merged
storage/ndb/test/ndbapi/InsertRecs.cpp:
  Auto merged
storage/ndb/test/ndbapi/ScanFilter.hpp:
  Auto merged
storage/ndb/test/ndbapi/ScanFunctions.hpp:
  Auto merged
storage/ndb/test/ndbapi/ScanInterpretTest.hpp:
  Auto merged
storage/ndb/test/ndbapi/TraceNdbApi.cpp:
  Auto merged
storage/ndb/test/ndbapi/VerifyNdbApi.cpp:
  Auto merged
storage/ndb/test/ndbapi/acid.cpp:
  Auto merged
storage/ndb/test/ndbapi/acid2.cpp:
  Auto merged
storage/ndb/test/ndbapi/adoInsertRecs.cpp:
  Auto merged
storage/ndb/test/ndbapi/asyncGenerator.cpp:
  Auto merged
storage/ndb/test/ndbapi/benchronja.cpp:
  Auto merged
storage/ndb/test/ndbapi/bulk_copy.cpp:
  Auto merged
storage/ndb/test/ndbapi/cdrserver.cpp:
  Auto merged
storage/ndb/test/ndbapi/celloDb.cpp:
  Auto merged
storage/ndb/test/ndbapi/create_all_tabs.cpp:
  Auto merged
storage/ndb/test/ndbapi/create_tab.cpp:
  Auto merged
storage/ndb/test/ndbapi/drop_all_tabs.cpp:
  Auto merged
storage/ndb/test/ndbapi/flexAsynch.cpp:
  Auto merged
storage/ndb/test/ndbapi/flexBench.cpp:
  Auto merged
storage/ndb/test/ndbapi/flexHammer.cpp:
  Auto merged
storage/ndb/test/ndbapi/flexScan.cpp:
  Auto merged
storage/ndb/test/ndbapi/flexTT.cpp:
  Auto merged
storage/ndb/test/ndbapi/flexTimedAsynch.cpp:
  Auto merged
storage/ndb/test/ndbapi/flex_bench_mysql.cpp:
  Auto merged
storage/ndb/test/ndbapi/index.cpp:
  Auto merged
storage/ndb/test/ndbapi/index2.cpp:
  Auto merged
storage/ndb/test/ndbapi/initronja.cpp:
  Auto merged
storage/ndb/test/ndbapi/interpreterInTup.cpp:
  Auto merged
storage/ndb/test/ndbapi/mainAsyncGenerator.cpp:
  Auto merged
storage/ndb/test/ndbapi/msa.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_async1.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_async2.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_populate.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_transaction.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_transaction2.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_transaction3.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_transaction4.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_transaction5.cpp:
  Auto merged
storage/ndb/test/ndbapi/ndb_user_transaction6.cpp:
  Auto merged
storage/ndb/test/ndbapi/restarter.cpp:
  Auto merged
storage/ndb/test/ndbapi/restarter2.cpp:
  Auto merged
storage/ndb/test/ndbapi/restarts.cpp:
  Auto merged
storage/ndb/test/ndbapi/size.cpp:
  Auto merged
storage/ndb/test/ndbapi/testBackup.cpp:
  Auto merged
storage/ndb/test/ndbapi/testBasic.cpp:
  Auto merged
storage/ndb/test/ndbapi/testBasicAsynch.cpp:
  Auto merged
storage/ndb/test/ndbapi/testBlobs.cpp:
  Auto merged
storage/ndb/test/ndbapi/testDataBuffers.cpp:
  Auto merged
storage/ndb/test/ndbapi/testDeadlock.cpp:
  Auto merged
storage/ndb/test/ndbapi/testDict.cpp:
  Auto merged
storage/ndb/test/ndbapi/testGrepVerify.cpp:
  Auto merged
storage/ndb/test/ndbapi/testIndex.cpp:
  Auto merged
storage/ndb/test/ndbapi/testInterpreter.cpp:
  Auto merged
storage/ndb/test/ndbapi/testMgm.cpp:
  Auto merged
storage/ndb/test/ndbapi/testNdbApi.cpp:
  Auto merged
storage/ndb/test/ndbapi/testNodeRestart.cpp:
  Auto merged
storage/ndb/test/ndbapi/testOIBasic.cpp:
  Auto merged
storage/ndb/test/ndbapi/testOperations.cpp:
  Auto merged
storage/ndb/test/ndbapi/testOrderedIndex.cpp:
  Auto merged
storage/ndb/test/ndbapi/testPartitioning.cpp:
  Auto merged
storage/ndb/test/ndbapi/testReadPerf.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/Bank.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/Bank.hpp:
  Auto merged
storage/ndb/test/ndbapi/bank/BankLoad.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/bankCreator.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/bankMakeGL.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/bankSumAccounts.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/bankTimer.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/bankTransactionMaker.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp:
  Auto merged
storage/ndb/test/ndbapi/bank/testBank.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/asyncGenerator.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/dbGenerator.h:
  Auto merged
storage/ndb/test/ndbapi/bench/dbPopulate.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/dbPopulate.h:
  Auto merged
storage/ndb/test/ndbapi/bench/macros.h:
  Auto merged
storage/ndb/test/ndbapi/bench/mainAsyncGenerator.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/mainPopulate.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_async1.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_async2.cpp:
  Auto merged
storage/ndb/test/ndbapi/testRestartGci.cpp:
  Auto merged
storage/ndb/test/ndbapi/testSRBank.cpp:
  Auto merged
storage/ndb/test/ndbapi/testScan.cpp:
  Auto merged
storage/ndb/test/ndbapi/testScanInterpreter.cpp:
  Auto merged
storage/ndb/test/ndbapi/testScanPerf.cpp:
  Auto merged
storage/ndb/test/ndbapi/testSystemRestart.cpp:
  Auto merged
storage/ndb/test/ndbapi/testTimeout.cpp:
  Auto merged
storage/ndb/test/ndbapi/testTransactions.cpp:
  Auto merged
storage/ndb/test/ndbapi/test_event.cpp:
  Auto merged
storage/ndb/test/ndbapi/test_event_merge.cpp:
  Auto merged
storage/ndb/test/ndbapi/test_event_multi_table.cpp:
  Auto merged
storage/ndb/test/ndbapi/userInterface.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_error.hpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_schema.hpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_user_transaction.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_user_transaction2.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_user_transaction3.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_user_transaction4.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_user_transaction5.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/ndb_user_transaction6.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/testData.h:
  Auto merged
storage/ndb/test/ndbapi/bench/testDefinitions.h:
  Auto merged
storage/ndb/test/ndbapi/bench/userInterface.cpp:
  Auto merged
storage/ndb/test/ndbapi/bench/userInterface.h:
  Auto merged
storage/ndb/test/newtonapi/basic_test/basic/basic.cpp:
  Auto merged
storage/ndb/test/newtonapi/basic_test/bulk_read/br_test.cpp:
  Auto merged
storage/ndb/test/newtonapi/basic_test/common.cpp:
  Auto merged
storage/ndb/test/newtonapi/basic_test/common.hpp:
  Auto merged
storage/ndb/test/newtonapi/basic_test/ptr_binding/ptr_binding_test.cpp:
  Auto merged
storage/ndb/test/newtonapi/basic_test/too_basic.cpp:
  Auto merged
storage/ndb/test/newtonapi/perf_test/perf.cpp:
  Auto merged
storage/ndb/test/odbc/SQL99_test/SQL99_test.cpp:
  Auto merged
storage/ndb/test/odbc/SQL99_test/SQL99_test.h:
  Auto merged
storage/ndb/test/odbc/client/NDBT_ALLOCHANDLE.cpp:
  Auto merged
storage/ndb/test/odbc/client/NDBT_ALLOCHANDLE_HDBC.cpp:
  Auto merged
storage/ndb/test/odbc/client/NDBT_SQLConnect.cpp:
  Auto merged
storage/ndb/test/odbc/client/NDBT_SQLPrepare.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLAllocEnvTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLAllocHandleTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLAllocHandleTest_bf.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLBindColTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLBindParameterTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLCancelTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLCloseCursorTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLColAttributeTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLColAttributeTest1.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLColAttributeTest2.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLColAttributeTest3.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLConnectTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLCopyDescTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLDescribeColTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLDisconnectTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLDriverConnectTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLEndTranTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLErrorTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLExecDirectTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLExecuteTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLFetchScrollTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLFetchTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLFreeHandleTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLFreeStmtTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetConnectAttrTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetCursorNameTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetDataTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetDescFieldTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetDescRecTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetDiagFieldTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetDiagRecSimpleTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetDiagRecTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetEnvAttrTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetFunctionsTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetInfoTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetStmtAttrTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLGetTypeInfoTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLMoreResultsTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLNumResultColsTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLParamDataTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLPrepareTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLPutDataTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLRowCountTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLSetConnectAttrTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLSetCursorNameTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLSetDescFieldTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLSetDescRecTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLSetEnvAttrTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLSetStmtAttrTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLTablesTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/SQLTransactTest.cpp:
  Auto merged
storage/ndb/test/odbc/client/common.hpp:
  Auto merged
storage/ndb/test/odbc/client/main.cpp:
  Auto merged
storage/ndb/test/odbc/driver/testOdbcDriver.cpp:
  Auto merged
storage/ndb/test/odbc/test_compiler/test_compiler.cpp:
  Auto merged
storage/ndb/test/run-test/main.cpp:
  Auto merged
storage/ndb/test/run-test/run-test.hpp:
  Auto merged
storage/ndb/test/src/CpcClient.cpp:
  Auto merged
storage/ndb/test/src/HugoAsynchTransactions.cpp:
  Auto merged
storage/ndb/test/src/HugoCalculator.cpp:
  Auto merged
storage/ndb/test/src/HugoOperations.cpp:
  Auto merged
storage/ndb/test/src/HugoTransactions.cpp:
  Auto merged
storage/ndb/test/src/NDBT_Error.cpp:
  Auto merged
storage/ndb/test/src/NDBT_Output.cpp:
  Auto merged
storage/ndb/test/src/NDBT_ResultRow.cpp:
  Auto merged
storage/ndb/test/src/NDBT_ReturnCodes.cpp:
  Auto merged
storage/ndb/test/src/NDBT_Table.cpp:
  Auto merged
storage/ndb/test/src/NDBT_Tables.cpp:
  Auto merged
storage/ndb/test/src/NDBT_Test.cpp:
  Auto merged
storage/ndb/test/src/NdbBackup.cpp:
  Auto merged
storage/ndb/test/src/NdbConfig.cpp:
  Auto merged
storage/ndb/test/src/NdbGrep.cpp:
  Auto merged
storage/ndb/test/src/NdbRestarter.cpp:
  Auto merged
storage/ndb/test/src/NdbRestarts.cpp:
  Auto merged
storage/ndb/test/src/NdbSchemaCon.cpp:
  Auto merged
storage/ndb/test/src/NdbSchemaOp.cpp:
  Auto merged
storage/ndb/test/src/UtilTransactions.cpp:
  Auto merged
storage/ndb/test/tools/copy_tab.cpp:
  Auto merged
storage/ndb/test/tools/cpcc.cpp:
  Auto merged
storage/ndb/test/tools/create_index.cpp:
  Auto merged
storage/ndb/test/tools/hugoCalculator.cpp:
  Auto merged
storage/ndb/test/tools/hugoFill.cpp:
  Auto merged
storage/ndb/test/tools/hugoLoad.cpp:
  Auto merged
storage/ndb/test/tools/hugoLockRecords.cpp:
  Auto merged
storage/ndb/test/tools/hugoPkDelete.cpp:
  Auto merged
storage/ndb/test/tools/hugoPkRead.cpp:
  Auto merged
storage/ndb/test/tools/hugoPkReadRecord.cpp:
  Auto merged
storage/ndb/test/tools/hugoPkUpdate.cpp:
  Auto merged
storage/ndb/test/tools/hugoScanRead.cpp:
  Auto merged
storage/ndb/test/tools/hugoScanUpdate.cpp:
  Auto merged
storage/ndb/test/tools/restart.cpp:
  Auto merged
storage/ndb/test/tools/transproxy.cpp:
  Auto merged
storage/ndb/test/tools/verify_index.cpp:
  Auto merged
storage/ndb/tools/delete_all.cpp:
  Auto merged
storage/ndb/tools/desc.cpp:
  Auto merged
storage/ndb/tools/drop_index.cpp:
  Auto merged
storage/ndb/tools/drop_tab.cpp:
  Auto merged
storage/ndb/tools/listTables.cpp:
  Auto merged
storage/ndb/tools/ndb_condig.cpp:
  Auto merged
storage/ndb/tools/ndb_test_platform.cpp:
  Auto merged
storage/ndb/tools/ndbsql.cpp:
  Auto merged
storage/ndb/tools/restore/Restore.cpp:
  Auto merged
storage/ndb/tools/restore/Restore.hpp:
  Auto merged
storage/ndb/tools/restore/consumer.cpp:
  Auto merged
storage/ndb/tools/restore/consumer.hpp:
  Auto merged
storage/ndb/tools/restore/consumer_printer.cpp:
  Auto merged
storage/ndb/tools/restore/consumer_printer.hpp:
  Auto merged
storage/ndb/tools/restore/consumer_restore.cpp:
  Auto merged
storage/ndb/tools/restore/consumer_restore.hpp:
  Auto merged
storage/ndb/tools/restore/consumer_restorem.cpp:
  Auto merged
storage/ndb/tools/restore/restore_main.cpp:
  Auto merged
storage/ndb/tools/select_all.cpp:
  Auto merged
storage/ndb/tools/select_count.cpp:
  Auto merged
storage/ndb/tools/waiter.cpp:
  Auto merged
strings/Makefile.am:
  Auto merged
strings/ctype-big5.c:
  Auto merged
strings/ctype-bin.c:
  Auto merged
strings/ctype-cp932.c:
  Auto merged
strings/ctype-euc_kr.c:
  Auto merged
strings/ctype-eucjpms.c:
  Auto merged
strings/ctype-gb2312.c:
  Auto merged
strings/ctype-gbk.c:
  Auto merged
strings/ctype-latin1.c:
  Auto merged
strings/ctype-mb.c:
  Auto merged
strings/ctype-simple.c:
  Auto merged
strings/ctype-sjis.c:
  Auto merged
strings/ctype-tis620.c:
  Auto merged
strings/ctype-ucs2.c:
  Auto merged
strings/ctype-ujis.c:
  Auto merged
strings/ctype-utf8.c:
  Auto merged
strings/ctype-win1250ch.c:
  Auto merged
strings/ctype.c:
  Auto merged
strings/decimal.c:
  Auto merged
strings/strxnmov.c:
  Auto merged
strings/xml.c:
  Auto merged
tests/Makefile.am:
  Auto merged
tests/mysql_client_test.c:
  Auto merged
vio/Makefile.am:
  Auto merged
vio/vio.c:
  Auto merged
vio/viosocket.c:
  Auto merged
vio/viossl.c:
  Auto merged
vio/viosslfactories.c:
  Auto merged
zlib/Makefile.am:
  Auto merged
2006-12-23 20:20:40 +01:00

4948 lines
158 KiB
C++
Raw Blame History

/* Copyright (C) 2003 MySQL 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
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
* testOdbcDriver
*
* Test of ODBC and SQL using a fixed set of tables.
*/
#include <ndb_global.h>
#undef test
#include <ndb_version.h>
#include <kernel/ndb_limits.h>
#include <Bitmask.hpp>
#include <kernel/AttributeList.hpp>
#ifdef ndbODBC
#include <NdbApi.hpp>
#endif
#include <sqlext.h>
#undef BOOL
#include <NdbMain.h>
#include <NdbOut.hpp>
#include <NdbThread.h>
#include <NdbMutex.h>
#include <NdbCondition.h>
#include <NdbTick.h>
#include <NdbSleep.h>
#ifdef ndbODBC
#include <NdbTest.hpp>
#else
#define NDBT_OK 0
#define NDBT_FAILED 1
#define NDBT_WRONGARGS 2
static int
NDBT_ProgramExit(int rcode)
{
const char* rtext = "Unknown";
switch (rcode) {
case NDBT_OK:
rtext = "OK";
break;
case NDBT_FAILED:
rtext = "Failed";
break;
case NDBT_WRONGARGS:
rtext = "Wrong arguments";
break;
};
ndbout_c("\nNDBT_ProgramExit: %d - %s\n", rcode, rtext);
return rcode;
}
#endif
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#define arraySize(x) (sizeof(x)/sizeof(x[0]))
#define SQL_ATTR_NDB_TUPLES_FETCHED 66601
// options
#define MAX_THR 128 // max threads
struct Opt {
const char* m_name[100];
unsigned m_namecnt;
bool m_core;
unsigned m_depth;
const char* m_dsn;
unsigned m_errs;
const char* m_fragtype;
unsigned m_frob;
const char* m_home;
unsigned m_loop;
bool m_nogetd;
bool m_noputd;
bool m_nosort;
unsigned m_scale;
bool m_serial;
const char* m_skip[100];
unsigned m_skipcnt;
unsigned m_subloop;
const char* m_table;
unsigned m_threads;
unsigned m_trace;
unsigned m_v;
Opt() :
m_namecnt(0),
m_core(false),
m_depth(5),
m_dsn("NDB"),
m_errs(0),
m_fragtype(0),
m_frob(0),
m_home(0),
m_loop(1),
m_nogetd(false),
m_noputd(false),
m_nosort(false),
m_scale(100),
m_serial(false),
m_skipcnt(0),
m_subloop(1),
m_table(0),
m_threads(1),
m_trace(0),
m_v(1) {
for (unsigned i = 0; i < arraySize(m_name); i++)
m_name[i] = 0;
for (unsigned i = 0; i < arraySize(m_skip); i++)
m_skip[i] = 0;
}
};
static Opt opt;
static void listCases();
static void listTables();
static void printusage()
{
Opt d;
ndbout
<< "usage: testOdbcDriver [options]" << endl
<< "-case name run only named tests (substring match - can be repeated)" << endl
<< "-core dump core on failure" << endl
<< "-depth N join depth - default " << d.m_depth << endl
<< "-dsn string data source name - default " << d.m_dsn << endl
<< "-errs N allow N errors before quitting - default " << d.m_errs << endl
<< "-fragtype t fragment type single/small/medium/large" << d.m_errs << endl
<< "-frob X case-dependent tweak (number)" << endl
<< "-home dir set NDB_HOME (contains Ndb.cfg)" << endl
<< "-loop N loop N times (0 = forever) - default " << d.m_loop << endl
<< "-nogetd do not use SQLGetData - default " << d.m_nogetd << endl
<< "-noputd do not use SQLPutData - default " << d.m_noputd << endl
<< "-nosort no order-by in verify scan (checks non-Pk values only)" << endl
<< "-scale N row count etc - default " << d.m_scale << endl
<< "-serial run multi-threaded test cases one at a time" << endl
<< "-skip name skip named tests (substring match - can be repeated)" << endl
<< "-subloop N loop count per case (same threads) - default " << d.m_subloop << endl
<< "-table T do only table T (table name on built-in list)" << endl
<< "-threads N number of threads (max " << MAX_THR << ") - default " << d.m_threads << endl
<< "-trace N trace in NDB ODBC driver - default " << d.m_trace << endl
<< "-v N verbosity - default " << d.m_v << endl
;
listCases();
listTables();
}
static void
fatal(const char* fmt, ...)
{
va_list ap;
char buf[200];
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
ndbout << buf << endl;
if (opt.m_errs != 0) {
opt.m_errs--;
return;
}
if (opt.m_core)
abort();
NDBT_ProgramExit(NDBT_FAILED);
exit(1);
}
static void
cleanprint(const char* s, unsigned n)
{
for (unsigned i = 0; i < n; i++) {
char b[10];
if (0x20 < s[i] && s[i] <= 0x7e)
sprintf(b, "%c", s[i]);
else
sprintf(b, "\\%02x", (unsigned)s[i]);
ndbout << b;
}
}
// global mutex
static NdbMutex my_mutex = NDB_MUTEX_INITIALIZER;
static void lock_mutex() { NdbMutex_Lock(&my_mutex); }
static void unlock_mutex() { NdbMutex_Unlock(&my_mutex); }
// semaphore zeroed before each call to a test routine
static unsigned my_sema = 0;
// print mutex
static NdbMutex out_mutex = NDB_MUTEX_INITIALIZER;
static NdbOut& lock(NdbOut& out) { NdbMutex_Lock(&out_mutex); return out; }
static NdbOut& unlock(NdbOut& out) { NdbMutex_Unlock(&out_mutex); return out; }
static unsigned
urandom(unsigned n)
{
assert(n != 0);
unsigned i = random();
return i % n;
}
// test cases
struct Test;
struct Case {
enum Mode {
Single = 1, // single thread
Serial = 2, // all threads but one at a time
Thread = 3 // all threads in parallel
};
const char* m_name;
void (*m_func)(Test& test);
Mode m_mode;
unsigned m_stuff;
const char* m_desc;
Case(const char* name, void (*func)(Test& test), Mode mode, unsigned stuff, const char* desc) :
m_name(name),
m_func(func),
m_mode(mode),
m_stuff(stuff),
m_desc(desc) {
}
const char* modename() const {
const char* s = "?";
if (m_mode == Case::Single)
return "Single";
if (m_mode == Case::Serial)
return "Serial";
if (m_mode == Case::Thread)
return "Thread";
return "?";
}
bool matchcase() const {
if (opt.m_namecnt == 0)
return ! skipcase();
for (unsigned i = 0; i < opt.m_namecnt; i++) {
if (strstr(m_name, opt.m_name[i]) != 0)
return ! skipcase();
}
return false;
}
private:
bool skipcase() const {
for (unsigned i = 0; i < opt.m_skipcnt; i++) {
if (strstr(m_name, opt.m_skip[i]) != 0)
return true;
}
return false;
}
};
// calculate values
struct Calc {
enum { m_mul = 1000000 };
unsigned m_no;
unsigned m_base;
unsigned m_salt; // modifies non-PK values
bool m_const; // base non-PK values on PK of row 0
Calc(unsigned no) :
m_no(no),
m_salt(0),
m_const(false) {
m_base = m_no * m_mul;
}
void calcPk(unsigned rownum, char* v, unsigned n) const {
char b[10];
sprintf(b, "%08x", m_base + rownum);
for (unsigned i = 0; i < n; i++) {
char c = i < n - 1 ? b[i % 8] : 0;
v[i] = c;
}
}
void calcPk(unsigned rownum, long* v) const {
*v = m_base + rownum;
}
void hashPk(unsigned* hash, const char* v, unsigned n) const {
for (unsigned i = 0; i < n; i++) {
*hash ^= (v[i] << i);
}
}
void hashPk(unsigned* hash, long v) const {
*hash ^= v;
}
void calcNk(unsigned hash, char* v, unsigned n, SQLINTEGER* ind, bool null) const {
unsigned m = hash % n;
for (unsigned i = 0; i < n; i++) {
char c = i < m ? 'a' + (hash + i) % ('z' - 'a' + 1) : i < n - 1 ? ' ' : 0;
v[i] = c;
}
*ind = null && hash % 9 == 0 ? SQL_NULL_DATA : SQL_NTS;
}
void calcNk(unsigned hash, long* v, SQLINTEGER* ind, bool null) const {
*v = long(hash);
*ind = null && hash % 7 == 0 ? SQL_NULL_DATA : 0;
}
void calcNk(unsigned hash, double* v, SQLINTEGER* ind, bool null) const {
*v = long(hash) / 1000.0;
*ind = null && hash % 5 == 0 ? SQL_NULL_DATA : 0;
}
bool verify(const char* v1, SQLINTEGER ind1, const char* v2, SQLINTEGER ind2, unsigned n) {
if (ind1 == SQL_NULL_DATA && ind2 == SQL_NULL_DATA)
return true;
if (ind1 != SQL_NULL_DATA && ind2 != SQL_NULL_DATA)
if (memcmp(v1, v2, n) == 0)
return true;
if (ind1 == SQL_NULL_DATA)
v1 = "NULL";
if (ind2 == SQL_NULL_DATA)
v2 = "NULL";
ndbout << "verify failed: got ";
if (ind1 == SQL_NULL_DATA)
ndbout << "NULL";
else
cleanprint(v1, n);
ndbout << " != ";
if (ind2 == SQL_NULL_DATA)
ndbout << "NULL";
else
cleanprint(v2, n);
ndbout << endl;
return false;
}
bool verify(long v1, SQLINTEGER ind1, long v2, SQLINTEGER ind2) {
char buf1[40], buf2[40];
if (ind1 == SQL_NULL_DATA && ind2 == SQL_NULL_DATA)
return true;
if (ind1 != SQL_NULL_DATA && ind2 != SQL_NULL_DATA)
if (v1 == v2)
return true;
if (ind1 == SQL_NULL_DATA)
strcpy(buf1, "NULL");
else
sprintf(buf1, "%ld", v1);
if (ind2 == SQL_NULL_DATA)
strcpy(buf2, "NULL");
else
sprintf(buf2, "%ld", v2);
ndbout << "verify failed: got " << buf1 << " != " << buf2 << endl;
return false;
}
bool verify(double v1, SQLINTEGER ind1, double v2, SQLINTEGER ind2) {
char buf1[40], buf2[40];
if (ind1 == SQL_NULL_DATA && ind2 == SQL_NULL_DATA)
return true;
if (ind1 != SQL_NULL_DATA && ind2 != SQL_NULL_DATA)
if (fabs(v1 - v2) < 1) // XXX
return true;
if (ind1 == SQL_NULL_DATA)
strcpy(buf1, "NULL");
else
sprintf(buf1, "%.10f", v1);
if (ind2 == SQL_NULL_DATA)
strcpy(buf2, "NULL");
else
sprintf(buf2, "%.10f", v2);
ndbout << "verify failed: got " << buf1 << " != " << buf2 << endl;
return false;
}
};
#if defined(NDB_SOLARIS) || defined(NDB_LINUX) || defined(NDB_MACOSX)
#define HAVE_SBRK
#else
#undef HAVE_SBRK
#endif
struct Timer {
Timer() :
m_cnt(0),
m_calls(0),
m_on(0),
m_msec(0)
#ifndef NDB_WIN32
,
m_brk(0),
m_incr(0)
#endif
{
}
void timerOn() {
m_cnt = 0;
m_calls = 0;
m_on = NdbTick_CurrentMillisecond();
#ifdef HAVE_SBRK
m_brk = (int)sbrk(0);
#endif
}
void timerOff() {
m_msec = NdbTick_CurrentMillisecond() - m_on;
if (m_msec <= 0)
m_msec = 1;
#ifdef HAVE_SBRK
m_incr = (int)sbrk(0) - m_brk;
if (m_incr < 0)
m_incr = 0;
#endif
}
void timerCnt(unsigned cnt) {
m_cnt += cnt;
}
void timerCnt(const Timer& timer) {
m_cnt += timer.m_cnt;
m_calls += timer.m_calls;
}
friend NdbOut& operator<<(NdbOut& out, const Timer& timer) {
out << timer.m_cnt << " ( " << 1000 * timer.m_cnt / timer.m_msec << "/sec )";
#ifdef HAVE_SBRK
out << " - " << timer.m_incr << " sbrk";
if (opt.m_namecnt != 0) { // per case meaningless if many cases
if (timer.m_cnt > 0)
out << " ( " << timer.m_incr / timer.m_cnt << "/cnt )";
}
#endif
out << " - " << timer.m_calls << " calls";
return out;
}
protected:
unsigned m_cnt; // count rows or whatever
unsigned m_calls; // count ODBC function calls
NDB_TICKS m_on;
unsigned m_msec;
#ifdef HAVE_SBRK
int m_brk;
int m_incr;
#endif
};
#define MAX_MESSAGE 500
#define MAX_DIAG 20
struct Diag {
char m_state[5+1];
SQLINTEGER m_native;
char m_message[MAX_MESSAGE];
unsigned m_flag; // temp use
Diag() {
strcpy(m_state, "00000");
m_native = 0;
memset(m_message, 0, sizeof(m_message));
m_flag = 0;
}
const char* text() {
snprintf(m_buf, sizeof(m_buf), "%s %d '%s'", m_state, (int)m_native, m_message);
return m_buf;
}
void getDiag(SQLSMALLINT type, SQLHANDLE handle, unsigned k, unsigned count) {
int ret;
SQLSMALLINT length = -1;
memset(m_message, 0, MAX_MESSAGE);
ret = SQLGetDiagRec(type, handle, k, (SQLCHAR*)m_state, &m_native, (SQLCHAR*)m_message, MAX_MESSAGE, &length);
if (k <= count && ret != SQL_SUCCESS)
fatal("SQLGetDiagRec %d of %d: return %d != SQL_SUCCESS", k, count, (int)ret);
if (k <= count && strlen(m_message) != length)
fatal("SQLGetDiagRec %d of %d: message length %d != %d", k, count, strlen(m_message), length);
if (k > count && ret != SQL_NO_DATA)
fatal("SQLGetDiagRec %d of %d: return %d != SQL_NO_DATA", k, count, (int)ret);
m_flag = 0;
}
private:
char m_buf[MAX_MESSAGE];
};
struct Diags {
Diag m_diag[MAX_DIAG];
SQLINTEGER m_diagCount;
SQLINTEGER m_rowCount;
SQLINTEGER m_functionCode;
void getDiags(SQLSMALLINT type, SQLHANDLE handle) {
int ret;
m_diagCount = -1;
ret = SQLGetDiagField(type, handle, 0, SQL_DIAG_NUMBER, &m_diagCount, SQL_IS_INTEGER, 0);
if (ret == SQL_INVALID_HANDLE)
return;
if (ret != SQL_SUCCESS)
fatal("SQLGetDiagField: return %d != SQL_SUCCESS", (int)ret);
if (m_diagCount < 0 || m_diagCount > MAX_DIAG)
fatal("SQLGetDiagField: count %d", (int)m_diagCount);
for (unsigned k = 0; k < MAX_DIAG; k++) {
m_diag[k].getDiag(type, handle, k + 1, m_diagCount);
if (k == m_diagCount + 1)
break;
}
m_rowCount = -1;
m_functionCode = SQL_DIAG_UNKNOWN_STATEMENT;
if (type == SQL_HANDLE_STMT) {
ret = SQLGetDiagField(type, handle, 0, SQL_DIAG_ROW_COUNT, &m_rowCount, SQL_IS_INTEGER, 0);
#ifndef iODBC
if (ret != SQL_SUCCESS)
fatal("SQLGetDiagField: return %d != SQL_SUCCESS", (int)ret);
#endif
ret = SQLGetDiagField(type, handle, 0, SQL_DIAG_DYNAMIC_FUNCTION_CODE, &m_functionCode, SQL_IS_INTEGER, 0);
}
}
void showDiags() {
for (unsigned k = 0; 0 <= m_diagCount && k < m_diagCount; k++) {
Diag& diag = m_diag[k];
ndbout << "diag " << k + 1;
ndbout << (diag.m_flag ? " [*]" : " [ ]");
ndbout << " " << diag.text() << endl;
if (k > 10)
abort();
}
}
};
struct Exp {
int m_ret;
const char* m_state;
SQLINTEGER m_native;
Exp() : m_ret(SQL_SUCCESS), m_state(""), m_native(0) {}
Exp(int ret, const char* state) : m_ret(ret), m_state(state) {}
};
struct Test : Calc, Timer, Diags {
Test(unsigned no, unsigned loop) :
Calc(no),
m_loop(loop),
m_stuff(0),
m_perf(false),
ccp(0) {
exp(SQL_SUCCESS, 0, 0, true);
}
unsigned m_loop; // current loop
Exp m_expList[20]; // expected results
unsigned m_expCount;
int m_ret; // actual return code
int m_stuff; // the stuff of abuse
bool m_perf; // check no diags on success
const Case* ccp; // current case
void exp(int ret, const char* state, SQLINTEGER native, bool reset) {
if (reset)
m_expCount = 0;
unsigned i = m_expCount++;
assert(i < arraySize(m_expList) - 1);
m_expList[i].m_ret = ret;
m_expList[i].m_state = state == 0 ? "" : state;
m_expList[i].m_native = native;
}
void runCase(const Case& cc) {
ccp = &cc;
if (opt.m_v >= 3)
ndbout << cc.m_name << ": start" << endl;
m_rowCount = -1;
NDB_TICKS m_ms1 = NdbTick_CurrentMillisecond();
m_salt = m_loop | (16 << cc.m_stuff);
m_const = cc.m_stuff == 0;
m_stuff = cc.m_stuff;
(*cc.m_func)(*this);
NDB_TICKS m_ms2 = NdbTick_CurrentMillisecond();
}
void run(SQLSMALLINT type, SQLHANDLE handle, int line, int ret) {
m_calls++;
m_ret = ret;
if (m_perf && (m_ret == SQL_SUCCESS))
return;
m_diagCount = 0;
if (handle != SQL_NULL_HANDLE)
getDiags(type, handle);
if (m_diagCount <= 0 && (ret != SQL_SUCCESS && ret != SQL_INVALID_HANDLE && ret != SQL_NEED_DATA && ret != SQL_NO_DATA)) {
fatal("%s: thr %d line %d: ret=%d but no diag records", ccp->m_name, m_no, line, ret);
}
for (unsigned k = 0; 0 <= m_diagCount && k < m_diagCount; k++) {
Diag& diag = m_diag[k];
bool match = false;
for (unsigned i = 0; i < m_expCount; i++) {
if (strcmp(diag.m_state, m_expList[i].m_state) == 0 && (diag.m_native % 10000 == m_expList[i].m_native % 10000 || m_expList[i].m_native == -1)) {
match = true;
diag.m_flag = 0;
continue;
}
diag.m_flag = 1; // mark unexpected
}
if (! match) {
showDiags();
fatal("%s: thr %d line %d: unexpected diag [*] ret=%d cnt=%d", ccp->m_name, m_no, line, (int)ret, (int)m_diagCount);
}
}
bool match = false;
for (unsigned i = 0; i < m_expCount; i++) {
if (ret == m_expList[i].m_ret) {
match = true;
break;
}
}
if (! match) {
showDiags();
fatal("%s: thr %d line %d: ret=%d not expected", ccp->m_name, m_no, line, ret);
}
// reset expected to success
exp(SQL_SUCCESS, 0, 0, true);
}
void chk(SQLSMALLINT type, SQLHANDLE handle, int line, bool match, const char* fmt, ...) {
if (match)
return;
va_list ap;
va_start(ap, fmt);
char buf[500];
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
fatal("%s: thr %d line %d: check failed - %s", ccp->m_name, m_no, line, buf);
}
};
#define HNull 0, SQL_NULL_HANDLE, __LINE__
#define HEnv(h) SQL_HANDLE_ENV, h, __LINE__
#define HDbc(h) SQL_HANDLE_DBC, h, __LINE__
#define HStmt(h) SQL_HANDLE_STMT, h, __LINE__
#define HDesc(h) SQL_HANDLE_DESC, h, __LINE__
// string support
#define MAX_SQL 20000
static void
scopy(char*& ptr, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsprintf(ptr, fmt, ap);
va_end(ap);
ptr += strlen(ptr);
}
static bool
blankeq(const char* s1, const char* s2, bool caseSensitive = false)
{
unsigned n1 = strlen(s1);
unsigned n2 = strlen(s2);
unsigned i = 0;
char c1 = 0;
char c2 = 0;
while (i < n1 || i < n2) {
c1 = i < n1 ? s1[i] : 0x20;
if (! caseSensitive && 'a' <= c1 && c1 <= 'z')
c1 -= 'a' - 'A';
c2 = i < n2 ? s2[i] : 0x20;
if (! caseSensitive && 'a' <= c2 && c2 <= 'z')
c2 -= 'a' - 'A';
if (c1 != c2)
break;
i++;
}
return c1 == c2;
}
// columns and tables
struct Col {
enum Type {
Char = SQL_CHAR,
Varchar = SQL_VARCHAR,
Int = SQL_INTEGER,
Bigint = SQL_BIGINT,
Real = SQL_REAL,
Double = SQL_DOUBLE
};
enum CType {
CChar = SQL_C_CHAR,
CLong = SQL_C_SLONG,
CDouble = SQL_C_DOUBLE
};
enum Cons {
Null, // nullable
NotNull, // not nullable
Pk // part of primary key
};
const char* m_name;
Type m_type;
unsigned m_length;
Cons m_cons;
CType m_ctype;
Col() :
m_type((Type)999) {
}
Col(const char* name, Type type, unsigned length, Cons cons, CType ctype) :
m_name(name),
m_type(type),
m_length(length),
m_cons(cons),
m_ctype(ctype) {
}
unsigned size() const {
switch (m_type) {
case Char:
case Varchar:
return m_length;
case Int:
return 4;
case Bigint:
return 8;
case Real:
return 4;
case Double:
return 8;
}
assert(false);
return 0;
}
unsigned csize() const { // size as char plus terminating null
switch (m_ctype) {
case CChar:
return m_length + 1;
case CLong:
return 12;
case CDouble:
return 24;
}
assert(false);
return 0;
}
void typespec(char*& ptr) const {
switch (m_type) {
case Char:
scopy(ptr, "char(%d)", m_length);
return;
case Varchar:
scopy(ptr, "varchar(%d)", m_length);
return;
case Int:
scopy(ptr, "int");
return;
case Bigint:
scopy(ptr, "bigint");
return;
case Real:
scopy(ptr, "real");
return;
case Double:
scopy(ptr, "float");
return;
}
assert(false);
}
SQLSMALLINT type() const {
return (SQLSMALLINT)m_type;
}
SQLSMALLINT ctype() const {
return (SQLSMALLINT)m_ctype;
}
void create(char*& ptr, bool pk) const {
scopy(ptr, "%s", m_name);
scopy(ptr, " ");
typespec(ptr);
if (m_cons == Pk && pk) {
scopy(ptr, " primary key");
}
if (m_cons == NotNull) {
scopy(ptr, " not null");
}
}
};
static Col ColUndef;
struct Tab {
const char* m_name;
const Col* m_colList;
unsigned m_colCount;
unsigned m_pkCount;
unsigned* m_pkIndex;
unsigned m_nkCount;
unsigned* m_nkIndex;
char m_upperName[20];
Tab(const char* name, const Col* colList, unsigned colCount) :
m_name(name),
m_colList(colList),
m_colCount(colCount) {
m_pkCount = 0;
m_nkCount = 0;
for (unsigned i = 0; i < m_colCount; i++) {
const Col& col = m_colList[i];
if (col.m_cons == Col::Pk)
m_pkCount++;
else
m_nkCount++;
}
m_pkIndex = new unsigned[m_pkCount];
m_nkIndex = new unsigned[m_nkCount];
unsigned pk = 0;
unsigned nk = 0;
for (unsigned i = 0; i < m_colCount; i++) {
const Col& col = m_colList[i];
if (col.m_cons == Col::Pk)
m_pkIndex[pk++] = i;
else
m_nkIndex[nk++] = i;
}
assert(pk == m_pkCount && nk == m_nkCount);
strcpy(m_upperName, m_name);
for (char* p = m_upperName; *p != 0; p++) {
if ('a' <= *p && *p <= 'z')
*p -= 'a' - 'A';
}
}
~Tab() {
delete[] m_pkIndex;
delete[] m_nkIndex;
}
void drop(char*& ptr) const {
scopy(ptr, "drop table %s", m_name);
}
void create(char*& ptr) const {
scopy(ptr, "create table %s (", m_name);
for (unsigned i = 0; i < m_colCount; i++) {
if (i > 0)
scopy(ptr, ", ");
const Col& col = m_colList[i];
col.create(ptr, m_pkCount == 1);
}
if (m_pkCount != 1) {
scopy(ptr, ", primary key (");
for (unsigned i = 0; i < m_pkCount; i++) {
const Col& col = m_colList[m_pkIndex[i]];
if (i > 0)
scopy(ptr, ", ");
scopy(ptr, "%s", col.m_name);
}
scopy(ptr, ")");
}
scopy(ptr, ")");
}
void wherePk(char*& ptr) const {
scopy(ptr, " where");
for (unsigned i = 0; i < m_pkCount; i++) {
const Col& col = m_colList[m_pkIndex[i]];
if (i > 0)
scopy(ptr, " and");
scopy(ptr, " %s = ?", col.m_name);
}
}
void whereRange(char*& ptr) const {
scopy(ptr, " where");
for (unsigned i = 0; i < m_pkCount; i++) {
const Col& col = m_colList[m_pkIndex[i]];
if (i > 0)
scopy(ptr, " and");
scopy(ptr, " ? <= %s", col.m_name);
scopy(ptr, " and ");
scopy(ptr, "%s < ?", col.m_name);
}
}
void orderPk(char*& ptr) const {
scopy(ptr, " order by");
for (unsigned i = 0; i < m_pkCount; i++) {
const Col& col = m_colList[m_pkIndex[i]];
if (i > 0)
scopy(ptr, ", ");
else
scopy(ptr, " ");
scopy(ptr, "%s", col.m_name);
}
}
void selectPk(char*& ptr) const {
scopy(ptr, "select * from %s", m_name);
wherePk(ptr);
}
void selectAll(char*& ptr) const {
scopy(ptr, "select * from %s", m_name);
}
void selectRange(char*& ptr, bool sort) const {
selectAll(ptr);
whereRange(ptr);
if (sort)
orderPk(ptr);
}
void selectCount(char*& ptr) const {
scopy(ptr, "select count(*) from %s", m_name);
}
void insertAll(char*& ptr) const {
scopy(ptr, "insert into %s values (", m_name);
for (unsigned i = 0; i < m_colCount; i++) {
if (i > 0)
scopy(ptr, ", ");
scopy(ptr, "?");
}
scopy(ptr, ")");
}
void updatePk(char*& ptr) const {
scopy(ptr, "update %s set", m_name);
for (unsigned i = 0; i < m_nkCount; i++) {
const Col& col = m_colList[m_nkIndex[i]];
if (i > 0)
scopy(ptr, ", ");
else
scopy(ptr, " ");
scopy(ptr, "%s = ?", col.m_name);
}
wherePk(ptr);
}
void updateRange(char*& ptr) const {
scopy(ptr, "update %s set", m_name);
for (unsigned i = 0; i < m_nkCount; i++) {
const Col& col = m_colList[m_nkIndex[i]];
if (i > 0)
scopy(ptr, ", ");
else
scopy(ptr, " ");
scopy(ptr, "%s = ?", col.m_name); // XXX constant for now
}
whereRange(ptr);
}
void deleteAll(char*& ptr) const {
scopy(ptr, "delete from %s", m_name);
}
void deletePk(char*& ptr) const {
scopy(ptr, "delete from %s", m_name);
wherePk(ptr);
}
void deleteRange(char*& ptr) const {
scopy(ptr, "delete from %s", m_name);
whereRange(ptr);
}
// simple
void insertDirect(char*& ptr, unsigned n) const {
scopy(ptr, "insert into %s values (", m_name);
for (unsigned i = 0; i < m_colCount; i++) {
const Col& col = m_colList[i];
if (i > 0)
scopy(ptr, ", ");
if (col.m_type == Col::Char || col.m_type == Col::Varchar) {
scopy(ptr, "'");
for (unsigned i = 0; i <= n % col.m_length; i++)
scopy(ptr, "%c", 'a' + (n + i) % 26);
scopy(ptr, "'");
} else if (col.m_type == Col::Int || col.m_type == Col::Bigint) {
scopy(ptr, "%u", n);
} else if (col.m_type == Col::Real || col.m_type == Col::Double) {
scopy(ptr, "%.3f", n * 0.001);
} else {
assert(false);
}
}
scopy(ptr, ")");
}
void whereDirect(char*& ptr, unsigned n) const {
scopy(ptr, " where");
for (unsigned i = 0; i < m_pkCount; i++) {
const Col& col = m_colList[m_pkIndex[i]];
if (i > 0)
scopy(ptr, ", ");
else
scopy(ptr, " ");
scopy(ptr, "%s = ", col.m_name);
if (col.m_type == Col::Char || col.m_type == Col::Varchar) {
scopy(ptr, "'");
for (unsigned i = 0; i <= n % col.m_length; i++)
scopy(ptr, "%c", 'a' + (n + i) % 26);
scopy(ptr, "'");
} else if (col.m_type == Col::Int || col.m_type == Col::Bigint) {
scopy(ptr, "%u", n);
} else {
assert(false);
}
}
}
void countDirect(char*& ptr, unsigned n) const {
scopy(ptr, "select count(*) from %s", m_name);
whereDirect(ptr, n);
}
void deleteDirect(char*& ptr, unsigned n) const {
scopy(ptr, "delete from %s", m_name);
whereDirect(ptr, n);
}
// joins
void selectCart(char*& ptr, unsigned cnt) const {
scopy(ptr, "select count(*) from");
for (unsigned j = 0; j < cnt; j++) {
if (j > 0)
scopy(ptr, ",");
scopy(ptr, " %s", m_name);
scopy(ptr, " t%u", j);
}
}
void selectJoin(char*& ptr, unsigned cnt) const {
scopy(ptr, "select * from");
for (unsigned j = 0; j < cnt; j++) {
if (j > 0)
scopy(ptr, ",");
scopy(ptr, " %s", m_name);
scopy(ptr, " t%u", j);
}
for (unsigned i = 0; i < m_pkCount; i++) {
const Col& col = m_colList[m_pkIndex[i]];
for (unsigned j = 0; j < cnt - 1; j++) {
if (i == 0 && j == 0)
scopy(ptr, " where");
else
scopy(ptr, " and");
scopy(ptr, " t%u.%s = t%u.%s", j, col.m_name, j + 1, col.m_name);
}
}
}
// check if selected on command line
bool optok() const {
return opt.m_table == 0 || strcasecmp(m_name, opt.m_table) == 0;
}
};
// the test tables
static Col col0[] = {
Col( "a", Col::Bigint, 0, Col::Pk, Col::CLong ),
Col( "b", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c", Col::Char, 4, Col::NotNull, Col::CChar ),
Col( "d", Col::Double, 0, Col::Null, Col::CDouble ),
Col( "e", Col::Char, 40, Col::Null, Col::CChar ),
Col( "f", Col::Char, 10, Col::Null, Col::CChar )
};
static Col col1[] = {
Col( "c0", Col::Int, 0, Col::Pk, Col::CLong ),
Col( "c1", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c2", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c3", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c4", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c5", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c6", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c7", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c8", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c9", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c10", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c11", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c12", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c13", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c14", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c15", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c16", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c17", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c18", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c19", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c20", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c21", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c22", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c23", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c24", Col::Int, 0, Col::NotNull, Col::CLong ),
Col( "c25", Col::Int, 0, Col::NotNull, Col::CLong )
};
static Col col2[] = {
Col( "a", Col::Int, 0, Col::Pk, Col::CLong ),
Col( "c", Col::Char, 8000, Col::NotNull, Col::CChar )
};
static Col col3[] = {
Col( "a", Col::Int, 0, Col::Pk, Col::CLong ),
Col( "c1", Col::Varchar, 1, Col::Null, Col::CChar ),
Col( "c2", Col::Varchar, 2, Col::Null, Col::CChar ),
Col( "c3", Col::Varchar, 3, Col::Null, Col::CChar ),
Col( "c4", Col::Varchar, 4, Col::Null, Col::CChar ),
Col( "c5", Col::Varchar, 10, Col::Null, Col::CChar ),
Col( "c6", Col::Varchar, 40, Col::Null, Col::CChar ),
Col( "c7", Col::Varchar, 255, Col::Null, Col::CChar ),
Col( "c8", Col::Varchar, 4000, Col::Null, Col::CChar )
};
static Col col4[] = {
Col( "a", Col::Char, 8, Col::Pk, Col::CChar ),
Col( "b", Col::Char, 8, Col::NotNull, Col::CChar ),
};
static Tab tabList[] = {
#define colList(x) x, arraySize(x)
Tab( "tt00", colList(col0) ),
Tab( "tt01", colList(col1) ), // fl<66>skbench special
Tab( "tt02", colList(col2) ),
Tab( "tt03", colList(col3) ),
Tab( "tt04", colList(col4) )
#undef colList
};
static const unsigned tabCount = arraySize(tabList);
static const unsigned maxColCount = 100; // per table - keep up to date
static bool
findTable()
{
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (tab.optok())
return true;
}
return false;
}
static void
listTables()
{
ndbout << "tables:" << endl;
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (i > 0)
ndbout << " ";
ndbout << tab.m_name;
}
ndbout << endl;
}
// data fields and rows
struct Fld {
const Col& m_col;
union {
char* m_char;
long m_long;
double m_double;
};
SQLINTEGER m_ind;
SQLINTEGER m_need; // constant
Fld() :
m_col(ColUndef),
m_need(0) {
}
Fld(const Col& col) :
m_col(col),
m_need(SQL_LEN_DATA_AT_EXEC(0)) {
switch (m_col.m_ctype) {
case Col::CChar:
m_char = new char[m_col.csize()];
memset(m_char, 0, m_col.csize());
break;
case Col::CLong:
m_long = 0;
break;
case Col::CDouble:
m_double = 0.0;
break;
}
m_ind = -1;
}
~Fld() {
switch (m_col.m_ctype) {
case Col::CChar:
delete[] m_char;
break;
case Col::CLong:
break;
case Col::CDouble:
break;
}
}
void zero() {
switch (m_col.m_ctype) {
case Col::CChar:
memset(m_char, 0x1f, m_col.csize());
break;
case Col::CLong:
m_long = 0x1f1f1f1f;
break;
case Col::CDouble:
m_double = 1111111.1111111;
break;
}
m_ind = -1;
}
// copy values from another field
void copy(const Fld& fld) {
assert(&m_col == &fld.m_col);
switch (m_col.m_ctype) {
case Col::CChar:
memcpy(m_char, fld.m_char, m_col.csize());
break;
case Col::CLong:
m_long = fld.m_long;
break;
case Col::CDouble:
m_double = fld.m_double;
break;
default:
assert(false);
break;
}
m_ind = fld.m_ind;
}
SQLPOINTER caddr() {
switch (m_col.m_ctype) {
case Col::CChar:
return (SQLPOINTER)m_char;
case Col::CLong:
return (SQLPOINTER)&m_long;
case Col::CDouble:
return (SQLPOINTER)&m_double;
}
assert(false);
return 0;
}
SQLINTEGER* ind() {
return &m_ind;
}
SQLINTEGER* need() {
m_need = SQL_LEN_DATA_AT_EXEC(0);
return &m_need;
}
void calcPk(const Test& test, unsigned rownum) {
switch (m_col.m_ctype) {
case Col::CChar:
test.calcPk(rownum, m_char, m_col.csize());
m_ind = SQL_NTS;
return;
case Col::CLong:
test.calcPk(rownum, &m_long);
m_ind = 0;
return;
case Col::CDouble:
assert(false);
return;
}
assert(false);
}
void hashPk(const Test& test, unsigned* hash) const {
switch (m_col.m_ctype) {
case Col::CChar:
test.hashPk(hash, m_char, m_col.csize());
return;
case Col::CLong:
test.hashPk(hash, m_long);
return;
case Col::CDouble:
assert(false);
return;
}
assert(false);
}
void calcNk(const Test& test, unsigned hash) {
bool null = m_col.m_cons == Col::Null;
switch (m_col.m_ctype) {
case Col::CChar:
test.calcNk(hash, m_char, m_col.csize(), &m_ind, null);
return;
case Col::CLong:
test.calcNk(hash, &m_long, &m_ind, null);
return;
case Col::CDouble:
test.calcNk(hash, &m_double, &m_ind, null);
return;
}
assert(false);
}
bool verify(Test& test, const Fld& fld) {
assert(&m_col == &fld.m_col);
switch (m_col.m_ctype) {
case Col::CChar:
return test.verify(m_char, m_ind, fld.m_char, fld.m_ind, m_col.csize());
case Col::CLong:
return test.verify(m_long, m_ind, fld.m_long, fld.m_ind);
case Col::CDouble:
return test.verify(m_double, m_ind, fld.m_double, fld.m_ind);
}
assert(false);
return false;
}
// debug
void print() const {
if (m_ind == SQL_NULL_DATA)
ndbout << "NULL";
else {
switch (m_col.m_ctype) {
case Col::CChar:
ndbout << m_char;
break;
case Col::CLong:
ndbout << (int)m_long;
break;
case Col::CDouble:
ndbout << m_double;
break;
}
}
}
};
struct Row {
const Tab& m_tab;
Fld* m_fldList;
Row(const Tab& tab) :
m_tab(tab) {
m_fldList = new Fld[m_tab.m_colCount];
for (unsigned i = 0; i < m_tab.m_colCount; i++) {
const Col& col = m_tab.m_colList[i];
void* place = &m_fldList[i];
new (place) Fld(col);
}
}
~Row() {
delete[] m_fldList;
}
// copy values from another row
void copy(const Row& row) {
assert(&m_tab == &row.m_tab);
for (unsigned i = 0; i < m_tab.m_colCount; i++) {
Fld& fld = m_fldList[i];
fld.copy(row.m_fldList[i]);
}
}
// primary key value is determined by row number
void calcPk(Test& test, unsigned rownum) {
for (unsigned i = 0; i < m_tab.m_pkCount; i++) {
Fld& fld = m_fldList[m_tab.m_pkIndex[i]];
fld.calcPk(test, rownum);
}
}
// other fields are determined by primary key value
void calcNk(Test& test) {
unsigned hash = test.m_salt;
for (unsigned i = 0; i < m_tab.m_pkCount; i++) {
Fld& fld = m_fldList[m_tab.m_pkIndex[i]];
fld.hashPk(test, &hash);
}
for (unsigned i = 0; i < m_tab.m_colCount; i++) {
const Col& col = m_tab.m_colList[i];
if (col.m_cons == Col::Pk)
continue;
Fld& fld = m_fldList[i];
fld.calcNk(test, hash);
}
}
// verify against another row
bool verifyPk(Test& test, const Row& row) const {
assert(&m_tab == &row.m_tab);
for (unsigned i = 0; i < m_tab.m_pkCount; i++) {
Fld& fld = m_fldList[m_tab.m_pkIndex[i]];
if (! fld.verify(test, row.m_fldList[m_tab.m_pkIndex[i]])) {
ndbout << "verify failed: tab=" << m_tab.m_name << " col=" << fld.m_col.m_name << endl;
return false;
}
}
return true;
}
bool verifyNk(Test& test, const Row& row) const {
assert(&m_tab == &row.m_tab);
for (unsigned i = 0; i < m_tab.m_nkCount; i++) {
Fld& fld = m_fldList[m_tab.m_nkIndex[i]];
if (! fld.verify(test, row.m_fldList[m_tab.m_nkIndex[i]])) {
ndbout << "verify failed: tab=" << m_tab.m_name << " col=" << fld.m_col.m_name << endl;
return false;
}
}
return true;
}
bool verify(Test& test, const Row& row) const {
return verifyPk(test, row) && verifyNk(test, row);
}
// debug
void print() const {
ndbout << "row";
for (unsigned i = 0; i < m_tab.m_colCount; i++) {
ndbout << " " << i << "=";
Fld& fld = m_fldList[i];
fld.print();
}
ndbout << endl;
}
};
// set ODBC version - required
static void
setVersion(Test& test, SQLHANDLE hEnv)
{
test.run(HEnv(hEnv), SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER));
}
// set autocommit
static void
setAutocommit(Test& test, SQLHANDLE hDbc, bool on)
{
SQLUINTEGER value = on ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
test.run(HDbc(hDbc), SQLSetConnectAttr(hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)value, SQL_IS_UINTEGER));
SQLUINTEGER value2 = (SQLUINTEGER)-1;
test.run(HDbc(hDbc), SQLGetConnectAttr(hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)&value2, SQL_IS_UINTEGER, 0));
test.chk(HDbc(hDbc), value2 == value, "got %u != %u", (unsigned)value2, (unsigned)value);
}
// subroutines - migrate simple common routines here
static void
allocEnv(Test& test, SQLHANDLE& hEnv)
{
test.run(HNull, SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv));
setVersion(test, hEnv);
}
static void
allocDbc(Test& test, SQLHANDLE hEnv, SQLHANDLE& hDbc)
{
test.run(HEnv(hEnv), SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));
}
static void
allocConn(Test& test, SQLHANDLE hEnv, SQLHANDLE& hDbc)
{
allocDbc(test, hEnv, hDbc);
#ifdef unixODBC
test.exp(SQL_SUCCESS_WITH_INFO, "IM003", 0, false); // unicode??
test.exp(SQL_SUCCESS_WITH_INFO, "01000", 0, false); // version??
#endif
test.run(HDbc(hDbc), SQLConnect(hDbc, (SQLCHAR*)opt.m_dsn, SQL_NTS, (SQLCHAR*)"user", SQL_NTS, (SQLCHAR*)"pass", SQL_NTS));
}
static void
allocStmt(Test& test, SQLHANDLE hDbc, SQLHANDLE& hStmt)
{
test.run(HDbc(hDbc), SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt));
}
static void
allocAll(Test& test, SQLHANDLE& hEnv, SQLHANDLE& hDbc, SQLHANDLE& hStmt)
{
allocEnv(test, hEnv);
allocConn(test, hEnv, hDbc);
allocStmt(test, hDbc, hStmt);
}
static void
allocAll(Test& test, SQLHANDLE& hEnv, SQLHANDLE& hDbc, SQLHANDLE* hStmtList, unsigned nStmt)
{
allocEnv(test, hEnv);
allocConn(test, hEnv, hDbc);
for (unsigned i = 0; i < nStmt; i++)
allocStmt(test, hDbc, hStmtList[i]);
}
static void
freeEnv(Test& test, SQLHANDLE hEnv)
{
test.run(HNull, SQLFreeHandle(SQL_HANDLE_ENV, hEnv));
}
static void
freeDbc(Test& test, SQLHANDLE hEnv, SQLHANDLE hDbc)
{
test.run(HEnv(hEnv), SQLFreeHandle(SQL_HANDLE_DBC, hDbc));
}
static void
freeConn(Test& test, SQLHANDLE hEnv, SQLHANDLE hDbc)
{
test.run(HDbc(hDbc), SQLDisconnect(hDbc));
test.run(HEnv(hEnv), SQLFreeHandle(SQL_HANDLE_DBC, hDbc));
}
static void
freeStmt(Test& test, SQLHANDLE hDbc, SQLHANDLE hStmt)
{
test.run(HDbc(hDbc), SQLFreeHandle(SQL_HANDLE_STMT, hStmt));
}
static void
freeAll(Test& test, SQLHANDLE hEnv, SQLHANDLE hDbc, SQLHANDLE hStmt)
{
freeStmt(test, hDbc, hStmt);
freeConn(test, hEnv, hDbc);
freeEnv(test, hEnv);
}
static void
freeAll(Test& test, SQLHANDLE hEnv, SQLHANDLE hDbc, SQLHANDLE* hStmtList, unsigned nStmt)
{
for (unsigned i = 0; i < nStmt; i++)
freeStmt(test, hDbc, hStmtList[i]);
freeConn(test, hEnv, hDbc);
freeEnv(test, hEnv);
}
#define chkTuplesFetched(/*Test&*/ _test, /*SQLHANDLE*/ _hStmt, /*SQLUINTEGER*/ _countExp) \
do { \
SQLUINTEGER _count = (SQLUINTEGER)-1; \
getTuplesFetched(_test, _hStmt, &_count); \
test.chk(HStmt(_hStmt), _count == _countExp, "tuples: got %ld != %ld", (long)_count, (long)_countExp); \
} while (0)
static void
getTuplesFetched(Test& test, SQLHANDLE hStmt, SQLUINTEGER* count)
{
*count = (SQLUINTEGER)-1;
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_NDB_TUPLES_FETCHED, count, SQL_IS_POINTER, 0));
}
static void
selectCount(Test& test, SQLHANDLE hStmt, const char* sql, long* count)
{
if (opt.m_v >= 3)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
SQLINTEGER ind;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_SLONG, count, 0, &ind));
ind = -1;
*count = -1;
test.run(HStmt(hStmt), SQLExecute(hStmt));
unsigned k = 0;
while (1) {
if (k == 1)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (k == 1)
break;
k++;
}
test.chk(HStmt(hStmt), ind == sizeof(long), "got %d != %d", (int)ind, (int)sizeof(long));
test.chk(HStmt(hStmt), *count >= 0, "got %ld < 0", *count);
chkTuplesFetched(test, hStmt, *count);
#ifndef iODBC
//
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
#else
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_CLOSE));
#endif
}
static void
selectCount(Test& test, SQLHANDLE hStmt, const Tab& tab, long* count)
{
static char sql[MAX_SQL], *sqlptr; // XXX static or core
tab.selectCount(sqlptr = sql);
selectCount(test, hStmt, sql, count);
}
static void
verifyCount(Test& test, SQLHANDLE hStmt, const Tab& tab, long countExp)
{
long count = -1;
selectCount(test, hStmt, tab, &count);
test.chk(HStmt(hStmt), count == countExp, "got %ld != %ld", count, countExp);
}
#define chkRowCount(/*Test&*/ _test, /*SQLHANDLE*/ _hStmt, /*SQLINTEGER*/ _countExp) \
do { \
SQLINTEGER _count = -1; \
getRowCount(_test, _hStmt, &_count); \
test.chk(HStmt(_hStmt), _count == _countExp, "rowcount: got %ld != %ld", (long)_count, (long)_countExp); \
} while (0)
static void
getRowCount(Test& test, SQLHANDLE hStmt, SQLINTEGER* count)
{
*count = -1;
test.run(HStmt(hStmt), SQLRowCount(hStmt, count));
}
// handle allocation
static void
testAlloc(Test& test)
{
const unsigned n1 = (opt.m_scale >> 8) & 0xf; // default 500 = 0x1f4
const unsigned n2 = (opt.m_scale >> 4) & 0xf;
const unsigned n3 = (opt.m_scale >> 0) & 0xf;
const unsigned count = n1 + n1 * n2 + n1 * n2 * n3;
SQLHANDLE hEnvList[0xf];
SQLHANDLE hDbcList[0xf][0xf];
SQLHANDLE hStmtList[0xf][0xf][0xf];
for (unsigned i1 = 0; i1 < n1; i1++) {
SQLHANDLE& hEnv = hEnvList[i1];
test.run(HNull, SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv));
test.run(HEnv(hEnv), SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER));
for (unsigned i2 = 0; i2 < n2; i2++) {
SQLHANDLE& hDbc = hDbcList[i1][i2];
test.run(HEnv(hEnv), SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));
#ifdef unixODBC
test.exp(SQL_SUCCESS_WITH_INFO, "IM003", 0, false); // unicode??
test.exp(SQL_SUCCESS_WITH_INFO, "01000", 0, false); // version??
#endif
test.run(HDbc(hDbc), SQLConnect(hDbc, (SQLCHAR*)opt.m_dsn, SQL_NTS, (SQLCHAR*)"user", SQL_NTS, (SQLCHAR*)"pass", SQL_NTS));
// some attributes
test.exp(SQL_ERROR, "HY092", -1, true); // read-only attribute
test.run(HDbc(hDbc), SQLSetConnectAttr(hDbc, SQL_ATTR_AUTO_IPD, (SQLPOINTER)SQL_TRUE, SQL_IS_UINTEGER));
test.exp(SQL_ERROR, "HYC00", -1, true); // not supported
test.run(HDbc(hDbc), SQLSetConnectAttr(hDbc, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)SQL_TXN_SERIALIZABLE, SQL_IS_UINTEGER));
test.run(HDbc(hDbc), SQLSetConnectAttr(hDbc, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER)"DEFAULT", strlen("DEFAULT")));
for (unsigned i3 = 0; i3 < n3; i3++) {
SQLHANDLE& hStmt = hStmtList[i1][i2][i3];
test.run(HDbc(hDbc), SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt));
SQLHANDLE ipd0, ipd1;
SQLHANDLE ird0, ird1;
SQLHANDLE apd0, apd1, apd2;
SQLHANDLE ard0, ard1, ard2;
// get
ipd0 = ird0 = apd0 = ard0 = 0;
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_IMP_PARAM_DESC, &ipd0, SQL_IS_POINTER, 0));
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_IMP_ROW_DESC, &ird0, SQL_IS_POINTER, 0));
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_APP_PARAM_DESC, &apd0, SQL_IS_POINTER, 0));
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_APP_ROW_DESC, &ard0, SQL_IS_POINTER, 0));
#ifndef unixODBC
test.chk(HStmt(hStmt), ipd0 != 0, "got 0");
test.chk(HStmt(hStmt), ird0 != 0, "got 0");
test.chk(HStmt(hStmt), apd0 != 0, "got 0");
test.chk(HStmt(hStmt), ard0 != 0, "got 0");
#endif
// alloc
ipd1 = ird1 = apd1 = ard1 = 0;
test.run(HDbc(hDbc), SQLAllocHandle(SQL_HANDLE_DESC, hDbc, &ipd1));
test.run(HDbc(hDbc), SQLAllocHandle(SQL_HANDLE_DESC, hDbc, &ird1));
test.run(HDbc(hDbc), SQLAllocHandle(SQL_HANDLE_DESC, hDbc, &apd1));
test.run(HDbc(hDbc), SQLAllocHandle(SQL_HANDLE_DESC, hDbc, &ard1));
test.chk(HDbc(hDbc), ipd1 != 0 && ird1 != 0 && apd1 != 0 && ard1 != 0, "got null");
// set
test.exp(SQL_ERROR, "HY092", -1, true); // read-only attribute
test.run(HStmt(hStmt), SQLSetStmtAttr(hStmt, SQL_ATTR_IMP_PARAM_DESC, ipd1, SQL_IS_POINTER));
test.exp(SQL_ERROR, "HY092", -1, true); // read-only attribute
test.run(HStmt(hStmt), SQLSetStmtAttr(hStmt, SQL_ATTR_IMP_ROW_DESC, ird1, SQL_IS_POINTER));
test.run(HStmt(hStmt), SQLSetStmtAttr(hStmt, SQL_ATTR_APP_PARAM_DESC, apd1, SQL_IS_POINTER));
test.run(HStmt(hStmt), SQLSetStmtAttr(hStmt, SQL_ATTR_APP_ROW_DESC, ard1, SQL_IS_POINTER));
// get
apd2 = ard2 = 0;
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_APP_PARAM_DESC, &apd2, SQL_IS_POINTER, 0));
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_APP_ROW_DESC, &ard2, SQL_IS_POINTER, 0));
test.chk(HStmt(hStmt), apd2 == apd1, "got %x != %x", (unsigned)apd2, (unsigned)apd1);
test.chk(HStmt(hStmt), ard2 == ard1, "got %x != %x", (unsigned)ard2, (unsigned)ard1);
// free
test.run(HDbc(hDbc), SQLFreeHandle(SQL_HANDLE_DESC, ipd1));
test.run(HDbc(hDbc), SQLFreeHandle(SQL_HANDLE_DESC, ird1));
test.run(HDbc(hDbc), SQLFreeHandle(SQL_HANDLE_DESC, apd1));
test.run(HDbc(hDbc), SQLFreeHandle(SQL_HANDLE_DESC, ard1));
}
}
}
test.timerCnt(count);
if (opt.m_v >= 3)
ndbout << "allocated " << count << endl;
for (unsigned i1 = 0; i1 < n1; i1++) {
SQLHANDLE& hEnv = hEnvList[i1];
for (unsigned i2 = 0; i2 < n2; i2++) {
SQLHANDLE& hDbc = hDbcList[i1][i2];
if (i2 % 2 == 0) {
for (unsigned i3 = 0; i3 < n3; i3++) {
SQLHANDLE& hStmt = hStmtList[i1][i2][i3];
test.run(HDbc(hDbc), SQLFreeHandle(SQL_HANDLE_STMT, hStmt));
}
} else {
// cleaned up by SQLDisconnect
}
test.run(HDbc(hDbc), SQLDisconnect(hDbc));
test.run(HEnv(hEnv), SQLFreeHandle(SQL_HANDLE_DBC, hDbc));
}
test.run(HNull, SQLFreeHandle(SQL_HANDLE_ENV, hEnv));
}
test.timerCnt(count);
if (opt.m_v >= 3)
ndbout << "freed " << count << endl;
}
// create tables
static void
testCreate(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
Tab& tab = tabList[i];
if (! tab.optok())
continue;
// drop
tab.drop(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
test.exp(SQL_ERROR, "IM000", 2040709, false);
test.run(HStmt(hStmt), SQLExecute(hStmt));
if (test.m_ret == SQL_SUCCESS)
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_DROP_TABLE, "got %d != %d", test.m_functionCode, SQL_DIAG_DROP_TABLE);
if (test.m_ret == SQL_SUCCESS && opt.m_v >= 2)
ndbout << "table " << tab.m_name << " dropped" << endl;
if (test.m_ret != SQL_SUCCESS && opt.m_v >= 2)
ndbout << "table " << tab.m_name << " does not exist" << endl;
test.timerCnt(1);
// create
tab.create(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
test.exp(SQL_ERROR, "IM000", 2040721, false);
test.run(HStmt(hStmt), SQLExecute(hStmt));
if (test.m_ret == SQL_SUCCESS)
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_CREATE_TABLE, "got %d != %d", test.m_functionCode, SQL_DIAG_CREATE_TABLE);
if (test.m_ret == SQL_SUCCESS && opt.m_v >= 2)
ndbout << "table " << tab.m_name << " created" << endl;
if (test.m_ret != SQL_SUCCESS && opt.m_v >= 2)
ndbout << "table " << tab.m_name << " already exists" << endl;
test.timerCnt(1);
}
freeAll(test, hEnv, hDbc, hStmt);
}
// prepare without execute
static void
testPrepare(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
char sql[MAX_SQL], *sqlptr;
for (unsigned cnt = opt.m_depth; cnt <= opt.m_depth; cnt++) {
for (unsigned i = 0; i < tabCount; i++) {
Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.selectJoin(sqlptr = sql, cnt);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
SQLSMALLINT colCount = -1;
SQLSMALLINT colExp = cnt * tab.m_colCount;
test.run(HStmt(hStmt), SQLNumResultCols(hStmt, &colCount));
test.chk(HStmt(hStmt), colCount == colExp, "got %d != %d", (int)colCount, (int)colExp);
test.timerCnt(1);
}
}
freeAll(test, hEnv, hDbc, hStmt);
}
// catalog functions
static void
testCatalog(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
odbc_typeinfo: {
long type[] = {
SQL_CHAR, SQL_VARCHAR, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT, SQL_REAL, SQL_DOUBLE
};
unsigned rows[] = {
1, 1, 2, 2, 2, 1, 1 // 2 for signed and unsigned
};
for (unsigned i = 0; i < arraySize(type); i++) {
test.run(HStmt(hStmt), SQLGetTypeInfo(hStmt, type[i]));
long dataType = 0;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 2, SQL_C_SLONG, &dataType, 0, 0));
unsigned k = 0;
while (1) {
if (k == rows[i])
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (k == rows[i])
break;
test.chk(HStmt(hStmt), dataType == type[i], "got %ld != %ld", dataType, type[i]);
test.timerCnt(1);
k++;
}
#ifndef iODBC
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
#else
freeStmt(test, hDbc, hStmt);
allocStmt(test, hDbc, hStmt);
#endif
}
if (opt.m_v >= 2)
ndbout << "found " << (UintPtr)arraySize(type) << " data types" << endl;
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_UNBIND));
}
odbc_tables: {
unsigned found[tabCount];
for (unsigned i = 0; i < tabCount; i++)
found[i] = 0;
test.run(HStmt(hStmt), SQLTables(hStmt, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0));
char tableName[200] = "";
char tableType[200] = "";
test.run(HStmt(hStmt), SQLBindCol(hStmt, 3, SQL_C_CHAR, tableName, sizeof(tableName), 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 4, SQL_C_CHAR, tableType, sizeof(tableType), 0));
unsigned cnt = 0;
while (1) {
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (test.m_ret == SQL_NO_DATA)
break;
test.timerCnt(1);
cnt++;
if (! blankeq(tableType, "TABLE"))
continue;
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
if (! blankeq(tab.m_name, tableName))
continue;
test.chk(HStmt(hStmt), found[i] == 0, "duplicate table %s", tab.m_name);
found[i]++;
}
}
#ifndef iODBC
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
#else
freeStmt(test, hDbc, hStmt);
allocStmt(test, hDbc, hStmt);
#endif
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
test.chk(HStmt(hStmt), found[i] == 1, "table %s not found", tab.m_name);
}
if (opt.m_v >= 2)
ndbout << "found " << cnt << " tables" << endl;
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_UNBIND));
}
odbc_columns: {
unsigned found[tabCount][maxColCount];
for (unsigned i = 0; i < tabCount; i++) {
for (unsigned j = 0; j < maxColCount; j++)
found[i][j] = 0;
}
test.run(HStmt(hStmt), SQLColumns(hStmt, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0));
char tableName[200] = "";
char columnName[200] = "";
long dataType = 0;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 3, SQL_C_CHAR, tableName, sizeof(tableName), 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 4, SQL_C_CHAR, columnName, sizeof(columnName), 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 5, SQL_C_SLONG, &dataType, 0, 0));
unsigned cnt = 0;
while (1) {
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (test.m_ret == SQL_NO_DATA)
break;
test.timerCnt(1);
cnt++;
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
if (! blankeq(tab.m_name, tableName))
continue;
bool columnFound = false;
for (unsigned j = 0; j < tab.m_colCount; j++) {
const Col& col = tab.m_colList[j];
if (! blankeq(col.m_name, columnName))
continue;
test.chk(HStmt(hStmt), found[i][j] == 0, "duplicate column %s.%s", tableName, columnName);
found[i][j]++;
columnFound = true;
}
test.chk(HStmt(hStmt), columnFound, "unknown column %s.%s", tableName, columnName);
}
}
#ifndef iODBC
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
#else
freeStmt(test, hDbc, hStmt);
allocStmt(test, hDbc, hStmt);
#endif
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
for (unsigned j = 0; j < tab.m_colCount; j++) {
const Col& col = tab.m_colList[j];
test.chk(HStmt(hStmt), found[i][j] == 1, "column %s.%s not found", tab.m_name, col.m_name);
}
}
if (opt.m_v >= 2)
ndbout << "found " << cnt << " columns" << endl;
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_UNBIND));
}
odbc_primarykeys: {
// table patterns are no allowed
for (unsigned i = 0; i < tabCount; i++) {
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
char tmp[200]; // p.i.t.a
strcpy(tmp, tab.m_name);
for (char* a = tmp; *a != 0; a++) {
if ('a' <= *a && *a <= 'z')
*a -= 'a' - 'A';
}
test.run(HStmt(hStmt), SQLPrimaryKeys(hStmt, (SQLCHAR*)0, 0, (SQLCHAR*)0, 0, (SQLCHAR*)tmp, SQL_NTS));
char tableName[200] = "";
char columnName[200] = "";
long keySeq = -1;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 3, SQL_C_CHAR, tableName, sizeof(tableName), 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 4, SQL_C_CHAR, columnName, sizeof(columnName), 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 5, SQL_C_SLONG, &keySeq, 0, 0));
unsigned cnt = 0;
while (1) {
if (cnt == tab.m_pkCount)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (test.m_ret == SQL_NO_DATA)
break;
test.chk(HStmt(hStmt), keySeq == 1 + cnt, "got %ld != %u", keySeq, 1 + cnt);
const Col& col = tab.m_colList[tab.m_pkIndex[keySeq - 1]];
test.chk(HStmt(hStmt), blankeq(columnName, col.m_name), "got %s != %s", columnName, col.m_name);
test.timerCnt(1);
cnt++;
}
#ifndef iODBC
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
#else
freeStmt(test, hDbc, hStmt);
allocStmt(test, hDbc, hStmt);
#endif
}
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_UNBIND));
}
freeAll(test, hEnv, hDbc, hStmt);
}
// insert
static void
testInsert(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// prepare
tab.insertAll(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
SQLSMALLINT parCount = -1;
test.run(HStmt(hStmt), SQLNumParams(hStmt, &parCount));
test.chk(HStmt(hStmt), parCount == tab.m_colCount, "got %d != %d", (int)parCount, (int)tab.m_colCount);
// bind parameters
Row row(tab);
for (unsigned j = 0; j < tab.m_colCount; j++) {
Fld& fld = row.m_fldList[j];
const Col& col = fld.m_col;
// every other at-exec
SQLPOINTER caddr;
SQLINTEGER* ind;
if (opt.m_noputd || j % 2 == 0) {
caddr = fld.caddr();
ind = fld.ind();
} else {
caddr = (SQLPOINTER)j;
ind = fld.need();
}
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, caddr, col.csize(), ind));
}
// bind columns (none)
SQLSMALLINT colCount = -1;
test.run(HStmt(hStmt), SQLNumResultCols(hStmt, &colCount));
test.chk(HStmt(hStmt), colCount == 0, "got %d != 0", (int)colCount);
// execute
for (unsigned k = 0; k < opt.m_scale; k++) {
if (k % 5 == 0) {
// rebind
unsigned j = 0;
Fld& fld = row.m_fldList[j];
const Col& col = fld.m_col;
// every other at-exec
SQLPOINTER caddr;
SQLINTEGER* ind;
if (opt.m_noputd || j % 2 == 0) {
caddr = fld.caddr();
ind = fld.ind();
} else {
caddr = (SQLPOINTER)j;
ind = fld.need();
}
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, caddr, col.csize(), ind));
}
row.calcPk(test, k);
row.calcNk(test);
unsigned needData = opt.m_noputd ? 0 : tab.m_colCount / 2;
if (needData)
test.exp(SQL_NEED_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_INSERT, "got %d != %d", test.m_functionCode, SQL_DIAG_INSERT);
if (needData) {
while (1) {
SQLPOINTER jPtr = (SQLPOINTER)999;
if (needData)
test.exp(SQL_NEED_DATA, 0, 0, true);
// completes SQLExecute on success
test.run(HStmt(hStmt), SQLParamData(hStmt, &jPtr));
if (! needData)
break;
unsigned j = (unsigned)jPtr;
test.chk(HStmt(hStmt), j < tab.m_colCount && j % 2 != 0, "got %u 0x%x", j, j);
Fld& fld = row.m_fldList[j];
const Col& col = fld.m_col;
SQLSMALLINT ctype = col.ctype();
if (k % 2 == 0 || ctype != Col::CChar)
test.run(HStmt(hStmt), SQLPutData(hStmt, fld.caddr(), *fld.ind()));
else {
// put in pieces
unsigned size = col.csize() - 1; // omit null terminator
char* caddr = (char*)(fld.caddr());
unsigned off = 0;
while (off < size) {
unsigned m = size / 7; // bytes to put
if (m == 0)
m = 1;
if (m > size - off)
m = size - off;
bool putNull = (*fld.ind() == SQL_NULL_DATA);
// no null terminator
SQLINTEGER len = putNull ? SQL_NULL_DATA : (int)m;
test.run(HStmt(hStmt), SQLPutData(hStmt, caddr + off, len));
if (putNull)
break;
off += m;
}
}
needData--;
}
}
chkRowCount(test, hStmt, 1);
chkTuplesFetched(test, hStmt, 0);
}
test.timerCnt(opt.m_scale);
if (opt.m_v >= 3)
ndbout << "inserted " << opt.m_scale << " into " << tab.m_name << endl;
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
// count
static void
testCount(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
long count = -1;
selectCount(test, hStmt, tab, &count);
test.chk(HStmt(hStmt), count == opt.m_scale * opt.m_threads, "got %ld != %u", count, opt.m_scale * opt.m_threads);
test.timerCnt(count);
if (opt.m_v >= 3)
ndbout << "counted " << (int)count << " rows in " << tab.m_name << endl;
}
// scan all at same time
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.selectAll(sqlptr = sql);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
unsigned k = 0;
while (1) {
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
if (k == opt.m_scale * opt.m_threads)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (k != opt.m_scale * opt.m_threads) {
chkTuplesFetched(test, hStmt, k + 1);
test.timerCnt(1);
} else {
chkTuplesFetched(test, hStmt, k);
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLMoreResults(hStmt));
}
}
if (k == opt.m_scale * opt.m_threads)
break;
k++;
}
if (opt.m_v >= 3)
ndbout << "scanned " << opt.m_scale << " rows from each table" << endl;
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
// update
static void
testUpdatePk(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// prepare
tab.updatePk(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
// bind parameters
Row row(tab);
SQLSMALLINT parCount = -1;
test.run(HStmt(hStmt), SQLNumParams(hStmt, &parCount));
test.chk(HStmt(hStmt), parCount == tab.m_colCount, "got %d != %d", (int)parCount, (int)tab.m_colCount);
for (unsigned j = 0; j < tab.m_nkCount; j++) {
Fld& fld = row.m_fldList[tab.m_nkIndex[j]];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
for (unsigned j = 0; j < tab.m_pkCount; j++) {
Fld& fld = row.m_fldList[tab.m_pkIndex[j]];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + tab.m_nkCount + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
// bind columns (none)
SQLSMALLINT colCount = -1;
test.run(HStmt(hStmt), SQLNumResultCols(hStmt, &colCount));
test.chk(HStmt(hStmt), colCount == 0, "got %d != 0", (int)colCount);
// execute
for (unsigned k = 0; k < opt.m_scale; k++) {
if (k % 5 == 0) {
unsigned j = 0;
Fld& fld = row.m_fldList[tab.m_nkIndex[j]];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
row.calcPk(test, k);
row.calcNk(test);
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_UPDATE_WHERE, "got %d != %d", test.m_functionCode, SQL_DIAG_UPDATE_WHERE);
chkRowCount(test, hStmt, 1);
// direct update, no read has been necessary
chkTuplesFetched(test, hStmt, 0);
}
test.timerCnt(opt.m_scale);
if (opt.m_v >= 3)
ndbout << "updated " << opt.m_scale << " in " << tab.m_name << endl;
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
static void
testUpdateScan(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// prepare
tab.updateRange(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
// bind parameters
Row row(tab); // for set clause
Row rowlo(tab); // for pk ranges
Row rowhi(tab);
SQLSMALLINT parCount = -1;
test.run(HStmt(hStmt), SQLNumParams(hStmt, &parCount));
test.chk(HStmt(hStmt), parCount == tab.m_nkCount + 2 * tab.m_pkCount, "got %d != %d", (int)parCount, (int)tab.m_nkCount + 2 * (int)tab.m_pkCount);
for (unsigned j = 0; j < tab.m_nkCount; j++) {
const Col& col = tab.m_colList[tab.m_nkIndex[j]];
Fld& fld = row.m_fldList[tab.m_nkIndex[j]];
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
bool canInterp = true;
for (unsigned j = 0; j < tab.m_pkCount; j++) {
const Col& col = tab.m_colList[tab.m_pkIndex[j]];
Fld& fldlo = rowlo.m_fldList[tab.m_pkIndex[j]];
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + tab.m_nkCount + 2 * j + 0, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fldlo.caddr(), col.csize(), fldlo.ind()));
Fld& fldhi = rowhi.m_fldList[tab.m_pkIndex[j]];
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + tab.m_nkCount + 2 * j + 1, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fldhi.caddr(), col.csize(), fldhi.ind()));
if (col.m_type != Col::Char)
canInterp = false; // XXX no unsigned yet
}
// execute
row.calcPk(test, 0);
row.calcNk(test);
rowlo.calcPk(test, 0);
rowhi.calcPk(test, test.m_mul); // sucks
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_UPDATE_WHERE, "got %d != %d", test.m_functionCode, SQL_DIAG_UPDATE_WHERE);
chkRowCount(test, hStmt, opt.m_scale);
chkTuplesFetched(test, hStmt, canInterp ? opt.m_scale : opt.m_scale * opt.m_threads);
test.timerCnt(opt.m_scale);
if (opt.m_v >= 3)
ndbout << "updated " << opt.m_scale << " in " << tab.m_name << endl;
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
// verify
static void
testVerifyPk(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// prepare
tab.selectPk(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
// use same row for input and output
Row row(tab);
// bind parameters
SQLSMALLINT parCount = -1;
test.run(HStmt(hStmt), SQLNumParams(hStmt, &parCount));
test.chk(HStmt(hStmt), parCount == tab.m_pkCount, "got %d != %d", (int)parCount, (int)tab.m_pkCount);
for (unsigned j = 0; j < tab.m_pkCount; j++) {
Fld& fld = row.m_fldList[tab.m_pkIndex[j]];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
// bind columns
SQLSMALLINT colCount = -1;
test.run(HStmt(hStmt), SQLNumResultCols(hStmt, &colCount));
test.chk(HStmt(hStmt), colCount == tab.m_colCount, "got %d != %d", (int)colCount, (int)tab.m_colCount);
for (unsigned j = 0; j < tab.m_colCount; j++) {
Fld& fld = row.m_fldList[j];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1 + j, col.ctype(), fld.caddr(), col.csize(), fld.ind()));
}
// row for SQLGetData
Row rowGet(tab);
// reference row
Row rowRef(tab);
// execute
for (unsigned k = 0; k < opt.m_scale; k++) {
if (k % 5 == 0) {
// rebind
unsigned j = 0;
Fld& fld = row.m_fldList[tab.m_pkIndex[j]];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
row.calcPk(test, k);
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_SELECT_CURSOR, "got %d != %d", test.m_functionCode, SQL_DIAG_SELECT_CURSOR);
// fetch
for (unsigned k2 = 0; ; k2++) {
if (k2 == 1)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
chkTuplesFetched(test, hStmt, 1);
if (k2 == 1)
break;
rowRef.calcPk(test, k);
test.chk(HStmt(hStmt), row.verifyPk(test, rowRef), "verify row=%d", k);
if (test.m_const)
rowRef.calcPk(test, 0);
rowRef.calcNk(test);
test.chk(HStmt(hStmt), row.verifyNk(test, rowRef), "verify row=%d", k);
// SQLGetData is supported independent of SQLBindCol
if (opt.m_nogetd)
continue;
for (unsigned j = 0; j < tab.m_colCount; j++) {
Fld& fld = rowGet.m_fldList[j];
fld.zero();
const Col& col = fld.m_col;
// test both variants
SQLSMALLINT ctype = k % 2 == 0 ? col.ctype() : SQL_ARD_TYPE;
if (ctype != Col::CChar)
test.run(HStmt(hStmt), SQLGetData(hStmt, 1 + j, ctype, fld.caddr(), col.csize(), fld.ind()));
else {
// get in pieces
unsigned size = col.csize() - 1; // omit null terminator
char* caddr = (char*)(fld.caddr());
unsigned off = 0;
while (off < size) {
unsigned m = size / 3; // bytes to get
if (m == 0)
m = 1;
if (m > size - off)
m = size - off;
bool getNull = (rowRef.m_fldList[j].m_ind == SQL_NULL_DATA);
if (off + m < size && ! getNull)
test.exp(SQL_SUCCESS_WITH_INFO, "01004", -1, true);
// include null terminator in buffer size
test.run(HStmt(hStmt), SQLGetData(hStmt, 1 + j, ctype, caddr + off, m + 1, fld.ind()));
int ind = *fld.ind();
if (getNull) {
test.chk(HStmt(hStmt), ind == SQL_NULL_DATA, "got %d", ind);
break;
}
test.chk(HStmt(hStmt), ind == size - off, "got %d != %u", ind, size - off);
off += m;
}
}
}
rowRef.calcPk(test, k);
test.chk(HStmt(hStmt), rowGet.verifyPk(test, rowRef), "verify row=%d", k);
if (test.m_const)
rowRef.calcPk(test, 0);
rowRef.calcNk(test);
test.chk(HStmt(hStmt), rowGet.verifyNk(test, rowRef), "verify row=%d", k);
// SQLGetData again
for (unsigned j = 0; j < tab.m_colCount; j++) {
Fld& fld = rowGet.m_fldList[j];
const Col& col = fld.m_col;
// test both variants
SQLSMALLINT ctype = k % 2 == 0 ? col.ctype() : SQL_ARD_TYPE;
// expect no more data
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLGetData(hStmt, 1 + j, ctype, fld.caddr(), col.csize(), fld.ind()));
}
}
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
}
test.timerCnt(opt.m_scale);
if (opt.m_v >= 3)
ndbout << "verified " << opt.m_scale << " from " << tab.m_name << endl;
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
static void
testVerifyScan(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// prepare
tab.selectRange(sqlptr = sql, ! opt.m_nosort);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
// bind parameters
Row rowlo(tab); // use available PK fields..
Row rowhi(tab); // since we have no other way for now
SQLSMALLINT parCount = -1;
test.run(HStmt(hStmt), SQLNumParams(hStmt, &parCount));
test.chk(HStmt(hStmt), parCount == 2 * tab.m_pkCount, "got %d != %d", (int)parCount, 2 * (int)tab.m_pkCount);
for (unsigned j = 0; j < tab.m_pkCount; j++) {
const Col& col = tab.m_colList[tab.m_pkIndex[j]];
Fld& fldlo = rowlo.m_fldList[tab.m_pkIndex[j]];
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + 2 * j + 0, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fldlo.caddr(), col.csize(), fldlo.ind()));
Fld& fldhi = rowhi.m_fldList[tab.m_pkIndex[j]];
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + 2 * j + 1, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fldhi.caddr(), col.csize(), fldhi.ind()));
}
// bind columns
Row row(tab);
SQLSMALLINT colCount = -1;
test.run(HStmt(hStmt), SQLNumResultCols(hStmt, &colCount));
test.chk(HStmt(hStmt), colCount == tab.m_colCount, "got %d != %d", (int)colCount, (int)tab.m_colCount);
for (unsigned j = 0; j < tab.m_colCount; j++) {
Fld& fld = row.m_fldList[j];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1 + j, col.ctype(), fld.caddr(), col.csize(), fld.ind()));
}
// execute
rowlo.calcPk(test, 0);
rowhi.calcPk(test, test.m_mul); // sucks
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_SELECT_CURSOR, "got %d != %d", test.m_functionCode, SQL_DIAG_SELECT_CURSOR);
// reference row
Row rowRef(tab);
// fetch
unsigned k = 0;
SQLUINTEGER rowCount1 = (SQLUINTEGER)-1;
test.run(HStmt(hStmt), SQLSetStmtAttr(hStmt, SQL_ATTR_ROWS_FETCHED_PTR, &rowCount1, SQL_IS_POINTER));
while (1) {
unsigned countExp;
if (k == opt.m_scale) {
countExp = k;
test.exp(SQL_NO_DATA, 0, 0, true);
} else {
countExp = k + 1;
}
test.run(HStmt(hStmt), SQLFetch(hStmt));
// let me count the ways..
chkRowCount(test, hStmt, countExp);
test.chk(HStmt(hStmt), rowCount1 == countExp, "got %lu != %u", rowCount1, countExp);
SQLUINTEGER rowCount2 = (SQLUINTEGER)-1;
test.run(HStmt(hStmt), SQLGetStmtAttr(hStmt, SQL_ATTR_ROW_NUMBER, &rowCount2, SQL_IS_POINTER, 0));
test.chk(HStmt(hStmt), rowCount2 == countExp, "got %lu != %u", rowCount2, countExp);
if (k == opt.m_scale)
break;
if (! opt.m_nosort) {
// expecting k-th row
rowRef.calcPk(test, k);
test.chk(HStmt(hStmt), row.verifyPk(test, rowRef), "verify row=%d", k);
if (test.m_const)
rowRef.calcPk(test, 0);
rowRef.calcNk(test);
test.chk(HStmt(hStmt), row.verifyNk(test, rowRef), "verify row=%d", k);
} else {
// expecting random row
rowRef.copy(row);
test.chk(HStmt(hStmt), row.verifyNk(test, rowRef), "verify row=%d", k);
}
k++;
}
test.timerCnt(opt.m_scale);
if (opt.m_v >= 3)
ndbout << "verified " << opt.m_scale << " from " << tab.m_name << endl;
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
// self-join (scan followed by pk lookups)
static void
testJoin(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned cnt = opt.m_depth; cnt <= opt.m_depth; cnt++) {
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.selectJoin(sqlptr = sql, cnt);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
unsigned k = 0;
while (1) {
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
if (k == opt.m_scale * opt.m_threads)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (k == opt.m_scale * opt.m_threads) {
chkTuplesFetched(test, hStmt, k * opt.m_depth);
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
} else {
chkTuplesFetched(test, hStmt, (k + 1) * opt.m_depth);
test.timerCnt(1);
}
}
if (k == opt.m_scale * opt.m_threads)
break;
k++;
}
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
// cartesian join (multiple nested scans)
static void
testCart(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned cnt = 2; cnt <= 2; cnt++) {
unsigned rows = 1;
//for (unsigned k = 0; k < opt.m_depth; k++) {
//rows *= opt.m_scale * opt.m_threads;
//}
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.selectCart(sqlptr = sql, cnt);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
unsigned k = 0;
while (1) {
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
if (k == rows)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (k == rows) {
//chkTuplesFetched(test, hStmt, k);
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
} else {
//chkTuplesFetched(test, hStmt, k + 1);
test.timerCnt(1);
}
}
if (k == rows)
break;
k++;
}
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
// delete
static void
testDeleteAll(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
Tab& tab = tabList[i];
if (! tab.optok())
continue;
long count0 = -1;
selectCount(test, hStmt, tab, &count0);
tab.deleteAll(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
if (count0 == 0)
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLExecute(hStmt));
#ifndef iODBC
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_DELETE_WHERE, "got %d != %d", test.m_functionCode, SQL_DIAG_DELETE_WHERE);
#endif
SQLINTEGER rowCount = -1;
getRowCount(test, hStmt, &rowCount);
test.timerCnt(rowCount);
test.chk(HStmt(hStmt), rowCount == count0, "got %d != %ld", (int)rowCount, count0);
chkTuplesFetched(test, hStmt, rowCount);
if (opt.m_v >= 3)
ndbout << "deleted " << (int)rowCount << " from " << tab.m_name << endl;
long count = -1;
selectCount(test, hStmt, tab, &count);
test.chk(HStmt(hStmt), count == 0, "got %ld != 0", count);
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
static void
testDeletePk(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// prepare
tab.deletePk(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
// bind parameters
Row row(tab);
SQLSMALLINT parCount = -1;
test.run(HStmt(hStmt), SQLNumParams(hStmt, &parCount));
test.chk(HStmt(hStmt), parCount == tab.m_pkCount, "got %d != %d", (int)parCount, (int)tab.m_colCount);
for (unsigned j = 0; j < tab.m_pkCount; j++) {
Fld& fld = row.m_fldList[tab.m_pkIndex[j]];
const Col& col = fld.m_col;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, col.ctype(), col.type(), col.size(), 0, fld.caddr(), col.csize(), fld.ind()));
}
// bind columns (none)
SQLSMALLINT colCount = -1;
test.run(HStmt(hStmt), SQLNumResultCols(hStmt, &colCount));
test.chk(HStmt(hStmt), colCount == 0, "got %d != 0", (int)colCount);
// execute
for (unsigned k = 0; k < opt.m_scale; k++) {
row.calcPk(test, k);
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == SQL_DIAG_DELETE_WHERE, "got %d != %d", test.m_functionCode, SQL_DIAG_DELETE_WHERE);
chkRowCount(test, hStmt, 1);
// direct delete, no fetch required
chkTuplesFetched(test, hStmt, 0);
}
test.timerCnt(opt.m_scale);
if (opt.m_v >= 3)
ndbout << "updated " << opt.m_scale << " in " << tab.m_name << endl;
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
static void
testTrans(Test& test)
{
#ifdef unixODBC
if (opt.m_v >= 1)
ndbout << "unixODBC does not support transactions - test skipped" << endl;
#else
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
// delete all
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.deleteAll(sqlptr = sql);
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
SQLINTEGER rowCount = -1;
getRowCount(test, hStmt, &rowCount);
if (opt.m_v >= 3)
ndbout << "deleted " << (int)rowCount << " from " << tab.m_name << endl;
}
setAutocommit(test, hDbc, false);
if (opt.m_v >= 2)
ndbout << "set autocommit OFF" << endl;
for (int commit = 0; commit < opt.m_scale; commit += 1) {
bool rollback = (commit % 2 == 0);
// XXX delete with no data leaves trans in error state for 2nd table
if (commit > 0 && rollback) { // previous case was commit
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.deleteDirect(sqlptr = sql, 0);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
test.run(HDbc(hDbc), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT));
}
// insert
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.insertDirect(sqlptr = sql, 0);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
if (opt.m_v >= 2)
ndbout << tab.m_name << ": inserted 1 row" << endl;
}
// count them via pk
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.countDirect(sqlptr = sql, 0);
long count = -1;
long countExp = 1;
selectCount(test, hStmt, sql, &count);
test.chk(HStmt(hStmt), count == countExp, "got %ld != %ld", count, countExp);
}
// count them via scan
for (unsigned i = 0; i < tabCount; i++) {
// XXX hupp no work
break;
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
long count = -1;
long countExp = 1;
selectCount(test, hStmt, tab, &count);
test.chk(HStmt(hStmt), count == countExp, "got %ld != %ld", count, countExp);
}
// rollback or commit
if (rollback) {
if (opt.m_v >= 2)
ndbout << "end trans ROLLBACK" << endl;
test.run(HDbc(hDbc), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_ROLLBACK));
} else {
if (opt.m_v >= 2)
ndbout << "end trans COMMIT" << endl;
test.run(HDbc(hDbc), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT));
}
// count them via pk again
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
tab.countDirect(sqlptr = sql, 0);
long count = -1;
long countExp = rollback ? 0 : 1;
selectCount(test, hStmt, sql, &count);
test.chk(HStmt(hStmt), count == countExp, "got %ld != %ld", count, countExp);
}
// count them via scan again
for (unsigned i = 0; i < tabCount; i++) {
// XXX hupp no work
break;
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
long count = -1;
long countExp = rollback ? 0 : 1;
selectCount(test, hStmt, tab, &count);
test.chk(HStmt(hStmt), count == countExp, "got %ld != %ld", count, countExp);
}
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
#endif
}
static void
testConcur(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmtList[tabCount];
allocAll(test, hEnv, hDbc, hStmtList, tabCount);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
SQLHANDLE& hStmt = hStmtList[i];
const Tab& tab = tabList[i];
if (! tab.optok())
continue;
// delete all
tab.deleteAll(sqlptr = sql);
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// insert some
unsigned rowcount = 10;
for (unsigned n = 0; n < rowcount; n++) {
tab.insertDirect(sqlptr = sql, n);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
verifyCount(test, hStmt, tab, rowcount);
// start query scan followed by pk lookups
tab.selectJoin(sqlptr = sql, 2);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// start fetch
unsigned k = 0;
while (1) {
if (k > 0)
test.exp(SQL_ERROR, "24000", -1, true); // commit closed cursor
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (k > 0)
break;
// delete some random row
tab.deleteDirect(sqlptr = sql, k);
// try using same statement
test.exp(SQL_ERROR, "24000", -1, true); // cursor is open
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// try using different statement
SQLHANDLE hStmt2;
allocStmt(test, hDbc, hStmt2);
test.run(HStmt(hStmt2), SQLExecDirect(hStmt2, (SQLCHAR*)sql, SQL_NTS));
k++;
}
test.exp(SQL_ERROR, "24000", -1, true); // cursor is not open
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
test.timerCnt(rowcount);
}
freeAll(test, hEnv, hDbc, hStmtList, tabCount);
}
static void
testReadcom(Test& test)
{
testDeleteAll(test);
testInsert(test);
const unsigned nc = 3;
SQLHANDLE hEnv[nc], hDbc[nc], hStmt[nc];
char sql[MAX_SQL], *sqlptr;
for (unsigned j = 0; j < nc; j++)
allocAll(test, hEnv[j], hDbc[j], hStmt[j]);
for (unsigned i = 0; i < tabCount; i++) {
Tab& tab = tabList[i];
if (! tab.optok())
continue;
long count;
// check count
count = -1;
selectCount(test, hStmt[0], tab, &count);
test.chk(HStmt(hStmt[0]), count == opt.m_scale, "got %d != %d", (int)count, (int)opt.m_scale);
// scan delete uncommitted with handle 0
setAutocommit(test, hDbc[0], false);
tab.deleteAll(sqlptr = sql);
if (opt.m_scale == 0)
test.exp(SQL_NO_DATA, 0, 0, false);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt[0]), SQLExecDirect(hStmt[0], (SQLCHAR*)sql, SQL_NTS));
// scan via other tx should not hang and see all rows
for (unsigned j = 0; j < nc; j++) {
count = -1;
int want = j == 0 ? 0 : opt.m_scale;
selectCount(test, hStmt[j], tab, &count);
test.chk(HStmt(hStmt[j]), count == want, "tx %u: got %d != %d", j, (int)count, want);
if (opt.m_v >= 2)
ndbout << "tx " << j << " ok !" << endl;
}
// setting autocommit on commits the delete
setAutocommit(test, hDbc[0], true);
// check count
count = -1;
selectCount(test, hStmt[0], tab, &count);
test.chk(HStmt(hStmt[0]), count == 0, "got %d != 0", (int)count);
}
for (unsigned j = 0; j < nc; j++)
freeAll(test, hEnv[j], hDbc[j], hStmt[j]);
}
static void
testPerf(Test& test)
{
if (test.m_stuff == 0) {
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
char sql[MAX_SQL], *sqlptr;
for (unsigned i = 0; i < tabCount; i++) {
Tab& tab = tabList[i];
if (! tab.optok())
continue;
test.exp(SQL_NO_DATA, 0, 0, false);
tab.deleteAll(sqlptr = sql);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
long count0 = -1;
// XXX triggers SEGV somewhere
//selectCount(test, hStmt, tab, &count0);
//test.chk(HStmt(hStmt), count0 == 0, "got %d != 0", (int)count0);
}
freeAll(test, hEnv, hDbc, hStmt);
return;
}
assert(test.m_stuff == 1 || test.m_stuff == 2);
bool ndbapi = (test.m_stuff == 1);
tt01: {
const unsigned OFF = 1000000;
const unsigned N = 25;
Tab& tab = tabList[1];
if (! tab.optok())
goto out;
if (ndbapi) {
#ifndef ndbODBC
if (opt.m_v >= 1)
ndbout << "running via DM - test skipped" << endl;
#else
Ndb* ndb = new Ndb("TEST_DB");
ndb->init();
if (ndb->waitUntilReady() != 0) {
ndbout << ndb->getNdbError() << endl;
fatal("waitUntilReady");
}
Uint32 val[1+N];
// insert
for (unsigned k = 1; k <= opt.m_scale; k++) {
NdbConnection* con = ndb->startTransaction();
if (con == 0) {
ndbout << ndb->getNdbError() << endl;
fatal("startTransaction");
}
NdbOperation* op = con->getNdbOperation(tab.m_upperName);
if (op == 0) {
ndbout << con->getNdbError() << endl;
fatal("getNdbOperation");
}
if (op->insertTuple() == -1) {
ndbout << op->getNdbError() << endl;
fatal("insertTuple");
}
for (unsigned j = 0; j <= N; j++) {
val[j] = (j == 0 ? k + test.m_no * OFF : k * j);
if (j == 0) {
if (op->equal(j, val[j]) == -1) {
ndbout << op->getNdbError() << endl;
fatal("equal");
}
} else {
if (op->setValue(j, val[j]) == -1) {
ndbout << op->getNdbError() << endl;
fatal("setValue");
}
}
}
if (con->execute(Commit) == -1) {
ndbout << con->getNdbError() << endl;
fatal("execute");
}
ndb->closeTransaction(con);
}
test.timerCnt(opt.m_scale);
// select PK
for (unsigned k = 1; k <= opt.m_scale; k++) {
NdbConnection* con = ndb->startTransaction();
if (con == 0) {
ndbout << ndb->getNdbError() << endl;
fatal("startTransaction");
}
NdbOperation* op = con->getNdbOperation(tab.m_upperName);
if (op == 0) {
ndbout << con->getNdbError() << endl;
fatal("getNdbOperation");
}
if (op->readTuple() == -1) {
ndbout << op->getNdbError() << endl;
fatal("insertTuple");
}
for (unsigned j = 0; j <= N; j++) {
val[j] = (j == 0 ? k + test.m_no * OFF : 0);
if (j == 0) {
if (op->equal(j, val[j]) == -1) {
ndbout << op->getNdbError() << endl;
fatal("equal");
}
} else {
if (op->getValue(j, (char*)&val[j]) == 0) {
ndbout << op->getNdbError() << endl;
fatal("getValue");
}
}
}
if (con->execute(Commit) == -1) {
ndbout << con->getNdbError() << endl;
fatal("execute");
}
for (unsigned j = 1; j <= N; j++) {
assert(val[j] == k * j);
}
ndb->closeTransaction(con);
}
test.timerCnt(opt.m_scale);
// delete PK
for (unsigned k = 1; k <= opt.m_scale; k++) {
NdbConnection* con = ndb->startTransaction();
if (con == 0) {
ndbout << ndb->getNdbError() << endl;
fatal("startTransaction");
}
NdbOperation* op = con->getNdbOperation(tab.m_upperName);
if (op == 0) {
ndbout << con->getNdbError() << endl;
fatal("getNdbOperation");
}
if (op->deleteTuple() == -1) {
ndbout << op->getNdbError() << endl;
fatal("deleteTuple");
}
unsigned j = 0;
val[j] = k + test.m_no * OFF;
if (op->equal(j, val[j]) == -1) {
ndbout << op->getNdbError() << endl;
fatal("equal");
}
if (con->execute(Commit) == -1) {
ndbout << con->getNdbError() << endl;
fatal("execute");
}
ndb->closeTransaction(con);
}
test.timerCnt(opt.m_scale);
delete ndb;
#endif
} else {
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
long val[1+N];
char sql[MAX_SQL], *sqlptr;
// insert
tab.insertAll(sqlptr = sql);
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
for (unsigned j = 0; j <= N; j++) {
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &val[j], 0, 0));
}
test.m_perf = true;
for (unsigned k = 1; k <= opt.m_scale; k++) {
for (unsigned j = 0; j <= N; j++) {
val[j] = (j == 0 ? k + test.m_no * OFF : k * j);
}
test.run(HStmt(hStmt), SQLExecute(hStmt));
}
test.m_perf = false;
test.timerCnt(opt.m_scale);
// select PK
tab.selectPk(sqlptr = sql);
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
for (unsigned j = 0; j <= N; j++) {
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1 + j, SQL_C_SLONG, &val[j], 0, 0));
}
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + N + 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &val[0], 0, 0));
test.m_perf = true;
for (unsigned k = 1; k <= opt.m_scale; k++) {
val[0] = k + test.m_no * OFF;
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.run(HStmt(hStmt), SQLFetch(hStmt));
for (unsigned j = 1; j <= N; j++) {
assert(val[j] == k * j);
}
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
}
test.m_perf = false;
test.timerCnt(opt.m_scale);
// delete PK
tab.deletePk(sqlptr = sql);
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
unsigned j = 0;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1 + j, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &val[j], 0, 0));
test.m_perf = true;
for (unsigned k = 1; k <= opt.m_scale; k++) {
val[j] = k + test.m_no * OFF;
test.run(HStmt(hStmt), SQLExecute(hStmt));
}
test.m_perf = false;
test.timerCnt(opt.m_scale);
freeAll(test, hEnv, hDbc, hStmt);
}
out:
;
}
}
struct Sql {
const char* m_sql;
int m_functionCode;
int m_rowCount;
int m_tuplesFetched;
long m_lastValue;
unsigned long m_bindValue;
int m_ret;
const char* m_state;
SQLINTEGER m_native;
bool m_reset;
// run this function instead
typedef void (*TestFunc)(Test& test);
TestFunc m_testFunc;
Sql() :
m_sql(0) {
}
Sql(const char* do_cmd) :
m_sql(do_cmd) {
}
Sql(const char* sql, int functionCode, int rowCount, int tuplesFetched, long lastValue, long bindValue) :
m_sql(sql),
m_functionCode(functionCode),
m_rowCount(rowCount),
m_tuplesFetched(tuplesFetched),
m_lastValue(lastValue),
m_bindValue(bindValue),
m_ret(SQL_SUCCESS),
m_state(0),
m_native(0),
m_reset(true),
m_testFunc(0) {
}
// the 4 numbers after SQL_DIAG... rowCount tuplesFetched lastValue bindValue
Sql(const char* sql, int functionCode, int rowCount, int tuplesFetched, long lastValue, long bindValue, int ret, const char* state, SQLINTEGER native, bool reset) :
m_sql(sql),
m_functionCode(functionCode),
m_rowCount(rowCount),
m_tuplesFetched(tuplesFetched),
m_lastValue(lastValue),
m_bindValue(bindValue),
m_ret(ret),
m_state(state),
m_native(native),
m_reset(reset),
m_testFunc(0) {
}
Sql(const char* text, TestFunc testFunc) :
m_sql(text),
m_testFunc(testFunc) {
}
static const char* set_autocommit_on() {
return "set autocommit on";
}
static const char* set_autocommit_off() {
return "set autocommit off";
}
static const char* do_commit() {
return "commit";
}
static const char* do_rollback() {
return "rollback";
}
};
// 90
static const Sql
miscSql90[] = {
Sql("select * from dual",
SQL_DIAG_SELECT_CURSOR, 1, 0, -1, -1),
Sql("drop table tt90a",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt90a (a int, b int, c int, primary key(b, c)) storage(large) logging",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql()
};
// 91
static const Sql
miscSql91[] = {
Sql("drop table tt91a",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt91a (a bigint unsigned primary key, b bigint unsigned not null, c varchar(10))",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("insert into tt91a values (1, 111, 'aaa')",
SQL_DIAG_INSERT, 1, 0, -1, -1),
// fails
Sql("insert into tt91a values (2, null, 'ccc')",
SQL_DIAG_INSERT, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2014203, true),
Sql("update tt91a set b = 222 where a = 2",
SQL_DIAG_UPDATE_WHERE, 0, 0, -1, -1,
SQL_NO_DATA, 0, 0, true),
// two more
Sql("insert into tt91a values (2, 222, 'ccc')",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("insert into tt91a values (3, 333, 'bbb')",
SQL_DIAG_INSERT, 1, 0, -1, -1),
// direct update
Sql("update tt91a set b = 112 where a = 1",
SQL_DIAG_UPDATE_WHERE, 1, 0, -1, -1),
Sql("update tt91a set b = 113 where a = 1 and b > 111",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
// update and delete with interpreted scan
Sql("update tt91a set b = 114 where b < 114",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("delete from tt91a where b < 115",
SQL_DIAG_DELETE_WHERE, 1, 1, -1, -1),
Sql("insert into tt91a values (1, 111, 'aaa')",
SQL_DIAG_INSERT, 1, 0, -1, -1),
// check rows: 1,111,aaa + 2,222,ccc + 3,333,bbb
Sql("select * from tt91a order by c",
SQL_DIAG_SELECT_CURSOR, 3, 3, 2, -1),
Sql("select * from tt91a order by c desc",
SQL_DIAG_SELECT_CURSOR, 3, 3, 1, -1),
Sql("select * from tt91a where a = 2",
SQL_DIAG_SELECT_CURSOR, 1, 1, -1, -1),
Sql("select * from tt91a where a + b = 224",
SQL_DIAG_SELECT_CURSOR, 1, 3, -1, -1),
Sql("select * from tt91a where a = 4",
SQL_DIAG_SELECT_CURSOR, 0, 0, -1, -1),
Sql("select b-a from tt91a order by a-b",
SQL_DIAG_SELECT_CURSOR, 3, 3, 110, -1),
Sql("select sum(a+b) from tt91a",
SQL_DIAG_SELECT_CURSOR, 1, 3, 672, -1),
Sql("select x.b, y.b, z.b from tt91a x, tt91a y, tt91a z where x.b <= y.b and y.b < z.b order by x.b",
SQL_DIAG_SELECT_CURSOR, 4, 13, 222, -1),
Sql("select x.b, y.b, z.b from tt91a x, tt91a y, tt91a z where x.b + y.b = z.b order by x.b",
SQL_DIAG_SELECT_CURSOR, 3, 15, 222, -1),
// tmp index
Sql("create unique hash index xx91a on tt91a(b)",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
Sql("select x.b, y.b, z.b from tt91a x, tt91a y, tt91a z where x.b + y.b = z.b order by x.b",
SQL_DIAG_SELECT_CURSOR, 3, 15, 222, -1),
Sql("drop index xx91a on tt91a",
SQL_DIAG_DROP_INDEX, -1, -1, -1, -1),
// add some duplicates
Sql("insert into tt91a values (4, 222, 'ccc')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("insert into tt91a values (5, 333, 'bbb')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("insert into tt91a values (6, 333, 'bbb')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
// check rows: 1,111,aaa + 2 * 2,222,ccc + 3 * 3,333,bbb
Sql("select count(*) from tt91a",
SQL_DIAG_SELECT_CURSOR, 1, -1, 6, -1),
Sql("select a+b from tt91a where (b = 111 or b = 222 ) and (b = 222 or b = 333) and a > 1 and a < 3",
SQL_DIAG_SELECT_CURSOR, 1, -1, 224, -1),
Sql("select sum(a) from tt91a having min(a) = 1 and max(a) = 6",
SQL_DIAG_SELECT_CURSOR, 1, -1, 21, -1),
Sql("select sum(a) from tt91a where a = 2 or a = 4 having min(a) = 2 and max(a) = 4",
SQL_DIAG_SELECT_CURSOR, 1, -1, 6, -1),
Sql("select sum(a) from tt91a having min(a) = 1 and max(a) = 5",
SQL_DIAG_SELECT_CURSOR, 0, -1, -1, -1),
Sql("select sum(a), b from tt91a group by b order by b",
SQL_DIAG_SELECT_CURSOR, 3, -1, 14, -1),
Sql("select sum(a), b, c from tt91a group by b, c order by c",
SQL_DIAG_SELECT_CURSOR, 3, -1, 6, -1),
Sql("select b, sum(a) from tt91a group by b having b = 37 * sum(a)",
SQL_DIAG_SELECT_CURSOR, 1, -1, 222, -1),
// simple varchar vs interpreter test
Sql("select count(*) from tt91a where c = 'ccc'",
SQL_DIAG_SELECT_CURSOR, 1, 2, 2, -1),
Sql("select count(*) from tt91a where c like '%b%'",
SQL_DIAG_SELECT_CURSOR, 1, 3, 3, -1),
// interpreter limits (crashes in api on v211)
#if NDB_VERSION_MAJOR >= 3
Sql("select count(*) from tt91a where a in (99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2)",
SQL_DIAG_SELECT_CURSOR, 1, 5, 5, -1),
Sql("select count(*) from tt91a where c in ('xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','bbb','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy','zzzzz','xxxxx','yyyyy')",
SQL_DIAG_SELECT_CURSOR, 1, 3, 3, -1),
#endif
// distinct
Sql("select distinct b from tt91a order by b",
SQL_DIAG_SELECT_CURSOR, 3, -1, 333, -1),
// some illegal groupings
Sql("select a from tt91a group by b",
-1, -1, -1, -1, -1,
SQL_ERROR, "IM000", -1, -1),
Sql("select sum(a) from tt91a group by b having a = 2",
-1, -1, -1, -1, -1,
SQL_ERROR, "IM000", -1, -1),
Sql("select sum(a) from tt91a group by b order by a",
-1, -1, -1, -1, -1,
SQL_ERROR, "IM000", -1, -1),
// string functions
Sql("insert into tt91a (c, b, a) values ('abcdef', 999, 9)",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("select count(*) from tt91a where left(c, 2) = 'ab' and substr(c, 3, 2) = 'cd' and right(c, 2) = 'ef'",
SQL_DIAG_SELECT_CURSOR, 1, -1, 1, -1),
// nulls
Sql("update tt91a set c = null where a > 8",
SQL_DIAG_UPDATE_WHERE, 1, -1, -1, -1),
Sql("select a from tt91a where c is null and b is not null order by a",
SQL_DIAG_SELECT_CURSOR, 1, -1, 9, -1),
Sql("select a from tt91a where not (c is not null or b is null) order by a",
SQL_DIAG_SELECT_CURSOR, 1, -1, 9, -1),
// null value guard in interpreter
Sql("select count(*) from tt91a where c < 'x' or c > 'x' or c != 'x' or c = 'x'",
SQL_DIAG_SELECT_CURSOR, 1, 6, 6, -1),
Sql("delete from tt91a where c is null",
SQL_DIAG_DELETE_WHERE, 1, -1, -1, -1),
// indexes
Sql("update tt91a set b = a + 5",
SQL_DIAG_UPDATE_WHERE, 6, 6, -1, -1),
Sql("create unique hash index xx91a on tt91a(b)",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
// scan y primary key x
Sql("select x.b from tt91a x, tt91a y where x.a = y.b + 0",
SQL_DIAG_SELECT_CURSOR, 1, 7, 11, -1),
// scan x index y
Sql("select x.b from tt91a x, tt91a y where x.a + 0 = y.b",
SQL_DIAG_SELECT_CURSOR, 1, -1, 11, -1),
// scan x scan y
Sql("select x.b from tt91a x, tt91a y where x.a + 0 = y.b + 0",
SQL_DIAG_SELECT_CURSOR, 1, -1, 11, -1),
// dml ops
Sql("delete from tt91a where b = 11 and a > 999",
SQL_DIAG_DELETE_WHERE, 0, 1, -1, -1,
SQL_NO_DATA, 0, 0, true),
Sql("delete from tt91a where b = 11",
SQL_DIAG_DELETE_WHERE, 1, 0, -1, -1),
Sql("delete from tt91a where b = 11",
SQL_DIAG_DELETE_WHERE, 0, 0, -1, -1,
SQL_NO_DATA, 0, 0, true),
Sql("update tt91a set b = 10*10 where b = 10",
SQL_DIAG_UPDATE_WHERE, 1, 0, -1, -1),
Sql("update tt91a set b = 10 where b = 10*10",
SQL_DIAG_UPDATE_WHERE, 1, 0, -1, -1),
Sql("update tt91a set b = 10*10 where b = 10 and b >= 10",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("update tt91a set b = 10 where b = 10*10 and b >= 10*10",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
// char vs varchar
Sql("drop table tt91b",
SQL_DIAG_DROP_TABLE, -1, -1, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt91b (a int primary key, b char(5), c varchar(5))",
SQL_DIAG_CREATE_TABLE, -1, -1, -1, -1),
Sql("insert into tt91b values (1, 'abc', 'abc')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("insert into tt91b values (2, 'xyz', 'xyz')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("insert into tt91b values (3, 'xyz', 'xyz ')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
// char = char strips blanks
Sql("select count(*) from tt91b x where (x.b = 'abc') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 1, -1),
Sql("select count(*) from tt91b x where (x.b = 'abc')",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("select count(*) from tt91b x where (x.b = 'abc ') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 1, -1),
Sql("select count(*) from tt91b x where (x.b = 'abc ')",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
// varchar = char
Sql("select count(*) from tt91b x where (x.c = 'abc') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 1, -1),
Sql("select count(*) from tt91b x where (x.c = 'abc')",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("select count(*) from tt91b x where (x.c = 'abc ') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 0, -1),
Sql("select count(*) from tt91b x where (x.c = 'abc ')",
SQL_DIAG_SELECT_CURSOR, 1, 0, 0, -1),
// char = varchar
Sql("select count(*) from tt91b x, tt91b y where (x.b = y.c) or x.a = x.a+1 or y.a = y.a+1",
SQL_DIAG_SELECT_CURSOR, 1, -1, 2, -1),
Sql("select count(*) from tt91b x, tt91b y where (x.b = y.c)",
SQL_DIAG_SELECT_CURSOR, 1, -1, 2, -1),
// varchar = varchar
Sql("select count(*) from tt91b x, tt91b y where (x.c = y.c) or x.a = x.a+1 or y.a = y.a+1",
SQL_DIAG_SELECT_CURSOR, 1, -1, 3, -1),
Sql("select count(*) from tt91b x, tt91b y where (x.c = y.c)",
SQL_DIAG_SELECT_CURSOR, 1, -1, 3, -1),
// less
Sql("select 10 * x.a + y.a from tt91b x, tt91b y where (x.b < y.b) or x.a = x.a+1 or y.a = y.a+1 order by x.a, y.a",
SQL_DIAG_SELECT_CURSOR, 2, -1, 13, -1),
Sql("select 10 * x.a + y.a from tt91b x, tt91b y where (x.b < y.b) order by x.a, y.a",
SQL_DIAG_SELECT_CURSOR, 2, -1, 13, -1),
Sql("select 10 * x.a + y.a from tt91b x, tt91b y where (x.c < y.c) or x.a = x.a+1 or y.a = y.a+1 order by x.a, y.a",
SQL_DIAG_SELECT_CURSOR, 3, -1, 23, -1),
Sql("select 10 * x.a + y.a from tt91b x, tt91b y where (x.c < y.c) order by x.a, y.a",
SQL_DIAG_SELECT_CURSOR, 3, -1, 23, -1),
// like
Sql("select count(*) from tt91b x where (x.b like 'a%') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 1, -1),
Sql("select count(*) from tt91b x where (x.b like 'a%')",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("select count(*) from tt91b x where (x.b like 'x%z') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 0, -1),
Sql("select count(*) from tt91b x where (x.b like 'x%z')",
SQL_DIAG_SELECT_CURSOR, 1, 0, 0, -1),
Sql("select count(*) from tt91b x where (x.a+0 = 2 and x.c like 'x%z') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 1, -1),
Sql("select count(*) from tt91b x where (x.a+0 = 2 and x.c like 'x%z')",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("select count(*) from tt91b x where (x.a+0 = 3 and x.c like 'x%z ') or x.a = x.a+1",
SQL_DIAG_SELECT_CURSOR, 1, 3, 1, -1),
Sql("select count(*) from tt91b x where (x.a+0 = 3 and x.c like 'x%z ')",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql()
};
// 92
static void
testMisc92a(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
char sql[MAX_SQL];
char tname[20];
sprintf(tname, "tt92%c", 0140 + test.m_no);
if (test.m_loop == 1) {
lock_mutex();
sprintf(sql, "drop table %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.exp(SQL_ERROR, "IM000", 2040709, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
sprintf(sql, "create table %s (a int unsigned primary key, b int unsigned not null)", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
unlock_mutex();
} else {
sprintf(sql, "delete from %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
test.run(HStmt(hStmt), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT));
}
for (int on = true; on >= false; on--) {
if (opt.m_v >= 2)
ndbout << "set autocommit " << (on ? "ON" : "OFF") << endl;
setAutocommit(test, hDbc, on);
// insert rows
if (opt.m_v >= 2)
ndbout << "SQL: insert into " << tname << " ..." << opt.m_scale << endl;
for (unsigned k = 0; k < opt.m_scale; k++) {
sprintf(sql, "insert into %s values (%u, %u)", tname, k, 10 * k);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
// commit always
test.run(HStmt(hStmt), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT));
// scan delete
sprintf(sql, "delete from %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// rollback or commit
test.run(HStmt(hStmt), SQLEndTran(SQL_HANDLE_DBC, hDbc, on ? SQL_COMMIT : SQL_ROLLBACK));
// count
long count = -1;
sprintf(sql, "select count(*) from %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
selectCount(test, hStmt, sql, &count);
test.chk(HStmt(hStmt), count == on ? 0 : opt.m_scale, "%s: got %d != %d", tname, (int)count, (int)opt.m_scale);
}
freeAll(test, hEnv, hDbc, hStmt);
}
static const Sql
miscSql92[] = {
// create in C func
Sql("testMisc92a", testMisc92a),
Sql()
};
// 93
static void
testMisc93a(Test& test)
{
SQLHANDLE hEnv[2], hDbc[2], hStmt[2];
allocAll(test, hEnv[0], hDbc[0], hStmt[0]);
allocAll(test, hEnv[1], hDbc[1], hStmt[1]);
char sql[MAX_SQL];
// select via primary key
setAutocommit(test, hDbc[0], false);
sprintf(sql, "select c1 from tt93a where c0 = 1");
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt[0]), SQLExecDirect(hStmt[0], (SQLCHAR*)sql, SQL_NTS));
// update via another trans must time out
sprintf(sql, "update tt93a set c1 = 'b' where c0 = 1");
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt[1]), SQLExecDirect(hStmt[1], (SQLCHAR*)sql, SQL_NTS));
freeAll(test, hEnv[0], hDbc[0], hStmt[0]);
freeAll(test, hEnv[1], hDbc[1], hStmt[1]);
}
static const Sql
miscSql93[] = {
// create in C func
Sql("drop table tt93a",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt93a (c0 int primary key, c1 char(10))",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("insert into tt93a values(1, 'a')",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("testMisc93a", testMisc93a),
Sql()
};
// 95
static const Sql
miscSql95[] = {
Sql("drop table tt95a",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt95a (a int not null, b char(10) not null, c int not null, d char(10), primary key(a, b)) storage(small)",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
// ordered index create and drop
Sql("create index xx95a on tt95a (c, d) nologging",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
Sql("drop index xx95a on tt95a",
SQL_DIAG_DROP_INDEX, -1, -1, -1, -1),
Sql("create index xx95a on tt95a (c) nologging",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
Sql("insert into tt95a values(1, 'a', 10, 'b')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("insert into tt95a values(2, 'a', 20, 'b')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("insert into tt95a values(3, 'a', 30, 'b')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("select a from tt95a where c = 20",
SQL_DIAG_SELECT_CURSOR, 1, 1, 2, -1),
Sql("delete from tt95a where c = 10",
SQL_DIAG_DELETE_WHERE, 1, 1, -1, -1),
Sql("update tt95a set c = 300 where c = 30",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("delete from tt95a where c = 300",
SQL_DIAG_DELETE_WHERE, 1, 1, -1, -1),
Sql("delete from tt95a",
SQL_DIAG_DELETE_WHERE, 1, 1, -1, -1),
// simple insert and rollback
Sql("-- simple insert and rollback"),
Sql(Sql::set_autocommit_off()),
Sql("insert into tt95a values(1, 'a', 10, 'b')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("select count(*) from tt95a",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("select count(*) from tt95a where c = 10",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql(Sql::do_rollback()),
Sql(Sql::set_autocommit_on()),
Sql("select count(*) from tt95a",
SQL_DIAG_SELECT_CURSOR, 1, 0, 0, -1),
// simple update and rollback
Sql("-- simple update and rollback"),
Sql("insert into tt95a values(1, 'a', 10, 'b')",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql(Sql::set_autocommit_off()),
Sql("update tt95a set c = 20 where c = 10",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("select count(*) from tt95a",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("select count(*) from tt95a where c = 20",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql(Sql::do_rollback()),
Sql(Sql::set_autocommit_on()),
Sql("select count(*) from tt95a where c = 10",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
// simple delete and rollback
Sql("-- simple delete and rollback"),
Sql(Sql::set_autocommit_off()),
Sql("delete from tt95a where c = 10",
SQL_DIAG_DELETE_WHERE, 1, 1, -1, -1),
Sql("select count(*) from tt95a",
SQL_DIAG_SELECT_CURSOR, 0, 0, 0, -1),
Sql("select count(*) from tt95a where c = 10",
SQL_DIAG_SELECT_CURSOR, 0, 0, 0, -1),
Sql(Sql::do_rollback()),
Sql(Sql::set_autocommit_on()),
Sql("select count(*) from tt95a where c = 10",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
// multiple update
Sql("-- multiple update and rollback"),
Sql(Sql::set_autocommit_off()),
Sql("update tt95a set c = 20 where c = 10",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("select count(*) from tt95a where c = 20",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("update tt95a set c = 30 where c = 20",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("select count(*) from tt95a where c = 30",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("update tt95a set c = 40 where c = 30",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("select count(*) from tt95a where c = 40",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql("update tt95a set c = 50 where c = 40",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
Sql("select count(*) from tt95a where c = 50",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
Sql(Sql::do_rollback()),
Sql(Sql::set_autocommit_on()),
Sql("select count(*) from tt95a where c = 10",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1, -1),
// another variant which found no tuple via index (aligment issue)
Sql("drop table tt95b",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt95b (a int primary key, b char(10) not null, c int not null)",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("create index xx95b on tt95b (b, c) nologging",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
Sql("insert into tt95b values(0,'0123456789',1)",
SQL_DIAG_INSERT, 1, -1, -1, -1),
Sql("select a from tt95b where b='0123456789'",
SQL_DIAG_SELECT_CURSOR, 1, 1, 0, -1),
// update index key to different value
Sql("update tt95b set b = '9876543210' where b = '0123456789'",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
// same value goes nuts...
Sql("update tt95b set b = '9876543210'",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
#if 0
// ...if done via index key (variant of halloween problem)
Sql("update tt95b set b = '9876543210' where b = '9876543210'",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, -1),
#endif
Sql()
};
// 96
static void
testMisc96a(Test& test)
{
// single thread
if (test.m_no != 1)
return;
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
char sql[MAX_SQL], *sqlptr;
char tname[20];
strcpy(tname, "tt96a");
// drop table
scopy(sqlptr = sql, "drop table %s", tname);
test.exp(SQL_ERROR, "IM000", 2040709, false);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// create table with many attributes
unsigned attrs = 1 + opt.m_scale;
if (attrs > MAX_ATTRIBUTES_IN_TABLE)
attrs = MAX_ATTRIBUTES_IN_TABLE;
if (attrs > 64)
attrs = 64;
scopy(sqlptr = sql, "create table %s (c0 int primary key", tname);
for (unsigned j = 1; j < attrs; j++) {
if (j % 2 == 0)
scopy(sqlptr, ", c%d int unsigned not null", j);
else
scopy(sqlptr, ", c%d char(10) not null", j);
}
scopy(sqlptr, ")");
if (opt.m_fragtype != 0)
scopy(sqlptr, " storage(%s)", opt.m_fragtype);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// create or drop indexes
const unsigned seed = 1000037 * test.m_loop + 1000039 * opt.m_scale;
srandom(seed);
const unsigned imax = opt.m_scale < 20 ? opt.m_scale : 20;
AttributeMask* imasks = new AttributeMask[imax];
unsigned ccnt = 0;
unsigned dcnt = 0;
for (unsigned n = 0; n < imax; n++)
imasks[n].clear();
while (ccnt + dcnt < opt.m_scale) {
char iname[20];
unsigned n = urandom(imax);
sprintf(iname, "xx96a%02d", n);
AttributeMask& imask = imasks[n];
unsigned sel = urandom(10);
if (imask.isclear()) {
// create one
unsigned ncol = 0;
unsigned cols[MAX_ATTRIBUTES_IN_INDEX];
unsigned cnum = urandom(attrs);
cols[ncol++] = cnum;
while (ncol < MAX_ATTRIBUTES_IN_INDEX) {
unsigned sel2 = urandom(10);
if (sel2 < 2)
break;
unsigned cnum2 = urandom(attrs);
if (sel2 < 9 && cnum2 == 0)
continue;
unsigned j;
for (j = 0; j < ncol; j++) {
if (cols[j] == cnum2)
break;
}
if (j == ncol)
cols[ncol++] = cnum2;
}
if (sel < 3) {
scopy(sqlptr = sql, "create unique hash index %s on %s (", iname, tname);
for (unsigned j = 0; j < ncol; j++)
scopy(sqlptr, "%sc%d", j == 0 ? "" : ", ", cols[j]);
scopy(sqlptr, ")");
} else {
scopy(sqlptr = sql, "create index %s on %s (", iname, tname);
for (unsigned j = 0; j < ncol; j++)
scopy(sqlptr, "%sc%d", j == 0 ? "" : ", ", cols[j]);
scopy(sqlptr, ") nologging");
}
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
for (unsigned j = 0; j < ncol; j++)
imask.set(cols[j]);
ccnt++;
} else if (sel < 5 && ccnt > dcnt + 1) {
scopy(sqlptr = sql, "drop index %s on %s", iname, tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
imask.clear();
dcnt++;
}
}
// insert unique data
unsigned rows = opt.m_scale;
unsigned* uval = new unsigned[rows];
for (unsigned i = 0; i < rows; i++) {
uval[i] = urandom(4);
scopy(sqlptr = sql, "insert into %s values(", tname);
for (unsigned j = 0; j < attrs; j++) {
if (j != 0)
scopy(sqlptr, ",");
unsigned v = (i << 10) | (j << 2) | uval[i];
if (j == 0)
scopy(sqlptr, "%u", i);
else if (j % 2 == 0)
scopy(sqlptr, "%u", v);
else
scopy(sqlptr, "'%010u'", v);
}
scopy(sqlptr, ")");
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
// update each row via random index
for (unsigned i = 0; i < rows; i++) {
unsigned uold = uval[i];
uval[i] = 3 - uval[i];
AttributeMask imask;
do {
unsigned j = urandom(imax);
imask = imasks[j];
} while (imask.isclear());
scopy(sqlptr = sql, "update %s set", tname);
for (unsigned j = 1; j < attrs; j++) {
if (j != 1)
scopy(sqlptr, ",");
/*
* Equality update is just barely doable before savepoints
* provided we change value of keys in every index.
*/
unsigned v = (i << 10) | (j << 2) | uval[i];
if (j == 0)
;
else if (j % 2 == 0)
scopy(sqlptr, " c%d=%u", j, v);
else
scopy(sqlptr, " c%d='%010u'", j, v);
}
scopy(sqlptr, " where 1=1");
while (! imask.isclear()) {
unsigned j = urandom(attrs);
if (imask.get(j)) {
unsigned v = (i << 10) | (j << 2) | uold;
scopy(sqlptr, " and c%d=", j);
if (j == 0)
scopy(sqlptr, "%u", i);
else if (j % 2 == 0)
scopy(sqlptr, "%u", v);
else
scopy(sqlptr, "'%010u'", v);
imask.clear(j);
}
}
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
chkRowCount(test, hStmt, 1);
}
// delete all
scopy(sqlptr = sql, "delete from %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
//
if (opt.m_v >= 2)
ndbout << tname << ": creates " << ccnt << " drops " << dcnt << endl;
delete [] imasks;
delete [] uval;
freeAll(test, hEnv, hDbc, hStmt);
}
static const Sql
miscSql96[] = {
Sql("testMisc96a", testMisc96a),
Sql()
};
// 97
static void
testMisc97a(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
const char* tname = "TT97A";
const char* iname = "XX97A";
char sql[MAX_SQL];
// create in some thread
lock_mutex();
if (my_sema == 0) {
if (opt.m_v >= 1)
ndbout << "thread " << test.m_no << " does setup" << endl;
sprintf(sql, "drop table %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL[" << test.m_no << "]: " << sql << endl;
test.exp(SQL_ERROR, "IM000", 2040709, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
// a-pk b-index c-counter
sprintf(sql, "create table %s (a int primary key, b int, c int) storage(small)", tname);
if (opt.m_v >= 2)
ndbout << "SQL[" << test.m_no << "]: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
for (unsigned i = 0; i < opt.m_scale; i++) {
sprintf(sql, "insert into %s values (%d, %d, %d)", tname, i, 10 * i, 0);
if (opt.m_v >= 3)
ndbout << "SQL[" << test.m_no << "]: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
sprintf(sql, "create index %s on %s (b) nologging", iname, tname);
if (opt.m_v >= 2)
ndbout << "SQL[" << test.m_no << "]: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
my_sema = 1;
}
unlock_mutex();
assert(my_sema == 1);
// parallel run - default rotating pk, ts, is
// frob: low 3 hex digits give alt sequence e.g. 0x311 = pk, pk, is
// frob: 4-th hex digit non-zero says use NDB API e.g. 0x1000
unsigned typelist[3] = { 1, 2, 3 };
for (unsigned i = 0; i < 3; i++) {
unsigned t = (opt.m_frob >> (i * 4)) & 0xf;
if (t != 0)
typelist[i] = t;
}
unsigned type = typelist[(test.m_no - 1) % 3];
if ((opt.m_frob & 0xf000) == 0) {
for (unsigned i = 0; i < opt.m_scale; i++) {
if (type == 1) {
// pk update
sprintf(sql, "update %s set c = c + 1 where a = %d", tname, i % opt.m_scale);
if (opt.m_v >= 3)
ndbout << lock << "SQL[" << test.m_no << "]: " << sql << endl << unlock;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
if (type == 2) {
// table scan update
sprintf(sql, "update %s set c = c + 1 where b + 0 = %d", tname, 10 * i);
if (opt.m_v >= 3)
ndbout << lock << "SQL[" << test.m_no << "]: " << sql << endl << unlock;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
if (type == 3) {
// index scan update
sprintf(sql, "update %s set c = c + 1 where b = %d", tname, 10 * i);
if (opt.m_v >= 3)
ndbout << lock << "SQL[" << test.m_no << "]: " << sql << endl << unlock;
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
}
}
} else {
#ifdef ndbODBC
#define CHK(o, x) do { if (! (x)) { fatal("line %d: %d %s", __LINE__, o->getNdbError().code, o->getNdbError().message); } } while (0)
Ndb* ndb = new Ndb("TEST_DB");
ndb->init();
CHK(ndb, ndb->waitUntilReady() == 0);
Int32 a, b, c;
for (unsigned i = 0; i < opt.m_scale; i++) {
if (type == 1) {
// pk update with exclusive read
NdbConnection* con;
NdbOperation* op;
CHK(ndb, (con = ndb->startTransaction()) != 0);
a = i;
c = -1;
CHK(con, (op = con->getNdbOperation(tname)) != 0);
CHK(op, op->readTupleExclusive() == 0);
CHK(op, op->equal((unsigned)0, (char*)&a, 0) == 0);
CHK(op, op->getValue(2, (char*)&c) != 0);
CHK(con, con->execute(NoCommit) == 0);
c = c + 1;
CHK(con, (op = con->getNdbOperation(tname)) != 0);
CHK(op, op->updateTuple() == 0);
CHK(op, op->equal((unsigned)0, (char*)&a, 0) == 0);
CHK(op, op->setValue(2, (char*)&c) == 0);
CHK(con, con->execute(Commit) == 0);
ndb->closeTransaction(con);
if (opt.m_v >= 3)
ndbout << lock << "thr " << test.m_no << " pk a=" << i << " c=" << c << endl << unlock;
}
if (type == 2) {
// table scan update
NdbConnection* con;
NdbOperation* op;
CHK(ndb, (con = ndb->startTransaction()) != 0);
CHK(con, (op = con->getNdbOperation(tname)) != 0);
CHK(con, op->openScanExclusive(240) == 0);
CHK(op, op->getValue((unsigned)0, (char*)&a) != 0);
CHK(op, op->getValue(2, (char*)&c) != 0);
CHK(con, con->executeScan() == 0);
unsigned rows = 0;
unsigned updates = 0;
while (1) {
int ret;
a = -1;
c = -1;
CHK(con, (ret = con->nextScanResult()) == 0 || ret == 1);
if (ret == 1)
break;
rows++;
if (a == i) {
NdbConnection* con2;
NdbOperation* op2;
CHK(ndb, (con2 = ndb->startTransaction()) != 0);
CHK(op, (op2 = op->takeOverForUpdate(con2)) != 0);
c = c + 1;
CHK(op2, op2->setValue(2, (char*)&c) == 0);
CHK(con2, con2->execute(Commit) == 0);
ndb->closeTransaction(con2);
updates++;
if (opt.m_v >= 3)
ndbout << lock << "thr " << test.m_no << " ts rows=" << rows << " a=" << i << " c=" << c << endl << unlock;
// test stop scan too
CHK(con, con->stopScan() == 0);
break;
}
}
ndb->closeTransaction(con);
test.chk(HStmt(hStmt), updates == 1, "got %u != 1", updates);
}
if (type == 3) {
// index scan update
NdbConnection* con;
NdbOperation* op;
CHK(ndb, (con = ndb->startTransaction()) != 0);
CHK(con, (op = con->getNdbOperation(iname, tname)) != 0);
CHK(con, op->openScanExclusive(240) == 0);
b = 10 * i;
CHK(con, op->setBound((unsigned)0, 4, &b, sizeof(b)) == 0);
CHK(op, op->getValue((unsigned)0, (char*)&a) != 0);
CHK(op, op->getValue(2, (char*)&c) != 0);
CHK(con, con->executeScan() == 0);
unsigned rows = 0;
unsigned updates = 0;
while (1) {
int ret;
a = -1;
c = -1;
CHK(con, (ret = con->nextScanResult()) == 0 || ret == 1);
if (ret == 1)
break;
rows++;
if (a == i) {
NdbConnection* con2;
NdbOperation* op2;
CHK(ndb, (con2 = ndb->startTransaction()) != 0);
CHK(op, (op2 = op->takeOverForUpdate(con2)) != 0);
c = c + 1;
CHK(op2, op2->setValue(2, (char*)&c) == 0);
CHK(con2, con2->execute(Commit) == 0);
ndb->closeTransaction(con2);
updates++;
if (opt.m_v >= 3)
ndbout << lock << "thr " << test.m_no << " is rows=" << rows << " a=" << i << " c=" << c << endl << unlock;
// test stop scan too
CHK(con, con->stopScan() == 0);
break;
}
}
ndb->closeTransaction(con);
test.chk(HStmt(hStmt), rows == 1, "got %u != 1", rows);
test.chk(HStmt(hStmt), updates == 1, "got %u != 1", updates);
}
}
delete ndb;
#undef CHK
#endif
}
// verify result
lock_mutex();
if (++my_sema == 1 + opt.m_threads) {
if (opt.m_v >= 1)
ndbout << "thread " << test.m_no << " does verification" << endl;
sprintf(sql, "select * from %s order by a", tname);
if (opt.m_v >= 2)
ndbout << "SQL[" << test.m_no << "]: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
long a, b, c;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_SLONG, &a, 0, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 2, SQL_C_SLONG, &b, 0, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 3, SQL_C_SLONG, &c, 0, 0));
for (unsigned i = 0; i < opt.m_scale; i++) {
a = b = c = -1;
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.chk(HStmt(hStmt), a == i, "a: got %ld != %u", a, i);
test.chk(HStmt(hStmt), b == 10 * i, "b: got %ld != %u", b, 10 * i);
test.chk(HStmt(hStmt), c == opt.m_threads, "c: got %ld != %u", c, opt.m_threads);
if (opt.m_v >= 4)
ndbout << "verified " << i << endl;
}
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (opt.m_v >= 2)
ndbout << "thr " << test.m_no << " verified " << opt.m_scale << " rows" << endl;
my_sema = 0;
}
unlock_mutex();
freeAll(test, hEnv, hDbc, hStmt);
}
static const Sql
miscSql97[] = {
Sql("testMisc97a", testMisc97a),
Sql()
};
// 99
static void
testMisc99a(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
// bad
const char* sqlInsertBad = "insert into tt99a values(?, ?, ?, ?, ?)";
test.exp(SQL_ERROR, "21S01", -1, true);
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sqlInsertBad, SQL_NTS));
// good
const char* sqlInsert = "insert into tt99a (col1, col2, col3, col4, col5) values(?, ?, ?, ?, ?)";
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sqlInsert, SQL_NTS));
unsigned long value;
for (unsigned i = 1; i <= 5; i++) {
test.run(HStmt(hStmt), SQLBindParameter(hStmt, i, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &value, 0, 0));
}
const unsigned long base = 1000000000;
const unsigned long scale = 10;
for (value = base; value < base + scale; value++) {
test.run(HStmt(hStmt), SQLExecute(hStmt));
}
// bug1: re-analyze of converted expression...
const char* sqlSelect = "select col5 from tt99a where col2 + 0 = ?";
unsigned long output;
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_ULONG, &output, 0, 0));
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sqlSelect, SQL_NTS));
// bug2: previous bind must survive a new SQLPrepare
if (0) {
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &value, 0, 0));
}
for (value = base; value < base + scale; value++) {
if (value > base + 4) {
// bug1: ...when IPD changed by JDBC
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &value, 0, 0));
}
test.run(HStmt(hStmt), SQLExecute(hStmt));
output = (unsigned long)-1;
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.chk(HStmt(hStmt), output == value, "got %lu != %lu", output, value);
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
test.timerCnt(1);
}
freeAll(test, hEnv, hDbc, hStmt);
}
static void
testMisc99c(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
const char* sql = "select b from tt99c where a = ?";
const unsigned long c1 = 2100000000U;
const unsigned long c2 = 4100000000U;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
unsigned long aval, bval;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &aval, 0, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_ULONG, &bval, 0, 0));
// uno
for (unsigned i = 0; i < opt.m_scale; i++) {
aval = c1;
bval = (unsigned long)-1;
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << " [?=" << (Uint64)aval << "]" << endl;
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.chk(HStmt(hStmt), bval == c2, "got %lu != %lu", bval, c2);
//test.exp(SQL_NO_DATA, 0, 0, true);
//test.run(HStmt(hStmt), SQLFetch(hStmt));
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
}
// dos
for (unsigned i = 0; i < opt.m_scale; i++) {
break; // XXX not yet, hangs in NDB ?!?
aval = c2;
bval = (unsigned long)-1;
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << " [?=" << (Uint64)aval << "]" << endl;
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.chk(HStmt(hStmt), bval == c1, "got %lu != %lu", bval, c2);
//test.exp(SQL_NO_DATA, 0, 0, true);
//test.run(HStmt(hStmt), SQLFetch(hStmt));
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
}
freeAll(test, hEnv, hDbc, hStmt);
}
static void
testMisc99d(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
const char* tname = "TT99D";
char sql[MAX_SQL];
sprintf(sql, "drop table %s", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.exp(SQL_ERROR, "IM000", 2040709, false);
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
sprintf(sql, "create table %s (a bigint unsigned, b bigint, primary key (a))", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLExecDirect(hStmt, (SQLCHAR*)sql, SQL_NTS));
sprintf(sql, "insert into %s values (?, ?)", tname);
if (opt.m_v >= 2)
ndbout << "SQL: " << sql << endl;
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
// XXX replace by 100 when signed vs unsigned resolved
const unsigned num = 78;
SQLUBIGINT aval;
SQLBIGINT bval;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_BIGINT, 0, 0, &aval, 0, 0));
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_BIGINT, 0, 0, &bval, 0, 0));
for (SQLBIGINT i = 0; i < num; i++) {
if (opt.m_v >= 3)
ndbout << "insert " << i << endl;
aval = i * i * i * i * i * i * i * i * i * i; // 10
bval = -aval;
test.run(HStmt(hStmt), SQLExecute(hStmt));
}
sprintf(sql, "select a, b from tt99d where a = ?");
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql, SQL_NTS));
SQLUBIGINT kval;
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_BIGINT, 0, 0, &kval, 0, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_UBIGINT, &aval, 0, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 2, SQL_C_SBIGINT, &bval, 0, 0));
for (SQLBIGINT i = 0; i < num; i++) {
kval = i * i * i * i * i * i * i * i * i * i; // 10
if (opt.m_v >= 3)
ndbout << "fetch " << i << " key " << kval << endl;
test.run(HStmt(hStmt), SQLExecute(hStmt));
aval = bval = 0;
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.chk(HStmt(hStmt), aval == kval && bval == -kval, "got %llu, %lld != %llu, %lld", aval, bval, kval, -kval);
test.exp(SQL_NO_DATA, 0, 0, true);
test.run(HStmt(hStmt), SQLFetch(hStmt));
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
}
freeAll(test, hEnv, hDbc, hStmt);
}
static void
testMiscC2(Test& test)
{
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
#if 0
{
char POP[255];
char PORT[255];
char ACCESSNODE[255];
const char* sqlSelect = "select PORT from AAA where POP=? and ACCESSNODE=?";
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sqlSelect, SQL_NTS));
for (int j=0; j<5; j++) {
printf("Loop %u\n", j);
printf("LINE %u\n", __LINE__);
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 255, 0, POP, 255, 0));
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 255, 0, ACCESSNODE, 255, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_CHAR, PORT, 255, 0));
sprintf(POP, "a");
sprintf(ACCESSNODE, "b");
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.run(HStmt(hStmt), SQLFetch(hStmt));
printf("got %s\n", PORT);
printf("LINE %u\n", __LINE__);
test.exp(SQL_NO_DATA, 0, 0, true);
printf("LINE %u\n", __LINE__);
test.run(HStmt(hStmt), SQLFetch(hStmt));
printf("LINE %u\n", __LINE__);
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
printf("LINE %u\n", __LINE__);
}
}
return;
#endif
char POP[255];
char PORT[255];
char ACCESSNODE[255];
unsigned long VLAN = 0;
unsigned long SNMP_INDEX = 0;
unsigned long PORT_STATE = 0;
unsigned long STATIC_PORT = 0;
unsigned long COMMENT = 0;
const char* sqlSelect = "select PORT, PORT_STATE from PORTS where POP=? and ACCESSNODE=?";
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sqlSelect, SQL_NTS));
for (int j=0; j<5; j++) {
printf("Loop %u\n", j);
printf("LINE %u\n", __LINE__);
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 255, 0, POP, 255, 0));
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 255, 0, ACCESSNODE, 255, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_CHAR, PORT, 255, 0));
test.run(HStmt(hStmt), SQLBindCol(hStmt, 2, SQL_C_ULONG, &PORT_STATE, 0, 0));
sprintf(POP, "row%u.i%u.bredband.com", 2, 3);
sprintf(ACCESSNODE, "as%u", 2);
test.run(HStmt(hStmt), SQLExecute(hStmt));
for (int i=0; i < 3; i++) {
PORT_STATE=0;
sprintf(PORT, "XXXXXXXXXXXXXXXXXXXXX");
test.run(HStmt(hStmt), SQLFetch(hStmt));
printf("got %s %lu\n", PORT, PORT_STATE);
// test.chk(HStmt(hStmt), false, "got %s != %s", "xxx", PORT);
}
printf("LINE %u\n", __LINE__);
test.exp(SQL_NO_DATA, 0, 0, true);
printf("LINE %u\n", __LINE__);
test.run(HStmt(hStmt), SQLFetch(hStmt));
printf("LINE %u\n", __LINE__);
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
printf("LINE %u\n", __LINE__);
}
}
static const Sql
miscSqlC2[] = {
Sql("drop table PORTS",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table PORTS (POP varchar(200) not null, ACCESSNODE varchar(200) not null, PORT varchar(200) not null, VLAN int unsigned, SNMP_INDEX int unsigned, PORT_STATE int unsigned, STATIC_PORT int unsigned, COMMENT int unsigned, primary key (POP,ACCESSNODE,PORT))",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("create index xxPORTS on PORTS (POP, ACCESSNODE) nologging",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
Sql("insert into PORTS values ('row2.i3.bredband.com','as2','Fa0/0',0,1,2,3,4)",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("insert into PORTS values ('row2.i3.bredband.com','as2','Fa0/1',1,2,3,4,5)",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("insert into PORTS values ('row2.i3.bredband.com','as2','Fa0/2',2,3,4,5,6)",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("select PORT, PORT_STATE from PORTS where POP='row2.i3.bredband.com' and ACCESSNODE='as2'",
SQL_DIAG_SELECT_CURSOR, 3, 3, -1, -1),
Sql("drop table AAA",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table AAA (POP varchar(200), ACCESSNODE varchar(200) not null, PORT varchar(200) not null, primary key (POP,ACCESSNODE,PORT))",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("create index xxAAA on AAA (POP, ACCESSNODE) nologging",
SQL_DIAG_CREATE_INDEX, -1, -1, -1, -1),
Sql("insert into AAA values ('a','b','A')",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("testMiscC2", testMiscC2),
Sql()
};
/*
> SELECT PORT, PORT_STATE FROM PORTS where pop=? and accessnode=?
> SELECT VLAN, SNMP_INDEX, PORT_STATE, STATIC_PORT, COMMENT FROM PORTS WHERE POP=? AND ACCESSNODE=? AND PORT=?
> select count(*) from ports
> select snmp_index from ports where pop='row2.i3.bredband.com' and accessnode='as2' and port='Fa0/2'
> SELECT MAC, MAC_EXPIRE, IP, IP_EXPIRE, HOSTNAME, DETECTED, STATUS, STATIC_DNS, BLOCKED, NUM_REQUESTS, ACCESSTYPE, OS_TYPE, GATE_WAY, DIRTY_FLAG, LOCKED_IP FROM CLIENTS WHERE PORT=? AND ACCESSNODE=? AND POP=?
> SELECT SERVICES.ACCESSTYPE, SERVICES.NUM_IP, SERVICES.TEXPIRE, SERVICES.CUSTOMER_ID, SERVICES.LEASED_NUM_IP, SERVICES.PROVIDER, SERVICES.LOCKED_IP, SERVICES.STATIC_DNS, SERVICES.SUSPENDED_SERVICE FROM SERVICES , ACCESSTYPES WHERE SERVICES.PORT = ? AND SERVICES.ACCESSNODE = ? AND SERVICES.POP = ? AND SERVICES.ACCESSTYPE=ACCESSTYPES.ACCESSTYPE
*/
static const Sql
miscSql99[] = {
Sql("drop table tt99a",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt99a (col1 int unsigned primary key, col2 int unsigned, col3 int unsigned, col4 int unsigned, col5 int unsigned, col6 varchar(7) default 'abc123')",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
// inserts 10 rows, all same, start value 1000000000
Sql("testMisc99a", testMisc99a),
// interpreted scan plus bind parameter
Sql("select col1 from tt99a where col2 = ?",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1000000004, 1000000004),
Sql("select col1 from tt99a where col2 = 1000000000 + ?",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1000000004, 4),
Sql("select col1 from tt99a where col2 = ? + 1000000000",
SQL_DIAG_SELECT_CURSOR, 1, 1, 1000000004, 4),
// same not interpreted, tuple count 10
Sql("select col1 from tt99a where col2 + 0 = 1000000000 + ?",
SQL_DIAG_SELECT_CURSOR, 1, 10, 1000000004, 4),
// varchar variations
Sql("select count(*) from tt99a where col6 = 'abc123'",
SQL_DIAG_SELECT_CURSOR, 1, 10, 10, -1),
Sql("select count(*) from tt99a where left(col6, ?) = 'abc1'",
SQL_DIAG_SELECT_CURSOR, 1, 10, 10, 4),
Sql("select count(*) from tt99a where left(col6, ?) = 'abc1'",
SQL_DIAG_SELECT_CURSOR, 1, 10, 0, 3),
// tpc-b inspired, wrong optimization to direct update
Sql("drop table tt99b",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt99b(a int primary key, b int not null, c double precision)",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("insert into tt99b values(1, 10, 100.0)",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("insert into tt99b values(9, 90, 900.0)",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("create unique hash index tt99y on tt99b (b)",
SQL_DIAG_CREATE_INDEX, -1, 0, -1, -1),
// first scan update..
Sql("update tt99b set c = c + ? where a+0 = 1",
SQL_DIAG_UPDATE_WHERE, 1, 2, -1, 10),
Sql("update tt99b set c = c + ? where b+0 = 10",
SQL_DIAG_UPDATE_WHERE, 1, 2, -1, 10),
// then optimized..
Sql("update tt99b set c = c + ? where a = 1",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, 10),
Sql("update tt99b set c = c + ? where b = 10",
SQL_DIAG_UPDATE_WHERE, 1, 1, -1, 10),
// verify..
Sql("select count(*) from tt99b where 100-1 < c and c < 140-1",
SQL_DIAG_SELECT_CURSOR, 1, 2, 0, -1),
Sql("select count(*) from tt99b where 140-.001 < c and c < 140+.001",
SQL_DIAG_SELECT_CURSOR, 1, 2, 1, -1),
// unsigned test
Sql("drop table tt99c",
SQL_DIAG_DROP_TABLE, -1, 0, -1, -1,
SQL_ERROR, "IM000", 2040709, false),
Sql("create table tt99c(a int unsigned primary key, b int unsigned)",
SQL_DIAG_CREATE_TABLE, -1, 0, -1, -1),
Sql("insert into tt99c values(2100000000, 4100000000)",
SQL_DIAG_INSERT, 1, 0, -1, -1),
Sql("insert into tt99c (a, b) select b, a from tt99c",
SQL_DIAG_INSERT, 1, 1, -1, -1),
Sql("testMisc99c", testMisc99c),
// new external type SQL_C_[SU]BIGINT
Sql("testMisc99d", testMisc99d),
Sql()
};
static const struct { const Sql* sql; int minscale; }
miscSql[11] = {
{ miscSql90, 0 },
{ miscSql91, 0 },
{ miscSql92, 0 },
{ miscSql93, 0 },
{ 0, 0 }, // 94
{ miscSql95, 0 },
{ miscSql96, 0 },
{ miscSql97, 0 },
{ 0, 0 }, // 98
{ miscSql99, 0 },
{ miscSqlC2, 0 }
};
static void
testSql(Test& test)
{
const unsigned salt = test.m_stuff; // mess
if (opt.m_scale < miscSql[salt].minscale) {
if (opt.m_v >= 1)
ndbout << "skip - requires scale >= " << miscSql[salt].minscale << endl;
return;
}
assert(0 <= salt && salt < 11 && miscSql[salt].sql != 0);
SQLHANDLE hEnv, hDbc, hStmt;
allocAll(test, hEnv, hDbc, hStmt);
for (unsigned i = 0; ; i++) {
const Sql& sql = miscSql[salt].sql[i];
if (sql.m_sql == 0)
break;
if (opt.m_v >= 2)
ndbout << "SQL: " << sql.m_sql << endl;
if (sql.m_testFunc != 0) {
(*sql.m_testFunc)(test);
continue;
}
if (strncmp(sql.m_sql, "--", 2) == 0) {
continue;
}
if (strcmp(sql.m_sql, Sql::set_autocommit_on()) == 0) {
setAutocommit(test, hDbc, true);
continue;
}
if (strcmp(sql.m_sql, Sql::set_autocommit_off()) == 0) {
setAutocommit(test, hDbc, false);
continue;
}
if (strcmp(sql.m_sql, Sql::do_commit()) == 0) {
test.run(HDbc(hDbc), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT));
continue;
}
if (strcmp(sql.m_sql, Sql::do_rollback()) == 0) {
test.run(HDbc(hDbc), SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_ROLLBACK));
continue;
}
if (opt.m_v >= 3) {
ndbout << "expect:";
ndbout << " ret=" << sql.m_ret;
ndbout << " rows=" << sql.m_rowCount;
ndbout << " tuples=" << sql.m_tuplesFetched;
ndbout << endl;
}
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_UNBIND));
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_RESET_PARAMS));
// prep
test.exp(sql.m_ret, sql.m_state, sql.m_native, false);
test.run(HStmt(hStmt), SQLPrepare(hStmt, (SQLCHAR*)sql.m_sql, SQL_NTS));
if (test.m_ret != SQL_SUCCESS)
continue;
// bind between prep and exec like JDBC
unsigned long bindValue = sql.m_bindValue;
for (int k = 0; k <= 1; k++) {
if (bindValue != -1) {
assert(strchr(sql.m_sql, '?') != 0);
test.run(HStmt(hStmt), SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &bindValue, 0, 0));
}
if (k == 0) {
if (bindValue != -1) {
test.run(HStmt(hStmt), SQLFreeStmt(hStmt, SQL_RESET_PARAMS));
// exec with unbound parameter
test.exp(SQL_ERROR, "HY010", -1, true);
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == sql.m_functionCode || sql.m_functionCode == -1, "func: got %d != %d", (int)test.m_functionCode, (int)sql.m_functionCode);
}
} else {
// exec
test.exp(sql.m_ret, sql.m_state, sql.m_native, sql.m_reset);
test.run(HStmt(hStmt), SQLExecute(hStmt));
test.chk(HStmt(hStmt), test.m_functionCode == sql.m_functionCode || sql.m_functionCode == -1, "func: got %d != %d", (int)test.m_functionCode, (int)sql.m_functionCode);
}
}
if (sql.m_rowCount != -1) {
if (sql.m_functionCode == SQL_DIAG_SELECT_CURSOR) {
long lastValue;
if (sql.m_lastValue != -1)
test.run(HStmt(hStmt), SQLBindCol(hStmt, 1, SQL_C_SLONG, &lastValue, 0, 0));
unsigned k = 0;
do {
int rowCount = 0;
lastValue = -1;
while (1) {
test.exp(SQL_NO_DATA, 0, 0, false);
test.run(HStmt(hStmt), SQLFetch(hStmt));
if (test.m_ret == SQL_NO_DATA)
break;
rowCount++;
}
test.chk(HStmt(hStmt), rowCount == sql.m_rowCount, "rowCount: got %d != %d", (int)rowCount, (int)sql.m_rowCount);
if (sql.m_tuplesFetched != -1)
chkTuplesFetched(test, hStmt, sql.m_tuplesFetched);
if (rowCount > 0 && sql.m_lastValue != -1)
test.chk(HStmt(hStmt), lastValue == sql.m_lastValue, "lastValue: got %ld != %ld", (long)lastValue, (long)sql.m_lastValue);
test.run(HStmt(hStmt), SQLCloseCursor(hStmt));
if (++k >= opt.m_scale)
break;
test.run(HStmt(hStmt), SQLExecute(hStmt));
} while (1);
test.timerCnt(opt.m_scale);
} else {
assert(sql.m_lastValue == -1);
chkRowCount(test, hStmt, sql.m_rowCount);
if (sql.m_tuplesFetched != -1)
chkTuplesFetched(test, hStmt, sql.m_tuplesFetched);
test.timerCnt(1);
}
}
}
freeAll(test, hEnv, hDbc, hStmt);
}
// name, function, runmode, salt (0=const or n/a), description
static const Case caseList[] = {
Case( "00alloc", testAlloc, Case::Thread, 0, "allocate handles" ),
Case( "01create", testCreate, Case::Single, 0, "create tables for the test" ),
Case( "02prepare", testPrepare, Case::Thread, 0, "prepare without execute" ),
Case( "03catalog", testCatalog, Case::Thread, 0, "catalog functions" ),
Case( "10insert", testInsert, Case::Thread, 1, "insert computed rows" ),
Case( "11delall", testDeleteAll, Case::Single, 0, "delete all rows via scan" ),
Case( "12insert", testInsert, Case::Thread, 1, "insert computed rows again" ),
Case( "13count", testCount, Case::Single, 0, "count rows" ),
Case( "14verpk", testVerifyPk, Case::Thread, 1, "verify via primary key" ),
Case( "15verscan", testVerifyScan, Case::Serial, 1, "verify via range scans" ),
Case( "16join", testJoin, Case::Single, 0, "multiple self-join" ),
Case( "17cart", testCart, Case::Single, 0, "cartesian join" ),
Case( "20updpk", testUpdatePk, Case::Thread, 2, "update via primary key" ),
Case( "21verpk", testVerifyPk, Case::Thread, 2, "verify via primary key" ),
Case( "22verscan", testVerifyScan, Case::Serial, 2, "verify via range scans" ),
Case( "23updscan", testUpdateScan, Case::Serial, 0, "update via scan" ),
Case( "24verpk", testVerifyPk, Case::Thread, 0, "verify via primary key" ),
Case( "25verscan", testVerifyScan, Case::Serial, 0, "verify via range scans" ),
Case( "26delpk", testDeletePk, Case::Thread, 0, "delete via primary key" ),
Case( "30trans", testTrans, Case::Single, 3, "rollback and commit" ),
Case( "31concur", testConcur, Case::Single, 0, "commit across open cursor" ),
Case( "32readcom", testReadcom, Case::Single, 0, "read committed" ),
Case( "40perf", testPerf, Case::Single, 0, "perf test prepare" ),
Case( "41perf", testPerf, Case::Thread, 1, "perf test NDB API" ),
Case( "42perf", testPerf, Case::Thread, 2, "perf test NDB ODBC" ),
Case( "90sql", testSql, Case::Single, 0, "misc SQL: metadata" ),
Case( "91sql", testSql, Case::Single, 1, "misc SQL: misc" ),
Case( "92sql", testSql, Case::Thread, 2, "misc SQL: scan rollback" ),
Case( "93sql", testSql, Case::Single, 3, "misc SQL: locking" ),
Case( "95sql", testSql, Case::Single, 5, "misc SQL: indexes (simple)" ),
Case( "96sql", testSql, Case::Single, 6, "misc SQL: indexes" ),
Case( "97sql", testSql, Case::Thread, 7, "misc SQL: indexes" ),
Case( "99sql", testSql, Case::Single, 9, "misc SQL: bug du jour" ),
Case( "C2", testSql, Case::Single, 10, "misc SQL: C2" )
};
static const unsigned caseCount = arraySize(caseList);
static bool
findCase(const char* name)
{
for (unsigned i = 0; i < caseCount; i++) {
const Case& cc = caseList[i];
if (strstr(cc.m_name, name) != 0)
return true;
}
return false;
}
static void
listCases()
{
ndbout << "cases:" << endl;
unsigned m = 0;
for (unsigned i = 0; i < caseCount; i++) {
const Case& cc = caseList[i];
if (m < strlen(cc.m_name))
m = strlen(cc.m_name);
}
for (unsigned i = 0; i < caseCount; i++) {
const Case& cc = caseList[i];
char buf[200];
sprintf(buf, "%-*s [%-6s] %s", m, cc.m_name, cc.modename(), cc.m_desc);
ndbout << buf << endl;
}
}
// threads
extern "C" { static void* testThr(void* arg); }
struct Thr {
enum State {
Wait = 1, // wait for test case
Run = 2, // run the test case
Done = 3, // done with the case
Exit = 4 // exit thread
};
unsigned m_no; // thread number 1 .. max
NdbThread* m_thr; // thread id etc
const Case* m_case; // current case
State m_state; // condition variable
NdbMutex* m_mutex; // condition guard
NdbCondition* m_cond;
void* m_status; // exit status (not used)
Test m_test; // test runner
Thr(unsigned no, unsigned loop) :
m_no(no),
m_thr(0),
m_case(0),
m_state(Wait),
m_mutex(NdbMutex_Create()),
m_cond(NdbCondition_Create()),
m_status(0),
m_test(no, loop) {
}
~Thr() {
destroy();
NdbCondition_Destroy(m_cond);
NdbMutex_Destroy(m_mutex);
}
void create() {
assert(m_thr == 0);
m_thr = NdbThread_Create(testThr, (void**)this, 64*1024, "test", NDB_THREAD_PRIO_LOW);
}
void destroy() {
if (m_thr != 0)
NdbThread_Destroy(&m_thr);
m_thr = 0;
}
void lock() {
NdbMutex_Lock(m_mutex);
}
void unlock() {
NdbMutex_Unlock(m_mutex);
}
void wait() {
NdbCondition_Wait(m_cond, m_mutex);
}
void signal() {
NdbCondition_Signal(m_cond);
}
void join() {
NdbThread_WaitFor(m_thr, &m_status);
m_thr = 0;
}
// called from main
void mainStart(const Case& cc) {
lock();
m_case = &cc;
m_state = Run;
signal();
unlock();
}
void mainStop() {
lock();
while (m_state != Done) {
if (opt.m_v >= 4)
ndbout << ::lock << "thr " << m_no << " [main] wait state=" << m_state << endl << ::unlock;
wait();
}
if (opt.m_v >= 4)
ndbout << ::lock << "thr " << m_no << " [main] done" << endl << ::unlock;
m_state = Wait;
unlock();
}
// run in thread
void testSelf() {
while (1) {
lock();
while (m_state != Run && m_state != Exit) {
if (opt.m_v >= 4)
ndbout << ::lock << "thr " << m_no << " [self] wait state=" << m_state << endl << ::unlock;
wait();
}
if (m_state == Run) {
if (opt.m_v >= 4)
ndbout << ::lock << "thr " << m_no << " [self] run" << endl << ::unlock;
assert(m_case != 0);
m_test.timerOn();
m_test.runCase(*m_case);
m_test.timerOff();
m_state = Done;
if (opt.m_v >= 4)
ndbout << ::lock << "thr " << m_no << " [self] done" << endl << ::unlock;
signal();
unlock();
} else if (m_state == Exit) {
unlock();
break;
} else {
assert(false);
}
}
if (opt.m_v >= 4)
ndbout << ::lock << "thr " << m_no << " [self] exit" << endl << ::unlock;
}
};
static void*
testThr(void* arg)
{
Thr& thr = *(Thr*)arg;
thr.testSelf();
return 0;
}
#ifdef DMALLOC
extern "C" {
static int malloc_bytes = 0;
static int free_bytes = 0;
static void
malloc_track(const char *file, const unsigned int line, const int func_id, const DMALLOC_SIZE byte_size, const DMALLOC_SIZE alignment, const DMALLOC_PNT old_addr, const DMALLOC_PNT new_addr)
{
if (func_id == DMALLOC_FUNC_MALLOC) {
malloc_bytes += byte_size;
return;
}
if (func_id == DMALLOC_FUNC_FREE) {
DMALLOC_SIZE size = 0;
dmalloc_examine(old_addr, &size, 0, 0, 0);
free_bytes += size;
// XXX useless - byte_size and size are 0
return;
}
}
}
#endif /* DMALLOC */
static void
testMain()
{
#ifndef NDB_LINUX /* valgrind-1.0.3 does not support */
NdbThread_SetConcurrencyLevel(opt.m_threads + 2);
#endif
#ifdef DMALLOC
dmalloc_track(malloc_track);
#endif
Test test(0, 0);
#ifdef ndbODBC
Ndb* ndb = 0;
if (1) { // pre-alloc one Ndb object
ndb = new Ndb("TEST_DB");
ndb->init();
if (ndb->waitUntilReady() != 0) {
ndbout << ndb->getNdbError() << endl;
fatal("waitUntilReady");
}
}
#endif
for (unsigned loop = 1; opt.m_loop == 0 || loop <= opt.m_loop; loop++) {
if (opt.m_v >= 2)
ndbout << "loop " << loop << endl;
// create new set of threads in each loop
Thr** thrList = new Thr* [1 + opt.m_threads];
for (unsigned n = 1; n <= opt.m_threads; n++) {
Thr& thr = *(thrList[n] = new Thr(n, loop));
thr.create();
if (opt.m_v >= 4)
ndbout << "thr " << n << " [main] created" << endl;
}
#ifdef DMALLOC
malloc_bytes = free_bytes = 0;
#endif
for (unsigned i = 0; i < caseCount; i++) {
const Case& cc = caseList[i];
if (! cc.matchcase())
continue;
if (opt.m_v >= 2)
ndbout << "RUN: " << cc.m_name << " - " << cc.m_desc << endl;
test.timerOn();
for (unsigned subloop = 1; subloop <= opt.m_subloop; subloop++) {
my_sema = 0;
if (opt.m_v >= 3)
ndbout << "subloop " << subloop << endl;
if (cc.m_mode == Case::Single) {
Thr& thr = *thrList[1];
thr.mainStart(cc);
thr.mainStop();
test.timerCnt(thr.m_test);
} else if (cc.m_mode == Case::Serial) {
for (unsigned n = 1; n <= opt.m_threads; n++) {
Thr& thr = *thrList[n];
thr.mainStart(cc);
thr.mainStop();
test.timerCnt(thr.m_test);
}
} else if (cc.m_mode == Case::Thread) {
for (unsigned n = 1; n <= opt.m_threads; n++) {
Thr& thr = *thrList[n];
thr.mainStart(cc);
}
for (unsigned n = 1; n <= opt.m_threads; n++) {
Thr& thr = *thrList[n];
thr.mainStop();
test.timerCnt(thr.m_test);
}
} else {
assert(false);
}
}
test.timerOff();
if (opt.m_v >= 1)
ndbout << cc.m_name << " total " << test << endl;
}
#ifdef DMALLOC
if (opt.m_v >= 9) // XXX useless now
ndbout << "malloc " << malloc_bytes << " free " << free_bytes << " lost " << malloc_bytes - free_bytes << endl;
#endif
// tell threads to exit
for (unsigned n = 1; n <= opt.m_threads; n++) {
Thr& thr = *thrList[n];
thr.lock();
thr.m_state = Thr::Exit;
thr.signal();
thr.unlock();
if (opt.m_v >= 4)
ndbout << "thr " << n << " [main] told to exit" << endl;
}
for (unsigned n = 1; n <= opt.m_threads; n++) {
Thr& thr = *thrList[n];
thr.join();
if (opt.m_v >= 4)
ndbout << "thr " << n << " [main] joined" << endl;
delete &thr;
}
delete[] thrList;
}
#ifdef ndbODBC
delete ndb;
#endif
}
static bool
str2num(const char* arg, const char* str, unsigned* num, unsigned lo = 0, unsigned hi = 0)
{
char* end = 0;
long n = strtol(str, &end, 0);
if (end == 0 || *end != 0 || n < 0) {
ndbout << arg << " " << str << " is invalid number" << endl;
return false;
}
if (lo != 0 && n < lo) {
ndbout << arg << " " << str << " is too small min = " << lo << endl;
return false;
}
if (hi != 0 && n > hi) {
ndbout << arg << " " << str << " is too large max = " << hi << endl;
return false;
}
*num = n;
return true;
}
NDB_COMMAND(testOdbcDriver, "testOdbcDriver", "testOdbcDriver", "testOdbcDriver", 65535)
{
while (++argv, --argc > 0) {
const char* arg = argv[0];
if (strcmp(arg, "-case") == 0) {
if (++argv, --argc > 0) {
assert(opt.m_namecnt < arraySize(opt.m_name));
opt.m_name[opt.m_namecnt++] = argv[0];
if (findCase(argv[0]))
continue;
}
}
if (strcmp(arg, "-core") == 0) {
opt.m_core = true;
continue;
}
if (strcmp(arg, "-depth") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_depth))
continue;
}
}
if (strcmp(arg, "-dsn") == 0) {
if (++argv, --argc > 0) {
opt.m_dsn = argv[0];
continue;
}
}
if (strcmp(arg, "-frob") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_frob))
continue;
}
}
if (strcmp(arg, "-errs") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_errs))
continue;
}
}
if (strcmp(arg, "-fragtype") == 0) {
if (++argv, --argc > 0) {
opt.m_fragtype = argv[0];
continue;
}
}
if (strcmp(arg, "-home") == 0) {
if (++argv, --argc > 0) {
opt.m_home = argv[0];
continue;
}
}
if (strcmp(arg, "-loop") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_loop))
continue;
}
}
if (strcmp(arg, "-nogetd") == 0) {
opt.m_nogetd = true;
continue;
}
if (strcmp(arg, "-noputd") == 0) {
opt.m_noputd = true;
continue;
}
if (strcmp(arg, "-nosort") == 0) {
opt.m_nosort = true;
continue;
}
if (strcmp(arg, "-scale") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_scale))
continue;
}
}
if (strcmp(arg, "-serial") == 0) {
opt.m_serial = true;
continue;
}
if (strcmp(arg, "-skip") == 0) {
if (++argv, --argc > 0) {
assert(opt.m_skipcnt < arraySize(opt.m_skip));
opt.m_skip[opt.m_skipcnt++] = argv[0];
if (findCase(argv[0]))
continue;
}
}
if (strcmp(arg, "-subloop") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_subloop))
continue;
}
}
if (strcmp(arg, "-table") == 0) {
if (++argv, --argc > 0) {
opt.m_table = argv[0];
if (findTable())
continue;
}
}
if (strcmp(arg, "-threads") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_threads, 1, MAX_THR))
continue;
}
}
if (strcmp(arg, "-trace") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_trace))
continue;
}
}
if (strcmp(arg, "-v") == 0) {
if (++argv, --argc > 0) {
if (str2num(arg, argv[0], &opt.m_v))
continue;
}
}
if (strncmp(arg, "-v", 2) == 0 && isdigit(arg[2])) {
if (str2num(arg, &arg[2], &opt.m_v))
continue;
}
printusage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
homeEnv: {
static char env[1000];
if (opt.m_home != 0) {
sprintf(env, "NDB_HOME=%s", opt.m_home);
putenv(env);
}
}
traceEnv: {
static char env[40];
sprintf(env, "NDB_ODBC_TRACE=%u", opt.m_trace);
putenv(env);
}
debugEnv: {
static char env[40];
sprintf(env, "NDB_ODBC_DEBUG=%d", 1);
putenv(env);
}
testMain();
return NDBT_ProgramExit(NDBT_OK);
}
// vim: set sw=4: