This is an automated email from the ASF dual-hosted git repository. mblow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit dc1b45236dc71024b00b0257d0ffcf3737f135c2 Author: Dmitry Lychagin <[email protected]> AuthorDate: Fri Apr 17 09:02:08 2020 -0700 [NO ISSUE][RT] Support negative positions in path expression - user model changes: no - storage format changes: no - interface changes: no Details: - Support negative array index in path expressions: array[-1] addresses the last element, array[-2] next to last, and so on - Add testcase and update documentation Change-Id: Ib2bdeab42d3bd37c21d860dda583a2762a74e2fb Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/5845 Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: Dmitry Lychagin <[email protected]> Reviewed-by: Ali Alsuliman <[email protected]> --- .../get-item_03/get-item_03.4.query.sqlpp} | 19 +++++++++++-------- .../queries_sqlpp/misc/case_01/case_01.1.query.sqlpp | 2 +- .../queries_sqlpp/misc/case_02/case_02.1.query.sqlpp | 2 +- .../queries_sqlpp/misc/case_03/case_03.1.query.sqlpp | 2 +- .../queries_sqlpp/misc/case_04/case_04.1.query.sqlpp | 2 +- .../queries_sqlpp/misc/case_05/case_05.1.query.sqlpp | 2 +- .../queries_sqlpp/misc/case_06/case_06.1.query.sqlpp | 2 +- .../queries_sqlpp/misc/case_07/case_07.1.query.sqlpp | 2 +- .../numeric/add_double/add_double.1.query.sqlpp | 2 +- .../{get-item_03.1.adm => get-item_03.3.adm} | 0 .../results/list/get-item_03/get-item_03.4.adm | 1 + .../numeric/add_double/add_double.1.ast | 7 +------ .../asterix-doc/src/main/markdown/sqlpp/2_expr.md | 9 +++++++-- .../evaluators/functions/GetItemDescriptor.java | 4 ++++ 14 files changed, 32 insertions(+), 24 deletions(-) diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/get-item_03/get-item_03.4.query.sqlpp similarity index 67% copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/get-item_03/get-item_03.4.query.sqlpp index c2a4cea..ab27331 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/get-item_03/get-item_03.4.query.sqlpp @@ -17,12 +17,15 @@ * under the License. */ -SELECT - CASE t - WHEN 0 THEN 0.0 - WHEN NULL THEN -1 - WHEN MISSING THEN -2 - ELSE 2.0/t - END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +use test; +{ +"ta1": [1, 2, 3][-1], +"ta2": [1, 2, 3][-2], +"ta3": [1, 2, 3][-3], +"ta4": [1, 2, 3][-4] is missing, +"tb1": [1, 2, 3][-((select value id from test where id = 1)[0])], +"tb2": [1, 2, 3][-((select value id from test where id = 1)[0])-1], +"tb3": [1, 2, 3][-((select value id from test where id = 1)[0])-2], +"tb4": [1, 2, 3][-((select value id from test where id = 1)[0])-3] is missing +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp index c2a4cea..7f9647b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp @@ -24,5 +24,5 @@ SELECT WHEN MISSING THEN -2 ELSE 2.0/t END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp index ab19bcb..095eb20 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp @@ -24,6 +24,6 @@ SELECT WHEN t IS MISSING THEN -2 ELSE 2.0/t END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp index 7c3e566..12cd3f6 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp @@ -24,5 +24,5 @@ SELECT WHEN t IS MISSING THEN (SELECT -2 AS r) ELSE (SELECT -3 AS r) END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp index 154e611..e99da85 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp @@ -24,5 +24,5 @@ SELECT WHEN t IS MISSING THEN (SELECT -2) ELSE 2.0/t END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp index 32030a7..5940b19 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp @@ -26,5 +26,5 @@ SELECT WHEN t=2 THEN MISSING ELSE 2.0/t END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp index 5bf2786..8fbaa7a 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp @@ -22,5 +22,5 @@ SELECT WHEN t = 0 THEN MISSING ELSE NULL END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp index 4850047..27180b5 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp @@ -27,4 +27,4 @@ SELECT WHEN t IS UNKNOWN THEN (SELECT -3) // Should never enter this THEN branch. ELSE 2.0/t END -FROM [0, 1, 2, 4, NULL, [0][-1]] t; +FROM [0, 1, 2, 4, NULL, MISSING] t; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/add_double/add_double.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/add_double/add_double.1.query.sqlpp index 366f2b1..a5b1e1b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/add_double/add_double.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/add_double/add_double.1.query.sqlpp @@ -18,4 +18,4 @@ */ -{'result1':(double('-6.5d') + tinyint('+1')),'result2':(double('-6.5d') + smallint('2')),'result3':(double('-6.5d') + integer('+3')),'result4':(double('-6.5d') + bigint('-4')),'result5':(double('-6.5d') + float('-5.5f')),'result6':(double('-6.5d') + double('-6.5d')),'result7':(double('-6.5d') + null), 'result8':double('-6.5d') + [1.0][-1]}; +{'result1':(double('-6.5d') + tinyint('+1')),'result2':(double('-6.5d') + smallint('2')),'result3':(double('-6.5d') + integer('+3')),'result4':(double('-6.5d') + bigint('-4')),'result5':(double('-6.5d') + float('-5.5f')),'result6':(double('-6.5d') + double('-6.5d')),'result7':(double('-6.5d') + null), 'result8':double('-6.5d') + MISSING}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.3.adm similarity index 100% rename from asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.1.adm rename to asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.3.adm diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.4.adm new file mode 100644 index 0000000..27ec71f --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/get-item_03/get-item_03.4.adm @@ -0,0 +1 @@ +{ "ta1": 3, "ta2": 2, "ta3": 1, "ta4": true, "tb1": 3, "tb2": 2, "tb3": 1, "tb4": true } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/add_double/add_double.1.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/add_double/add_double.1.ast index 4550cfe..7e1443c 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/add_double/add_double.1.ast +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/add_double/add_double.1.ast @@ -97,12 +97,7 @@ RecordConstructor [ LiteralExpr [STRING] [-6.5d] ] + - IndexAccessor [ - OrderedListConstructor [ - LiteralExpr [DOUBLE] [1.0] - ] - Index: - LiteralExpr [LONG] [1] - ] + LiteralExpr [MISSING] ] ) ] diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md index 37e7f79..2e0b526 100644 --- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md +++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md @@ -218,8 +218,9 @@ For arrays, path access is based on (zero-based) array-style indexing. Array ind single element from an array, or a whole subset of an array. Accessing a single element is achieved by providing a single index argument (zero-based element position), while obtaining a subset of an array is achieved by providing the `start` and `end` (zero-based) index positions; the returned subset is from position `start` to position -`end - 1`; the `end` position argument is optional. Multisets have similar behavior to arrays, except for retrieving -arbitrary items as the order of items is not fixed in multisets. +`end - 1`; the `end` position argument is optional. If a position argument is negative then the element position is +counted from the end of the array (`-1` addresses the last element, `-2` next to last, and so on). Multisets have +similar behavior to arrays, except for retrieving arbitrary items as the order of items is not fixed in multisets. Attempts to access non-existent fields or out-of-bound array elements produce the special value `MISSING`. Type errors will be raised for inappropriate use of a path expression, such as applying a field accessor to a numeric value. @@ -232,12 +233,16 @@ and also a composition thereof. ({"name": "MyABCs", "array": [ "a", "b", "c"]}).array (["a", "b", "c"])[2] + + (["a", "b", "c"])[-1] ({"name": "MyABCs", "array": [ "a", "b", "c"]}).array[2] (["a", "b", "c"])[0:2] (["a", "b", "c"])[0:] + + (["a", "b", "c"])[-2:-1] ## <a id="Primary_expressions">Primary Expressions</a> diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/GetItemDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/GetItemDescriptor.java index f7bddf1..fb71eae 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/GetItemDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/GetItemDescriptor.java @@ -116,6 +116,10 @@ public class GetItemDescriptor extends AbstractScalarFunctionDynamicDescriptor { int itemIndex = ATypeHierarchy.getIntegerValue(BuiltinFunctions.GET_ITEM.getName(), 0, indexBytes, indexOffset); + if (itemIndex < 0) { + itemIndex = itemCount + itemIndex; + } + if (itemIndex < 0 || itemIndex >= itemCount) { // Out-of-bound index access should return MISSING. result.set(missingBytes, 0, 1);
