Incorrect behavior of join() on iterators was fixed
Due to the incorrect condition it code that limits iterators even collections with known limit (lists etc.) were converted to limiting iterators when there was no upper length limit. As a result when join() method was called without iterator limitation being configured (for example through yaql.eval) it received its collection arguments as iterators. Because iterators cannot be reset and re-read again iterator for the inner iterator became exhausted after the first item of the outer collection. join() method was fixed to work correctly to memorize inner iterator so that it could be re-read Change-Id: I287d0d86b5461490ff32731c11a726174939753d
This commit is contained in:
@@ -181,20 +181,19 @@ def get_memory_quota(engine):
|
||||
|
||||
def limit_iterable(iterable, limit_or_engine):
|
||||
if isinstance(limit_or_engine, int):
|
||||
count = limit_or_engine
|
||||
max_count = limit_or_engine
|
||||
else:
|
||||
count = get_max_collection_size(limit_or_engine)
|
||||
max_count = get_max_collection_size(limit_or_engine)
|
||||
|
||||
if count >= 0 and isinstance(iterable,
|
||||
(SequenceType, MappingType, SetType)):
|
||||
if len(iterable) > count:
|
||||
raise exceptions.CollectionTooLargeException(count)
|
||||
if isinstance(iterable, (SequenceType, MappingType, SetType)):
|
||||
if 0 <= max_count < len(iterable):
|
||||
raise exceptions.CollectionTooLargeException(max_count)
|
||||
return iterable
|
||||
|
||||
def limiting_iterator():
|
||||
for i, t in enumerate(iterable):
|
||||
if 0 <= count <= i:
|
||||
raise exceptions.CollectionTooLargeException(count)
|
||||
if 0 <= max_count <= i:
|
||||
raise exceptions.CollectionTooLargeException(max_count)
|
||||
yield t
|
||||
return limiting_iterator()
|
||||
|
||||
|
||||
@@ -371,7 +371,8 @@ def zip_longest(*collections, **kwargs):
|
||||
@specs.parameter('collection2', yaqltypes.Iterable())
|
||||
@specs.parameter('predicate', yaqltypes.Lambda())
|
||||
@specs.parameter('selector', yaqltypes.Lambda())
|
||||
def join(collection1, collection2, predicate, selector):
|
||||
def join(engine, collection1, collection2, predicate, selector):
|
||||
collection2 = utils.memorize(collection2, engine)
|
||||
for self_item in collection1:
|
||||
for other_item in collection2:
|
||||
if predicate(self_item, other_item):
|
||||
|
||||
Reference in New Issue
Block a user