From 8f73db1a191bb25cc46a0fac32a0aa27232bd7b1 Mon Sep 17 00:00:00 2001 From: Stan Lagun Date: Wed, 16 Dec 2015 19:29:04 +0300 Subject: [PATCH] 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 --- yaql/language/utils.py | 15 +++++++-------- yaql/standard_library/queries.py | 3 ++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/yaql/language/utils.py b/yaql/language/utils.py index e738659..6732394 100644 --- a/yaql/language/utils.py +++ b/yaql/language/utils.py @@ -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() diff --git a/yaql/standard_library/queries.py b/yaql/standard_library/queries.py index 1c16f80..c140a4a 100644 --- a/yaql/standard_library/queries.py +++ b/yaql/standard_library/queries.py @@ -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):