alternator: fix query with both projection and filtering

We had a bug when a Query/Scan had both projection (ProjectionExpression
or AttributesToGet) and filtering (FilterExpression or Query/ScanFilter).
The problem was that projection left only the requested attributes, and
the filter might have needed - and not got - additional attributes.

The solution in this patch is to add the generated JSON item also
the extra attributes needed by filtering (if any), run the filter on
that, and only at the end remove the extra filtering attributes from
the item to be returned.

The two tests

 test_query_filter.py::test_query_filter_and_attributes_to_get
 test_filter_expression.py::test_filter_expression_and_projection_expression

Which failed before this patch now pass so we drop their "xfail" tag.

Fixes #6951.

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
(cherry picked from commit 282742a469)
This commit is contained in:
Nadav Har'El
2020-10-04 23:16:13 +03:00
committed by Avi Kivity
parent 3b617164dc
commit dd7e3d3eab
5 changed files with 83 additions and 6 deletions

View File

@@ -658,7 +658,6 @@ def test_filter_expression_and_sort_key_condition(test_table_sn_with_data):
# In particular, test that FilterExpression may inspect attributes which will
# not be returned by the query, because of the ProjectionExpression.
# This test reproduces issue #6951.
@pytest.mark.xfail(reason="issue #6951: cannot filter on non-returned attributes")
def test_filter_expression_and_projection_expression(test_table):
p = random_string()
test_table.put_item(Item={'p': p, 'c': 'hi', 'x': 'dog', 'y': 'cat'})

View File

@@ -539,7 +539,6 @@ def test_query_filter_paging(test_table_sn_with_data):
# In particular, test that QueryFilter may inspect attributes which will
# not be returned by the query, because the AttributesToGet.
# This test reproduces issue #6951.
@pytest.mark.xfail(reason="issue #6951: cannot filter on non-returned attributes")
def test_query_filter_and_attributes_to_get(test_table):
p = random_string()
test_table.put_item(Item={'p': p, 'c': 'hi', 'x': 'dog', 'y': 'cat'})