Skip to content

Commit 9168603

Browse files
authored
Merge pull request #128 from dongxinEric/bugfix/fix-discrepancies-between-MM-and-DocLayer
Fixed several bugs in the MM code around index and unique index.
2 parents 33211b5 + 9b001f1 commit 9168603

2 files changed

Lines changed: 60 additions & 20 deletions

File tree

test/correctness/document-correctness.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -333,23 +333,31 @@ def _run_operation_(op1, op2):
333333
transactional_shim.remove(collection2)
334334

335335
indexes = []
336+
num_of_indexes = 5;
336337
indexes_first = gen.global_prng.choice([True, False])
337338
if indexes_enabled:
338-
for i in range(0, 5):
339+
for i in range(0, num_of_indexes):
339340
index_obj = gen.random_index_spec()
340341
indexes.append(index_obj)
341342

343+
# 0.5% likelyhood to allow using unique index in this iteration, assuming a uniform distribution
344+
useUnique = (gen.global_prng.randint(1,200) == 1)
345+
# only allow one out of $num_of_indexes to be unique.
346+
allowed_ii = gen.global_prng.randint(1,num_of_indexes)
342347
if indexes_first:
348+
ii = 1
343349
for i in indexes:
344-
# When we do enable make sure we don't enable for 50% cases. That way unique indexes will cloud everything else. Make it something like 5-10%.
345-
# uniqueIndex = gen.global_prng.choice([True, False])
346-
uniqueIndex = False
350+
if ii == allowed_ii:
351+
uniqueIndex = useUnique
352+
else:
353+
uniqueIndex = False
347354
okay = _run_operation_(
348355
(transactional_shim.ensure_index, (collection1, i), {"unique":uniqueIndex}),
349356
(transactional_shim.ensure_index, (collection2, i), {"unique":uniqueIndex})
350357
)
351358
if not okay:
352359
return (okay, fname, None)
360+
ii += 1
353361
docs = []
354362
for i in range(0, num_doc):
355363
doc = gen.random_document(True)
@@ -364,17 +372,20 @@ def _run_operation_(op1, op2):
364372
return (okay, fname, None)
365373

366374
if not indexes_first:
375+
ii = 1
367376
for i in indexes:
368-
# When we do enable make sure we don't enable for 50% cases. That way unique indexes will cloud everything else. Make it something like 5-10%.
369-
# uniqueIndex = gen.global_prng.choice([True, False])
370-
uniqueIndex = False
377+
if ii == allowed_ii:
378+
uniqueIndex = useUnique
379+
else:
380+
uniqueIndex = False
371381
okay = _run_operation_(
372382
(transactional_shim.ensure_index, (collection1, i), {"unique":uniqueIndex}),
373383
(transactional_shim.ensure_index, (collection2, i), {"unique":uniqueIndex})
374384
)
375385
if not okay:
376386
print "Failed when adding index after insert"
377387
return (okay, fname, None)
388+
ii += 1
378389

379390
okay = check_query(dict(), collection1, collection2)
380391
if not okay:

test/correctness/mongo_model.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -546,16 +546,23 @@ def _create_index(self, keys, kwargs):
546546
def _get_index_name(keys):
547547
return "_".join(["%s_%s" % item for item in keys])
548548
kwargs.setdefault("name", _get_index_name(keys))
549+
seen = set()
550+
deduplicatedKeys = []
551+
for key in keys:
552+
if key[0] not in seen:
553+
deduplicatedKeys.append(key)
554+
seen.add(key[0])
549555
for i in self.indexes:
550-
if i.keys == keys:
556+
if i.keys == deduplicatedKeys:
557+
# There was an index that indexes on the same field(s), abort here.
551558
return None
552559
if i.name == kwargs["name"]:
553560
raise MongoModelException("There is an index with this name and a different key spec", code=29993)
554561

555562
if "unique" in kwargs.keys() and kwargs["unique"]:
556-
newIndex = MongoUniqueIndex(keys, kwargs)
563+
newIndex = MongoUniqueIndex(deduplicatedKeys, kwargs)
557564
else:
558-
newIndex = MongoIndex(keys, kwargs)
565+
newIndex = MongoIndex(deduplicatedKeys, kwargs)
559566

560567
self.indexes.append(newIndex) # insert first, since an index can be added but in error state if its constraints are violated.
561568
newIndex.build(self.data.values())
@@ -1095,10 +1102,29 @@ class MongoIndex(object):
10951102
def __init__(self, indexKeys, kwargs):
10961103
self.name = kwargs["name"]
10971104
if len(indexKeys) == 1:
1105+
if indexKeys[0][1] == "text" :
1106+
raise MongoModelException("Document Layer does not support this index type, yet.", code=29969)
1107+
elif (type(indexKeys[0][1]) is int and abs(indexKeys[0][1]) != 1) or (type(indexKeys[0][1]) is not int):
1108+
raise MongoModelException("Index must be 1 for ascending or -1 for descending", code=29991)
1109+
else :
1110+
first = True
1111+
ascending = True
1112+
for key in indexKeys:
1113+
if key[1] == "text":
1114+
raise MongoModelException("Document Layer does not support this index type, yet.", code=29969)
1115+
elif (type(key[1]) is int and abs(key[1]) != 1) or (type(key[1]) is not int):
1116+
raise MongoModelException("Index must be 1 for ascending or -1 for descending", code=29991)
1117+
if first:
1118+
first = False
1119+
ascending = (key[1] == 1)
1120+
else:
1121+
if ascending != (key[1] == 1):
1122+
raise MongoModelException("Mixed order compound indexes are not supported", code=29990)
1123+
self.keys = indexKeys
1124+
if len(self.keys) == 1:
10981125
self.isSimple = True
10991126
else:
11001127
self.isSimple = False
1101-
self.keys = indexKeys
11021128
# self check
11031129
self.validate_self()
11041130

@@ -1119,7 +1145,7 @@ def validate_and_build_entry(self, documents):
11191145
nValues = 1
11201146
for key in self.keys:
11211147
values = expand(
1122-
field=key,
1148+
field=key[0],
11231149
document=document,
11241150
check_last_array=True,
11251151
expand_array=True,
@@ -1144,20 +1170,23 @@ def build(self, documents):
11441170
def validate_and_build_entry(self, documents):
11451171
seen = set()
11461172
for document in documents:
1173+
entry = ""
11471174
for key in self.keys:
1148-
entry = ""
11491175
_values = expand(
1150-
field=key,
1176+
field=key[0],
11511177
document=document,
11521178
check_last_array=True,
11531179
expand_array=True,
11541180
add_last_array=False,
11551181
check_none_at_all=True,
11561182
check_none_next=True,
11571183
debug=False)
1158-
1159-
entry = entry + reduce((lambda acc, x: acc + x), map((lambda x: str(x)), _values), "None")
1160-
if entry in seen:
1161-
raise MongoModelException("Duplicated value not allowed by unique index", code=11000)
1162-
else:
1163-
seen.add(entry)
1184+
entry = entry + reduce((lambda acc, x: acc + x), map((lambda x: str(x)), _values), "")
1185+
if entry in seen:
1186+
# print "[{}] in {} ? {}".format(entry, seen, entry in seen)
1187+
# print "Violating keys " + str(key)
1188+
# print "Duplicated value: " + entry
1189+
raise MongoModelException("Duplicated value not allowed by unique index", code=11000)
1190+
else:
1191+
# print "Inserting {} for key {}".format(entry, key)
1192+
seen.add(entry)

0 commit comments

Comments
 (0)