summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/test/suite/test_join01.py
diff options
context:
space:
mode:
authorRamon Fernandez <ramon@mongodb.com>2016-07-26 21:38:07 -0400
committerRamon Fernandez <ramon@mongodb.com>2016-07-26 21:39:41 -0400
commit385faa6ca72ad599d92d3948f1a2033d908e0226 (patch)
treeea6cc0faad72d06858cc6f094166a20b19489c71 /src/third_party/wiredtiger/test/suite/test_join01.py
parent482cc73bc00a09246f503fbe4026c539ac7f205b (diff)
downloadmongo-385faa6ca72ad599d92d3948f1a2033d908e0226.tar.gz
Import wiredtiger-wiredtiger-2.8.0-592-g848e5f5.tar.gz from wiredtiger branch mongodb-3.2
ref: 8b7110b..848e5f5 for: 3.2.9 This commit replaces a number of previous backports with the original change, so some of the tickets listed below may have been resolved in previous versions already as a backport to the v3.2 branch. For example, SERVER-24580 includes change a63e21b8 as a cherry-pick of 1f4aaa44, but this commit replaces that change with 1f4aaa44 itself. SERVER-23659 Provide useful message when wiredTigerJournalCompressor is changed SERVER-23661 $sample takes disproportionately long time on newly created collection SERVER-24306 40-second journaling stall from "log files prepared" to checkpoint SERVER-24580 Improve performance when WiredTiger cache is full WT-2103 Add incremental backup testing to format WT-2223 Add stress testing for in-memory WT-2268 JSON load incorrect with UNICODE input WT-2319 Add statistics around fsync calls WT-2325 Fix an incomplete comment WT-2343 Assert we don't remove or rename when backup cursor is open WT-2349 Add ability to open databases read-only WT-2359 WiredTiger with Python will hang if a calloc failure occurs during __wt_connection_close WT-2360 Allow disjunctions and combinations of operations in join cursors WT-2408 Windows error translation layer WT-2446 Estimate WT cache hit ratio WT-2450 Salvage releases pages, then explicitly evicts them. WT-2453 Throughput drop in wtperf evict Jenkins tests WT-2479 Dump utility discards table config (JSON) WT-2491 The dhandle close_lock isn't valuable at the moment WT-2504 Should READONLY always read basecfg file? WT-2505 Review clang analyzer warnings WT-2508 Test programs should remove test directories on the "clean" target WT-2514 Log path name is an empty string. WT-2518 LSM checkpoint handle acquisition optimization WT-2520 WT_SESSION::verify should not alter tables WT-2526 Mixing and matching readonly and read/write handles WT-2535 Extend test/format to test for transactions reading their writes WT-2537 Cannot open DB written by WT2.6.1 with WT2.8.0 due to WT_NOTFOUND on recovery WT-2539 Implement file streaming above pluggable filesystems WT-2540 Separate stream and file handle methods WT-2541 Add statistics for number of threads currently in read/write WT-2542 Fixed-length column store reconciliation overwrites original values WT-2544 Fix eviction statistics when clear is configured WT-2546 Eviction server not help evict pages sometimes WT-2547 Add 1-eviction-worker jobs to Jenkins WT-2548 Cap the amount of data handed to raw compression. WT-2549 joins using recno keys return no values WT-2550 java ex_schema example fails WT-2552 Public API for pluggable filesystems WT-2553 Document in-memory configuration and WT_CACHE_FULL error return WT-2554 Implement a framework for adding C test cases WT-2556 Typo in the Java example code WT-2557 format test program should discard log files after incremental backup WT-2558 WT_PAGE structure reorganization WT-2559 Windows segfault in logging code WT-2560 Stuck trying to update oldest transaction ID WT-2562 Reconfig02 test failing sometimes on PPC WT-2565 Item 3573 on page at [write-check] is a corrupted cell WT-2566 All lock operations should be barriers WT-2567 Segfault in test/format log truncate WT-2568 Java PackTest.java compilation error WT-2569 Win_handle_read should always call GetLastError on error WT-2570 Minor lint cleanups. WT-2571 Join code cleanup WT-2572 Don't select an in-memory format run if incompatible options configured WT-2573 Free of stack-allocated WT_REF WT-2574 Format doesn't free all allocated configure memory WT-2576 Variable-length column-store out-of-order return WT-2577 Core dump discarding non-existent addresses WT-2579 In-memory configurations break debugging support WT-2580 Potential SWIG naming conflict in Java WT-2581 Assert multi->disk_image == NULL WT-2582 Cache eviction server error: WT_RESTART WT-2583 Incremental backup can prevent future recovery WT-2584 Don't use periods in error messages WT-2586 Remove ex_config.c until config cursors are supported WT-2589 Check stats using WT_STAT_SET and 'clear' usage WT-2592 Joins using non-recno key types not working WT-2593 Disk full with pre-allocated log files WT-2595 Fix compiler warning in packing tests WT-2597 JSON dump needs LSM tests WT-2598 In-memory FS needs fast lookup on file names WT-2599 Split out the checksum code from the support directory WT-2600 Clean up test program #includes WT-2602 LSM stress hangs with very large uncompressed pages WT-2605 C tests focused on different schema types needed for join and other APIs WT-2609 Incorrect "skips API_END call" error. WT-2610 Investigate eviction hazard pointer check WT-2611 wtperf and/or WT_CONFIG_PARSER do not allow escaped double quotes WT-2612 The dist/s_prototypes script is creating a debugging file xxx. WT-2613 Windows build failing with a C4100 error WT-2615 Enabling checkpoints in test/format leads to reduced concurrency WT-2616 In-memory deadlock getting size WT-2617 Bug in pluggable file system example WT-2621 WiredTiger fails to compile on MSVC 2013 WT-2622 Unit test failed in test_cursor_random.test_cursor_random.test_cursor_random_multiple_page_records WT-2624 snprintf unsupported on MSVC 2013 WT-2626 snprintf errors with macro redefinition on MSVC2015 WT-2627 Coverity complaints WT-2628 Reconciliation can return without unlocking the page lock WT-2629 Introduction of ppc64le crc32c assembly file has made the stack executable WT-2630 Rename WT_FSTREAM methods to avoid using C99 reserved names WT-2632 Test format failures due to "checkpoints cannot be dropped when in-use" WT-2637 The file-extension documentation doesn't cover not-supported cases WT-2644 'wt load -r' (rename) fails with LSM WT-2646 Split the lock_wait flag into two, adding a checkpoint_wait flag WT-2651 Coverity 1355591 resource leak WT-2652 Logging code improvements WT-2653 The custom file-system example should show device configuration WT-2656 Builds failing on GCC 4.7 builder WT-2658 Only include PPC-specific files in PPC builds WT-2659 csuite tests, assorted lint and cleanup. WT-2660 Hang between eviction and connection close WT-2661 Coverity failures: 1356050-1356053 WT-2662 For internal spell checking, strip out double quote literals, they confuse aspell WT-2664 Change eviction so any eviction thread can find candidates WT-2667 Enhance WiredTiger Evergreen testing WT-2668 Create join statistics that are useful and are easy to understand WT-2671 Dump more information about the file layout in verify debug mode WT-2672 Handle system calls that don't set errno WT-2673 Stop automatically increasing memory page max WT-2674 Simplify metadata file check WT-2676 Don't use key size in column store in-memory splits. WT-2677 Fix JSON output so only printable ASCII is produced (seen on Solaris) WT-2682 Add option to configure WiredTiger with strict compiler flags WT-2683 WiredTiger no longer needs to return non-zero disk sizes WT-2685 Hazard pointer failure from clear walk WT-2686 Logging subsystem core dump WT-2687 Test suite should verify the exit status of the wt utility WT-2689 Use after free in WT_SESSION::open_cursor WT-2691 Use wrappers for ctype functions to avoid sign extension errors WT-2692 Fix race in file system example WT-2696 Race condition on unclean shutdown may miss log records with large updates WT-2698 Test/recovery hung WT-2702 Under high thread load, WiredTiger exceeds cache size WT-2704 Test/format hung on bengal WT-2706 Race condition on log file switch can cause missing log records WT-2707 dist/s_label enhancements, and error jump cleanups WT-2709 Connection reconfigure segfault in __wt_conn_cache_pool_destroy WT-2710 WT_FILE_HANDLE_INMEM no longer needs an off field WT-2712 Coverity 1356928 and 1356929: ASSERT_SIDE_EFFECT WT-2713 Document WT_PANIC so pluggable filesystems can panic. WT-2714 Lint WT-2715 random-abort test may write partial record at the end WT-2720 Pull request tester not running Python suite WT-2722 s_label or s_label_loop false positive WT-2724 Eviction workers created on open exit immediately WT-2763 Unit test test_intpack failing on OSX
Diffstat (limited to 'src/third_party/wiredtiger/test/suite/test_join01.py')
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join01.py409
1 files changed, 152 insertions, 257 deletions
diff --git a/src/third_party/wiredtiger/test/suite/test_join01.py b/src/third_party/wiredtiger/test/suite/test_join01.py
index 4aa2bc6e269..f8d96a2718a 100644
--- a/src/third_party/wiredtiger/test/suite/test_join01.py
+++ b/src/third_party/wiredtiger/test/suite/test_join01.py
@@ -35,10 +35,44 @@ from wtscenario import check_scenarios, multiply_scenarios, number_scenarios
class test_join01(wttest.WiredTigerTestCase):
nentries = 100
- scenarios = [
+ type_scen = [
('table', dict(ref='table')),
('index', dict(ref='index'))
]
+ bloom0_scen = [
+ ('bloom0=0', dict(joincfg0='')),
+ ('bloom0=1000', dict(joincfg0=',strategy=bloom,count=1000')),
+ ('bloom0=10000', dict(joincfg0=',strategy=bloom,count=10000')),
+ ]
+ bloom1_scen = [
+ ('bloom1=0', dict(joincfg1='')),
+ ('bloom1=1000', dict(joincfg1=',strategy=bloom,count=1000')),
+ ('bloom1=10000', dict(joincfg1=',strategy=bloom,count=10000')),
+ ]
+ projection_scen = [
+ ('no-projection', dict(do_proj=False)),
+ ('projection', dict(do_proj=True))
+ ]
+ nested_scen = [
+ ('simple', dict(do_nested=False)),
+ ('nested', dict(do_nested=True))
+ ]
+ stats_scen = [
+ ('no-stats', dict(do_stats=False)),
+ ('stats', dict(do_stats=True))
+ ]
+ order_scen = [
+ ('order=0', dict(join_order=0)),
+ ('order=1', dict(join_order=1)),
+ ('order=2', dict(join_order=2)),
+ ('order=3', dict(join_order=3)),
+ ]
+ scenarios = number_scenarios(multiply_scenarios('.', type_scen,
+ bloom0_scen, bloom1_scen,
+ projection_scen,
+ nested_scen, stats_scen,
+ order_scen))
+
# We need statistics for these tests.
conn_config = 'statistics=(all)'
@@ -52,9 +86,29 @@ class test_join01(wttest.WiredTigerTestCase):
return [s, rs, sort3]
# Common function for testing iteration of join cursors
- def iter_common(self, jc, do_proj):
+ def iter_common(self, jc, do_proj, do_nested, join_order):
# See comments in join_common()
- expect = [73, 82, 62, 83, 92]
+ # The order that the results are seen depends on
+ # the ordering of the joins. Specifically, the first
+ # join drives the order that results are seen.
+ if do_nested:
+ if join_order == 0:
+ expect = [73, 82, 83, 92]
+ elif join_order == 1:
+ expect = [73, 82, 83, 92]
+ elif join_order == 2:
+ expect = [82, 92, 73, 83]
+ elif join_order == 3:
+ expect = [92, 73, 82, 83]
+ else:
+ if join_order == 0:
+ expect = [73, 82, 62, 83, 92]
+ elif join_order == 1:
+ expect = [62, 73, 82, 83, 92]
+ elif join_order == 2:
+ expect = [62, 82, 92, 73, 83]
+ elif join_order == 3:
+ expect = [73, 82, 62, 83, 92]
while jc.next() == 0:
[k] = jc.get_keys()
i = k - 1
@@ -64,7 +118,9 @@ class test_join01(wttest.WiredTigerTestCase):
[v0,v1,v2] = jc.get_values()
self.assertEquals(self.gen_values(i), [v0,v1,v2])
if len(expect) == 0 or i != expect[0]:
- self.tty(' result ' + str(i) + ' is not in: ' + str(expect))
+ self.tty('ERROR: ' + str(i) + ' is not next in: ' +
+ str(expect))
+ self.tty('JOIN ORDER=' + str(join_order) + ', NESTED=' + str(do_nested))
self.assertTrue(i == expect[0])
expect.remove(i)
self.assertEquals(0, len(expect))
@@ -81,6 +137,8 @@ class test_join01(wttest.WiredTigerTestCase):
'join: index:join01:index2: ' + statdesc ]
if self.ref == 'index':
expectstats.append('join: index:join01:index0: ' + statdesc)
+ elif self.do_proj:
+ expectstats.append('join: table:join01(v2,v1,v0): ' + statdesc)
else:
expectstats.append('join: table:join01: ' + statdesc)
self.check_stats(statcur, expectstats)
@@ -118,11 +176,46 @@ class test_join01(wttest.WiredTigerTestCase):
self.assertTrue(len(expectstats) == 0,
'missing expected values in stats: ' + str(expectstats))
+ def session_record_join(self, jc, refc, config, order, joins):
+ joins.append([order, [jc, refc, config]])
+
+ def session_play_one_join(self, firsturi, jc, refc, config):
+ if refc.uri == firsturi and config != None:
+ config = config.replace('strategy=bloom','')
+ #self.tty('->join(jc, uri="' + refc.uri +
+ # '", config="' + str(config) + '"')
+ self.session.join(jc, refc, config)
+
+ def session_play_joins(self, joins, join_order):
+ #self.tty('->')
+ firsturi = None
+ for [i, joinargs] in joins:
+ if i >= join_order:
+ if firsturi == None:
+ firsturi = joinargs[1].uri
+ self.session_play_one_join(firsturi, *joinargs)
+ for [i, joinargs] in joins:
+ if i < join_order:
+ if firsturi == None:
+ firsturi = joinargs[1].uri
+ self.session_play_one_join(firsturi, *joinargs)
+
# Common function for testing the most basic functionality
# of joins
- def join_common(self, joincfg0, joincfg1, do_proj, do_stats):
+ def test_join(self):
+ joincfg0 = self.joincfg0
+ joincfg1 = self.joincfg1
+ do_proj = self.do_proj
+ do_nested = self.do_nested
+ do_stats = self.do_stats
+ join_order = self.join_order
#self.tty('join_common(' + joincfg0 + ',' + joincfg1 + ',' +
- # str(do_proj) + ')')
+ # str(do_proj) + ',' + str(do_nested) + ',' +
+ # str(do_stats) + ',' + str(join_order) + ')')
+
+ closeme = []
+ joins = [] # cursors to be joined
+
self.session.create('table:join01', 'key_format=r' +
',value_format=SSi,columns=(k,v0,v1,v2)')
self.session.create('index:join01:index0','columns=(v0)')
@@ -143,7 +236,7 @@ class test_join01(wttest.WiredTigerTestCase):
# We join on index2 first, not using bloom indices.
# This defines the order that items are returned.
- # index2 is sorts multiples of 3 first (see gen_values())
+ # index2 sorts multiples of 3 first (see gen_values())
# and by using 'gt' and key 99, we'll skip multiples of 3,
# and examine primary keys 2,5,8,...,95,98,1,4,7,...,94,97.
jc = self.session.open_cursor('join:table:join01' + proj_suffix,
@@ -152,7 +245,7 @@ class test_join01(wttest.WiredTigerTestCase):
c2 = self.session.open_cursor('index:join01:index2(v1)', None, None)
c2.set_key(99) # skips all entries w/ primary key divisible by three
self.assertEquals(0, c2.search())
- self.session.join(jc, c2, 'compare=gt')
+ self.session_record_join(jc, c2, 'compare=gt', 0, joins)
# Then select all the numbers 0-99 whose string representation
# sort >= '60'.
@@ -163,285 +256,87 @@ class test_join01(wttest.WiredTigerTestCase):
c0 = self.session.open_cursor('table:join01', None, None)
c0.set_key(60)
self.assertEquals(0, c0.search())
- self.session.join(jc, c0, 'compare=ge' + joincfg0)
+ self.session_record_join(jc, c0, 'compare=ge' + joincfg0, 1, joins)
# Then select all numbers whose reverse string representation
# is in '20' < x < '40'.
c1a = self.session.open_cursor('index:join01:index1(v1)', None, None)
c1a.set_key('21')
self.assertEquals(0, c1a.search())
- self.session.join(jc, c1a, 'compare=gt' + joincfg1)
+ self.session_record_join(jc, c1a, 'compare=gt' + joincfg1, 2, joins)
c1b = self.session.open_cursor('index:join01:index1(v1)', None, None)
c1b.set_key('41')
self.assertEquals(0, c1b.search())
- self.session.join(jc, c1b, 'compare=lt' + joincfg1)
+ self.session_record_join(jc, c1b, 'compare=lt' + joincfg1, 2, joins)
# Numbers that satisfy these 3 conditions (with ordering implied by c2):
# [73, 82, 62, 83, 92].
#
# After iterating, we should be able to reset and iterate again.
+ if do_nested:
+ # To test nesting, we create two new levels of conditions:
+ #
+ # x == 72 or x == 73 or x == 82 or x == 83 or
+ # (x >= 90 and x <= 99)
+ #
+ # that will get AND-ed into our existing join. The expected
+ # result is [73, 82, 83, 92].
+ #
+ # We don't specify the projection here, it should be picked up
+ # from the 'enclosing' join.
+ nest1 = self.session.open_cursor('join:table:join01', None, None)
+ nest2 = self.session.open_cursor('join:table:join01', None, None)
+
+ nc = self.session.open_cursor('index:join01:index0', None, None)
+ nc.set_key('90')
+ self.assertEquals(0, nc.search())
+ self.session.join(nest2, nc, 'compare=ge') # joincfg left out
+ closeme.append(nc)
+
+ nc = self.session.open_cursor('index:join01:index0', None, None)
+ nc.set_key('99')
+ self.assertEquals(0, nc.search())
+ self.session.join(nest2, nc, 'compare=le')
+ closeme.append(nc)
+
+ self.session.join(nest1, nest2, "operation=or")
+
+ for val in [ '72', '73', '82', '83' ]:
+ nc = self.session.open_cursor('index:join01:index0', None, None)
+ nc.set_key(val)
+ self.assertEquals(0, nc.search())
+ self.session.join(nest1, nc, 'compare=eq,operation=or' +
+ joincfg0)
+ closeme.append(nc)
+ self.session_record_join(jc, nest1, None, 3, joins)
+
+ self.session_play_joins(joins, join_order)
+ self.iter_common(jc, do_proj, do_nested, join_order)
if do_stats:
self.stats(jc, 0)
- self.iter_common(jc, do_proj)
+ jc.reset()
+ self.iter_common(jc, do_proj, do_nested, join_order)
if do_stats:
self.stats(jc, 1)
jc.reset()
- self.iter_common(jc, do_proj)
+ self.iter_common(jc, do_proj, do_nested, join_order)
if do_stats:
self.stats(jc, 2)
jc.reset()
- self.iter_common(jc, do_proj)
+ self.iter_common(jc, do_proj, do_nested, join_order)
jc.close()
c2.close()
c1a.close()
c1b.close()
c0.close()
+ if do_nested:
+ nest1.close()
+ nest2.close()
+ for c in closeme:
+ c.close()
self.session.drop('table:join01')
- # Test joins with basic functionality
- def test_join(self):
- bloomcfg1000 = ',strategy=bloom,count=1000'
- bloomcfg10000 = ',strategy=bloom,count=10000'
- for cfga in [ '', bloomcfg1000, bloomcfg10000 ]:
- for cfgb in [ '', bloomcfg1000, bloomcfg10000 ]:
- for do_proj in [ False, True ]:
- #self.tty('cfga=' + cfga +
- # ', cfgb=' + cfgb +
- # ', doproj=' + str(do_proj))
- self.join_common(cfga, cfgb, do_proj, False)
-
- def test_join_errors(self):
- self.session.create('table:join01', 'key_format=r,value_format=SS'
- ',columns=(k,v0,v1)')
- self.session.create('table:join01B', 'key_format=r,value_format=SS'
- ',columns=(k,v0,v1)')
- self.session.create('index:join01:index0','columns=(v0)')
- self.session.create('index:join01:index1','columns=(v1)')
- self.session.create('index:join01B:index0','columns=(v0)')
- jc = self.session.open_cursor('join:table:join01', None, None)
- tc = self.session.open_cursor('table:join01', None, None)
- fc = self.session.open_cursor('file:join01.wt', None, None)
- ic0 = self.session.open_cursor('index:join01:index0', None, None)
- ic0again = self.session.open_cursor('index:join01:index0', None, None)
- ic1 = self.session.open_cursor('index:join01:index1', None, None)
- icB = self.session.open_cursor('index:join01B:index0', None, None)
- tcB = self.session.open_cursor('table:join01B', None, None)
-
- tc.set_key(1)
- tc.set_value('val1', 'val1')
- tc.insert()
- tcB.set_key(1)
- tcB.set_value('val1', 'val1')
- tcB.insert()
- fc.next()
-
- # Joining using a non join-cursor
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(tc, ic0, 'compare=ge'),
- '/not a join cursor/')
- # Joining a table cursor, not index
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, fc, 'compare=ge'),
- '/not an index or table cursor/')
- # Joining a non positioned cursor
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0, 'compare=ge'),
- '/requires reference cursor be positioned/')
- ic0.set_key('val1')
- # Joining a non positioned cursor (no search or next has been done)
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0, 'compare=ge'),
- '/requires reference cursor be positioned/')
- ic0.set_key('valXX')
- self.assertEqual(ic0.search(), wiredtiger.WT_NOTFOUND)
- # Joining a non positioned cursor after failed search
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0, 'compare=ge'),
- '/requires reference cursor be positioned/')
-
- # position the cursors now
- ic0.set_key('val1')
- ic0.search()
- ic0again.next()
- icB.next()
-
- # Joining non matching index
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, icB, 'compare=ge'),
- '/table for join cursor does not match/')
-
- # The cursor must be positioned
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic1, 'compare=ge'),
- '/requires reference cursor be positioned/')
- ic1.next()
-
- # The first cursor joined cannot be bloom
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic1,
- 'compare=ge,strategy=bloom,count=1000'),
- '/first joined cursor cannot specify strategy=bloom/')
-
- # This succeeds.
- self.session.join(jc, ic1, 'compare=ge'),
-
- # With bloom filters, a count is required
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0, 'compare=ge,strategy=bloom'),
- '/count must be nonzero/')
-
- # This succeeds.
- self.session.join(jc, ic0, 'compare=ge,strategy=bloom,count=1000'),
-
- bloom_config = ',strategy=bloom,count=1000'
- # Cannot use the same index cursor
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0,
- 'compare=le' + bloom_config),
- '/index cursor already used in a join/')
-
- # When joining with the same index, need compatible compares
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0again, 'compare=ge' + bloom_config),
- '/join has overlapping ranges/')
-
- # Another incompatible compare
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0again, 'compare=gt' + bloom_config),
- '/join has overlapping ranges/')
-
- # Compare is compatible, but bloom args need to match
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0again, 'compare=le'),
- '/join has incompatible strategy/')
-
- # Counts need to match for bloom filters
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: self.session.join(jc, ic0again, 'compare=le,strategy=bloom,'
- 'count=100'), '/count.* does not match previous count/')
-
- # This succeeds
- self.session.join(jc, ic0again, 'compare=le,strategy=bloom,count=1000')
-
- # Need to do initial next() before getting key/values
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: jc.get_keys(),
- '/join cursor must be advanced with next/')
-
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: jc.get_values(),
- '/join cursor must be advanced with next/')
-
- # Operations on the joined cursor are frozen until the join is closed.
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: ic0.next(),
- '/index cursor is being used in a join/')
-
- # Operations on the joined cursor are frozen until the join is closed.
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: ic0.prev(),
- '/index cursor is being used in a join/')
-
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: ic0.reset(),
- '/index cursor is being used in a join/')
-
- # Only a small number of operations allowed on a join cursor
- msg = "/Unsupported cursor/"
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: jc.search(), msg)
-
- self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
- lambda: jc.prev(), msg)
-
- self.assertEquals(jc.next(), 0)
- self.assertEquals(jc.next(), wiredtiger.WT_NOTFOUND)
-
- # Only after the join cursor is closed can we use the index cursor
- # normally
- jc.close()
- self.assertEquals(ic0.next(), wiredtiger.WT_NOTFOUND)
- self.assertEquals(ic0.prev(), 0)
-
- # common code for making sure that cursors can be
- # implicitly closed, no matter the order they are created
- def cursor_close_common(self, joinfirst):
- self.session.create('table:join01', 'key_format=r' +
- ',value_format=SS,columns=(k,v0,v1)')
- self.session.create('index:join01:index0','columns=(v0)')
- self.session.create('index:join01:index1','columns=(v1)')
- c = self.session.open_cursor('table:join01', None, None)
- for i in range(0, self.nentries):
- c.set_key(*self.gen_key(i))
- c.set_value(*self.gen_values(i))
- c.insert()
- c.close()
-
- if joinfirst:
- jc = self.session.open_cursor('join:table:join01', None, None)
- c0 = self.session.open_cursor('index:join01:index0', None, None)
- c1 = self.session.open_cursor('index:join01:index1', None, None)
- c0.next() # index cursors must be positioned
- c1.next()
- if not joinfirst:
- jc = self.session.open_cursor('join:table:join01', None, None)
- self.session.join(jc, c0, 'compare=ge')
- self.session.join(jc, c1, 'compare=ge')
- self.session.close()
- self.session = None
-
- def test_cursor_close1(self):
- self.cursor_close_common(True)
-
- def test_cursor_close2(self):
- self.cursor_close_common(False)
-
- # test statistics using the framework set up for this test
- def test_stats(self):
- bloomcfg1000 = ',strategy=bloom,count=1000'
- bloomcfg10 = ',strategy=bloom,count=10'
- self.join_common(bloomcfg1000, bloomcfg1000, False, True)
-
- # Intentially run with an underconfigured Bloom filter,
- # statistics should pick up some false positives.
- self.join_common(bloomcfg10, bloomcfg10, False, True)
-
- # test statistics with a simple one index join cursor
- def test_simple_stats(self):
- self.session.create("table:join01b",
- "key_format=i,value_format=i,columns=(k,v)")
- self.session.create("index:join01b:index", "columns=(v)")
-
- cursor = self.session.open_cursor("table:join01b", None, None)
- cursor[1] = 11
- cursor[2] = 12
- cursor[3] = 13
- cursor.close()
-
- cursor = self.session.open_cursor("index:join01b:index", None, None)
- cursor.set_key(11)
- cursor.search()
-
- jcursor = self.session.open_cursor("join:table:join01b", None, None)
- self.session.join(jcursor, cursor, "compare=gt")
-
- while jcursor.next() == 0:
- [k] = jcursor.get_keys()
- [v] = jcursor.get_values()
-
- statcur = self.session.open_cursor("statistics:join", jcursor, None)
- found = False
- while statcur.next() == 0:
- [desc, pvalue, value] = statcur.get_values()
- #self.tty(str(desc) + "=" + str(pvalue))
- found = True
- self.assertEquals(found, True)
-
- jcursor.close()
- cursor.close()
-
-
if __name__ == '__main__':
wttest.run()