Skip to content

Commit 2709f6f

Browse files
author
Xin Dong
committed
Fixed several bugs in the MM code around index and unique index.
That including a bug in unique index where it cannot correctly detect duplicated values, a bug in index model where it failed to sanitize 'key' field to recognize the index build request that should be ignored and so on. Also enabled unique index generating in correctness to genrate a small portion (5% assuming a uniform distibution of the random int generator) of the indexes as unique indexes.
1 parent 9efd4d5 commit 2709f6f

2 files changed

Lines changed: 46 additions & 19 deletions

File tree

test/correctness/document-correctness.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,8 @@ def _run_operation_(op1, op2):
341341

342342
if indexes_first:
343343
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
344+
# 5% likelyhood to be unique, assuming a uniform distribution
345+
uniqueIndex = (gen.global_prng.randint(1,20) == 1)
347346
okay = _run_operation_(
348347
(transactional_shim.ensure_index, (collection1, i), {"unique":uniqueIndex}),
349348
(transactional_shim.ensure_index, (collection2, i), {"unique":uniqueIndex})
@@ -365,9 +364,8 @@ def _run_operation_(op1, op2):
365364

366365
if not indexes_first:
367366
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
367+
# 5% likelyhood to be unique, assuming a uniform distribution
368+
uniqueIndex = (gen.global_prng.randint(1,20) == 1)
371369
okay = _run_operation_(
372370
(transactional_shim.ensure_index, (collection1, i), {"unique":uniqueIndex}),
373371
(transactional_shim.ensure_index, (collection2, i), {"unique":uniqueIndex})

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)