This is an automated email from the ASF dual-hosted git repository. imaxon pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit 1933dfca4b4292c1994dbe88092470605e0ea488 Author: preetham0202 <[email protected]> AuthorDate: Wed Jan 14 18:14:06 2026 +0530 [ASTERIXDB-3677][COMP] Fix nested star operators failure - user model changes: no - storage format changes: no - interface changes: no Ext-ref: MB-70076 Details: Do not extract record-constructor() functions so that nested star operators don't fail. Change-Id: I557b9992d047c6fc53bddd5b90ff814bb678cedf Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20864 Tested-by: Michael Blow <[email protected]> Reviewed-by: Ali Alsuliman <[email protected]> Reviewed-by: Michael Blow <[email protected]> Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20794 Reviewed-by: Preetham Poluparthi <[email protected]> Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> --- .../translator/LangExpressionToPlanTranslator.java | 3 + .../SqlppExpressionToPlanTranslator.java | 5 +- .../ASTERIXDB-3682-field-access-in-join.plan | 590 ++++++++++----------- .../select-star/nested/nested.1.ddl.sqlpp | 32 ++ .../select-star/nested/nested.2.update.sqlpp | 25 + .../select-star/nested/nested.3.query.sqlpp | 22 + .../results/select-star/nested/nested.3.adm | 2 + .../src/test/resources/runtimets/sqlpp_queries.xml | 5 + .../DoNotExtractExpressionAnnotation.java | 27 + .../rules/ExtractCommonExpressionsRule.java | 11 +- 10 files changed, 424 insertions(+), 298 deletions(-) diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java index b1638d4e71..fee6816ed1 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java @@ -1482,6 +1482,9 @@ abstract class LangExpressionToPlanTranslator throws CompilationException { AbstractFunctionCallExpression f = new ScalarFunctionCallExpression( FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)); + if (rc.hasHints()) { + f.putAnnotations(rc.getHints()); + } f.setSourceLocation(rc.getSourceLocation()); LogicalVariable v1 = context.newVar(); AssignOperator a = new AssignOperator(v1, new MutableObject<>(f)); diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java index 02f1f0e9f8..d813a4c5a2 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java @@ -114,6 +114,7 @@ import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCa import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression; +import org.apache.hyracks.algebricks.core.algebra.expressions.DoNotExtractExpressionAnnotation; import org.apache.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue; import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation; import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression; @@ -916,8 +917,10 @@ public class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTransla CallExpr toObjectExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.TO_OBJECT), Collections.singletonList(projectionExpr)); toObjectExpr.setSourceLocation(sourceLoc); + RecordConstructor recordConstructor = new RecordConstructor(Collections.emptyList()); + recordConstructor.addHint(DoNotExtractExpressionAnnotation.INSTANCE); CallExpr ifMissingOrNullExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.IF_MISSING_OR_NULL), - Arrays.asList(toObjectExpr, new RecordConstructor(Collections.emptyList()))); + Arrays.asList(toObjectExpr, recordConstructor)); ifMissingOrNullExpr.setSourceLocation(sourceLoc); return ifMissingOrNullExpr; } diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-3682-field-access-in-join.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-3682-field-access-in-join.plan index a44e1cb635..be7926f2c9 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-3682-field-access-in-join.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-3682-field-access-in-join.plan @@ -4,327 +4,325 @@ distribute result [$$446] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| project ([$$446]) -- STREAM_PROJECT |PARTITIONED| - assign [$$446] <- [if-missing-or-null(to-object($$593), cast($$456))] + assign [$$446] <- [if-missing-or-null(to-object($$592), cast({ }))] -- ASSIGN |PARTITIONED| - project ([$$456, $$593]) + project ([$$592]) -- STREAM_PROJECT |PARTITIONED| exchange - -- SORT_MERGE_EXCHANGE [$$529(ASC), $$530(ASC), $$531(ASC), $$532(ASC) ] |PARTITIONED| - order (ASC, $$529) (ASC, $$530) (ASC, $$531) (ASC, $$532) - -- STABLE_SORT [$$529(ASC), $$530(ASC), $$531(ASC), $$532(ASC)] |PARTITIONED| + -- SORT_MERGE_EXCHANGE [$$528(ASC), $$529(ASC), $$530(ASC), $$531(ASC) ] |PARTITIONED| + order (ASC, $$528) (ASC, $$529) (ASC, $$530) (ASC, $$531) + -- STABLE_SORT [$$528(ASC), $$529(ASC), $$530(ASC), $$531(ASC)] |PARTITIONED| exchange -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - assign [$$529, $$530, $$531, $$532] <- [$$593.getField("join_key2"), $$593.getField("wsc"), $$593.getField("lcd"), $$593.getField("wsd")] + assign [$$528, $$529, $$530, $$531] <- [$$592.getField("join_key2"), $$592.getField("wsc"), $$592.getField("lcd"), $$592.getField("wsd")] -- ASSIGN |PARTITIONED| - project ([$$456, $$593]) + project ([$$592]) -- STREAM_PROJECT |PARTITIONED| select (and(like($$455, "%"), not(is-missing($$455)))) -- STREAM_SELECT |PARTITIONED| - project ([$$456, $$593, $$455]) + project ([$$592, $$455]) -- STREAM_PROJECT |PARTITIONED| - assign [$$593, $$455] <- [object-concat-strict(if-missing-or-null(to-object($$323), cast($$456)), {"lov_cKey": $$466, "wsd": $$603, "wsm": $$604, "wsc": $$513, "scKey": $$602, "wpdi": $$509, "bch": $$525, "omaa": $$526, "bco": uppercase(substring($$525, 0, position($$525, "_")))}), object-concat-strict(if-missing-or-null(to-object($$323), cast($$456)), {"lov_cKey": $$466, "wsd": $$388.getField(3), "wsm": $$388.getField(4), "wsc": $$513, "scKey": $$602, "wpdi": $$5 [...] + assign [$$592, $$455] <- [object-concat-strict(if-missing-or-null(to-object($$323), cast({ })), {"lov_cKey": $$465, "wsd": $$602, "wsm": $$603, "wsc": $$512, "scKey": $$601, "wpdi": $$508, "bch": $$524, "omaa": $$525, "bco": uppercase(substring($$524, 0, position($$524, "_")))}), object-concat-strict(if-missing-or-null(to-object($$323), cast({ })), {"lov_cKey": $$465, "wsd": $$388.getField(3), "wsm": $$388.getField(4), "wsc": $$512, "scKey": $$601, "wpdi": $$508 [...] -- ASSIGN |PARTITIONED| - select (and(like(object-concat-strict(if-missing-or-null(to-object($$323), cast($$456)), {"lov_cKey": $$466, "wsd": $$388.getField(3), "wsm": $$388.getField(4), "wsc": $$388.getField("wsc"), "scKey": $$602, "wpdi": $$509, "bch": $$525, "omaa": $$526, "bco": uppercase(substring($$525, 0, position($$525, "_")))}).getField("bch"), "%"), like(object-concat-strict(if-missing-or-null(to-object($$323), cast($$456)), {"lov_cKey": $$466, "wsd": $$388.getField(3), "wsm": [...] + select (and(like(object-concat-strict(if-missing-or-null(to-object($$323), cast({ })), {"lov_cKey": $$465, "wsd": $$388.getField(3), "wsm": $$388.getField(4), "wsc": $$388.getField("wsc"), "scKey": $$601, "wpdi": $$508, "bch": $$524, "omaa": $$525, "bco": uppercase(substring($$524, 0, position($$524, "_")))}).getField("bch"), "%"), like(object-concat-strict(if-missing-or-null(to-object($$323), cast({ })), {"lov_cKey": $$465, "wsd": $$388.getField(3), "wsm": $$ [...] -- STREAM_SELECT |PARTITIONED| - project ([$$323, $$466, $$603, $$604, $$513, $$602, $$509, $$388, $$456, $$525, $$526]) + project ([$$323, $$465, $$602, $$603, $$512, $$601, $$508, $$388, $$524, $$525]) -- STREAM_PROJECT |PARTITIONED| exchange -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - join (eq($$476, $$509)) - -- HYBRID_HASH_JOIN [$$509][$$476] |PARTITIONED| + join (eq($$475, $$508)) + -- HYBRID_HASH_JOIN [$$508][$$475] |PARTITIONED| exchange - -- HASH_PARTITION_EXCHANGE [$$509] |PARTITIONED| - assign [$$456] <- [{ }] - -- ASSIGN |PARTITIONED| - project ([$$323, $$466, $$603, $$604, $$513, $$602, $$509, $$388]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - join (and(eq($$599, $$601), eq($$466, $$602))) - -- HYBRID_HASH_JOIN [$$599, $$466][$$601, $$602] |PARTITIONED| - exchange - -- HASH_PARTITION_EXCHANGE [$$599, $$466] |PARTITIONED| - project ([$$323, $$466, $$599]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - join (eq($$uniqueID, $$489)) - -- HYBRID_HASH_JOIN [$$489][$$uniqueID] |PARTITIONED| - exchange - -- HASH_PARTITION_EXCHANGE [$$489] |PARTITIONED| - project ([$$323, $$599, $$489]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$323] <- [{"join_key2": $$599, "lov13_wsx1": substring($$465, 0, 7), "lcd": substring($$465, 0, 10), "lov13_name": $$467, "lov13_uunn": $$489, "lov13_t0_dd": $$600, "lov13_t0_ff": substring($$600, 0, 19)}] - -- ASSIGN |PARTITIONED| - project ([$$465, $$489, $$467, $$599, $$600]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$600] <- [to-string($$u_val.getField("t0"))] - -- ASSIGN |PARTITIONED| - select (not(is-null($$599))) - -- STREAM_SELECT |PARTITIONED| - project ([$$465, $$489, $$467, $$u_val, $$599]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$599] <- [substring(if-missing-or-null(if-missing-or-null($$461.getField("someId1"), $$461.getField("someId2")), $$461.getField("someId3")), 0, 38)] + -- HASH_PARTITION_EXCHANGE [$$508] |PARTITIONED| + project ([$$323, $$465, $$602, $$603, $$512, $$601, $$508, $$388]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + join (and(eq($$598, $$600), eq($$465, $$601))) + -- HYBRID_HASH_JOIN [$$598, $$465][$$600, $$601] |PARTITIONED| + exchange + -- HASH_PARTITION_EXCHANGE [$$598, $$465] |PARTITIONED| + project ([$$323, $$465, $$598]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + join (eq($$uniqueID, $$488)) + -- HYBRID_HASH_JOIN [$$488][$$uniqueID] |PARTITIONED| + exchange + -- HASH_PARTITION_EXCHANGE [$$488] |PARTITIONED| + project ([$$323, $$598, $$488]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$323] <- [{"join_key2": $$598, "lov13_wsx1": substring($$464, 0, 7), "lcd": substring($$464, 0, 10), "lov13_name": $$466, "lov13_uunn": $$488, "lov13_t0_dd": $$599, "lov13_t0_ff": substring($$599, 0, 19)}] + -- ASSIGN |PARTITIONED| + project ([$$464, $$488, $$466, $$598, $$599]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$599] <- [to-string($$u_val.getField("t0"))] + -- ASSIGN |PARTITIONED| + select (not(is-null($$598))) + -- STREAM_SELECT |PARTITIONED| + project ([$$464, $$488, $$466, $$u_val, $$598]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$598] <- [substring(if-missing-or-null(if-missing-or-null($$460.getField("someId1"), $$460.getField("someId2")), $$460.getField("someId3")), 0, 38)] + -- ASSIGN |PARTITIONED| + assign [$$460] <- [$$u_val.getField("marop")] -- ASSIGN |PARTITIONED| - assign [$$461] <- [$$u_val.getField("marop")] - -- ASSIGN |PARTITIONED| - project ([$$465, $$489, $$467, $$u_val]) - -- STREAM_PROJECT |PARTITIONED| - unnest $$u_val <- scan-collection($$290) - -- UNNEST |PARTITIONED| - project ([$$465, $$489, $$467, $$290]) - -- STREAM_PROJECT |PARTITIONED| - subplan { - aggregate [$$290] <- [listify($$289)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- AGGREGATE |LOCAL| - assign [$$289] <- [{"marop": $$468, "t0": $$488}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- ASSIGN |LOCAL| - select (and(eq($$487, "iap"), not(is-unknown($$468)))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- STREAM_SELECT |LOCAL| - assign [$$488, $$468, $$487] <- [$$item2.getField("t0"), $$item2.getField("marop"), $$item2.getField("ua")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- ASSIGN |LOCAL| - unnest $$item2 <- scan-collection($$486) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- UNNEST |LOCAL| - nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- NESTED_TUPLE_SOURCE |LOCAL| - } - -- SUBPLAN |PARTITIONED| - select (not(or(eq($$467, "p1"), eq($$467, "p2"), eq($$467, "p3")))) - -- STREAM_SELECT |PARTITIONED| - project ([$$465, $$489, $$486, $$467]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - join (eq($$470, $$275)) - -- HYBRID_HASH_JOIN [$$275][$$470] |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - assign [$$275] <- [get-item(split($$467, " "), 0)] - -- ASSIGN |PARTITIONED| - project ([$$465, $$489, $$486, $$467]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$486, $$467] <- [$$item.getField("value"), $$item.getField("name")] - -- ASSIGN |PARTITIONED| - project ([$$465, $$489, $$item]) - -- STREAM_PROJECT |PARTITIONED| - unnest $$item <- scan-collection(object-pairs($$477)) - -- UNNEST |PARTITIONED| - project ([$$465, $$489, $$477]) - -- STREAM_PROJECT |PARTITIONED| - select ($$262) - -- STREAM_SELECT |PARTITIONED| - project ([$$262, $$465, $$489, $$477]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - group by ([$$551 := $$457]) decor ([$$465; $$489; $$477]) { - aggregate [$$262] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- AGGREGATE |LOCAL| - select (not(is-missing($$550))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- STREAM_SELECT |LOCAL| - nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- NESTED_TUPLE_SOURCE |LOCAL| - } - -- PRE_CLUSTERED_GROUP_BY[$$457] |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$489, $$465, $$477, $$550, $$457]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - left outer join (eq($$457, $$549)) - -- HYBRID_HASH_JOIN [$$457][$$549] |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$489, $$465, $$477, $$457]) - -- STREAM_PROJECT |PARTITIONED| - select (and(eq($$b.getField("t"), "lovStat"), not(and(eq(len($$597), 1), eq(get-item($$597, 0), "some_str"))))) - -- STREAM_SELECT |PARTITIONED| - assign [$$597] <- [object-names($$477)] + project ([$$464, $$488, $$466, $$u_val]) + -- STREAM_PROJECT |PARTITIONED| + unnest $$u_val <- scan-collection($$290) + -- UNNEST |PARTITIONED| + project ([$$464, $$488, $$466, $$290]) + -- STREAM_PROJECT |PARTITIONED| + subplan { + aggregate [$$290] <- [listify($$289)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- AGGREGATE |LOCAL| + assign [$$289] <- [{"marop": $$467, "t0": $$487}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- ASSIGN |LOCAL| + select (and(eq($$486, "iap"), not(is-unknown($$467)))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- STREAM_SELECT |LOCAL| + assign [$$487, $$467, $$486] <- [$$item2.getField("t0"), $$item2.getField("marop"), $$item2.getField("ua")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- ASSIGN |LOCAL| + unnest $$item2 <- scan-collection($$485) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- UNNEST |LOCAL| + nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- SUBPLAN |PARTITIONED| + select (not(or(eq($$466, "p1"), eq($$466, "p2"), eq($$466, "p3")))) + -- STREAM_SELECT |PARTITIONED| + project ([$$464, $$488, $$485, $$466]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + join (eq($$469, $$275)) + -- HYBRID_HASH_JOIN [$$275][$$469] |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + assign [$$275] <- [get-item(split($$466, " "), 0)] + -- ASSIGN |PARTITIONED| + project ([$$464, $$488, $$485, $$466]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$485, $$466] <- [$$item.getField("value"), $$item.getField("name")] + -- ASSIGN |PARTITIONED| + project ([$$464, $$488, $$item]) + -- STREAM_PROJECT |PARTITIONED| + unnest $$item <- scan-collection(object-pairs($$476)) + -- UNNEST |PARTITIONED| + project ([$$464, $$488, $$476]) + -- STREAM_PROJECT |PARTITIONED| + select ($$262) + -- STREAM_SELECT |PARTITIONED| + project ([$$262, $$464, $$488, $$476]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + group by ([$$550 := $$456]) decor ([$$464; $$488; $$476]) { + aggregate [$$262] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- AGGREGATE |LOCAL| + select (not(is-missing($$549))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- STREAM_SELECT |LOCAL| + nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- PRE_CLUSTERED_GROUP_BY[$$456] |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$488, $$464, $$476, $$549, $$456]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + left outer join (eq($$456, $$548)) + -- HYBRID_HASH_JOIN [$$456][$$548] |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$488, $$464, $$476, $$456]) + -- STREAM_PROJECT |PARTITIONED| + select (and(eq($$b.getField("t"), "lovStat"), not(and(eq(len($$596), 1), eq(get-item($$596, 0), "some_str"))))) + -- STREAM_SELECT |PARTITIONED| + assign [$$596] <- [object-names($$476)] + -- ASSIGN |PARTITIONED| + assign [$$488, $$464, $$476] <- [$$b.getField("uunn"), $$b.getField("qwer"), $$b.getField("ihsaa")] -- ASSIGN |PARTITIONED| - assign [$$489, $$465, $$477] <- [$$b.getField("uunn"), $$b.getField("qwer"), $$b.getField("ihsaa")] - -- ASSIGN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$457, $$b] <- test.col2 - -- DATASOURCE_SCAN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - empty-tuple-source - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - assign [$$550] <- [true] - -- ASSIGN |PARTITIONED| - project ([$$549]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - join (eq($$469, $$251)) - -- HYBRID_HASH_JOIN [$$251][$$469] |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$549, $$251]) - -- STREAM_PROJECT |PARTITIONED| - select ($$260) - -- STREAM_SELECT |PARTITIONED| - project ([$$549, $$251, $$260]) - -- STREAM_PROJECT |PARTITIONED| - subplan { - aggregate [$$260] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- AGGREGATE |LOCAL| - select (and(eq($$484, "iap"), not(is-unknown($$483)))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- STREAM_SELECT |LOCAL| - assign [$$484, $$483] <- [$$item2.getField("ua"), $$item2.getField("marop")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- ASSIGN |LOCAL| - unnest $$item2 <- scan-collection($$482) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- UNNEST |LOCAL| - nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- NESTED_TUPLE_SOURCE |LOCAL| - } - -- SUBPLAN |PARTITIONED| - project ([$$549, $$251, $$482]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$251, $$482] <- [get-item(split($$item.getField("name"), " "), 0), $$item.getField("value")] - -- ASSIGN |PARTITIONED| - project ([$$549, $$item]) - -- STREAM_PROJECT |PARTITIONED| - unnest $$item <- scan-collection(object-pairs($$545)) - -- UNNEST |PARTITIONED| - project ([$$549, $$545]) - -- STREAM_PROJECT |PARTITIONED| - select (and(not(and(eq(len($$598), 1), eq(get-item($$598, 0), "some_str"))), eq($$546.getField("t"), "lovStat"))) - -- STREAM_SELECT |PARTITIONED| - assign [$$598] <- [object-names($$545)] - -- ASSIGN |PARTITIONED| - assign [$$545] <- [$$546.getField("ihsaa")] - -- ASSIGN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$549, $$546] <- test.col2 - -- DATASOURCE_SCAN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - empty-tuple-source - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - exchange - -- BROADCAST_EXCHANGE |PARTITIONED| - unnest $$469 <- scan-collection(array: [ "X", "Y" ]) - -- UNNEST |UNPARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + data-scan []<-[$$456, $$b] <- test.col2 + -- DATASOURCE_SCAN |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| empty-tuple-source - -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| - exchange - -- BROADCAST_EXCHANGE |PARTITIONED| - unnest $$470 <- scan-collection(array: [ "X", "Y" ]) - -- UNNEST |UNPARTITIONED| - empty-tuple-source - -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| - exchange - -- HASH_PARTITION_EXCHANGE [$$uniqueID] |PARTITIONED| - project ([$$466, $$uniqueID]) - -- STREAM_PROJECT |PARTITIONED| - unnest $$uniqueID <- scan-collection($$505) - -- UNNEST |PARTITIONED| - project ([$$466, $$505]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$505] <- [array-star($$p.getField("members")).getField("uniqueID")] - -- ASSIGN |PARTITIONED| - select (and(eq($$p.getField("r"), "uuu"), eq($$p.getField("t"), "ccc"), not(is-missing($$466)))) - -- STREAM_SELECT |PARTITIONED| - assign [$$466] <- [$$p.getField("cKey")] - -- ASSIGN |PARTITIONED| - project ([$$p]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$p] <- [$$p2] + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + assign [$$549] <- [true] + -- ASSIGN |PARTITIONED| + project ([$$548]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + join (eq($$468, $$251)) + -- HYBRID_HASH_JOIN [$$251][$$468] |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$548, $$251]) + -- STREAM_PROJECT |PARTITIONED| + select ($$260) + -- STREAM_SELECT |PARTITIONED| + project ([$$548, $$251, $$260]) + -- STREAM_PROJECT |PARTITIONED| + subplan { + aggregate [$$260] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- AGGREGATE |LOCAL| + select (and(eq($$483, "iap"), not(is-unknown($$482)))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- STREAM_SELECT |LOCAL| + assign [$$483, $$482] <- [$$item2.getField("ua"), $$item2.getField("marop")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- ASSIGN |LOCAL| + unnest $$item2 <- scan-collection($$481) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- UNNEST |LOCAL| + nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- SUBPLAN |PARTITIONED| + project ([$$548, $$251, $$481]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$251, $$481] <- [get-item(split($$item.getField("name"), " "), 0), $$item.getField("value")] + -- ASSIGN |PARTITIONED| + project ([$$548, $$item]) + -- STREAM_PROJECT |PARTITIONED| + unnest $$item <- scan-collection(object-pairs($$544)) + -- UNNEST |PARTITIONED| + project ([$$548, $$544]) + -- STREAM_PROJECT |PARTITIONED| + select (and(not(and(eq(len($$597), 1), eq(get-item($$597, 0), "some_str"))), eq($$545.getField("t"), "lovStat"))) + -- STREAM_SELECT |PARTITIONED| + assign [$$597] <- [object-names($$544)] + -- ASSIGN |PARTITIONED| + assign [$$544] <- [$$545.getField("ihsaa")] + -- ASSIGN |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + data-scan []<-[$$548, $$545] <- test.col2 + -- DATASOURCE_SCAN |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + empty-tuple-source + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + exchange + -- BROADCAST_EXCHANGE |PARTITIONED| + unnest $$468 <- scan-collection(array: [ "X", "Y" ]) + -- UNNEST |UNPARTITIONED| + empty-tuple-source + -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| + exchange + -- BROADCAST_EXCHANGE |PARTITIONED| + unnest $$469 <- scan-collection(array: [ "X", "Y" ]) + -- UNNEST |UNPARTITIONED| + empty-tuple-source + -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| + exchange + -- HASH_PARTITION_EXCHANGE [$$uniqueID] |PARTITIONED| + project ([$$465, $$uniqueID]) + -- STREAM_PROJECT |PARTITIONED| + unnest $$uniqueID <- scan-collection($$504) + -- UNNEST |PARTITIONED| + project ([$$465, $$504]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$504] <- [array-star($$p.getField("members")).getField("uniqueID")] + -- ASSIGN |PARTITIONED| + select (and(eq($$p.getField("r"), "uuu"), eq($$p.getField("t"), "ccc"), not(is-missing($$465)))) + -- STREAM_SELECT |PARTITIONED| + assign [$$465] <- [$$p.getField("cKey")] + -- ASSIGN |PARTITIONED| + project ([$$p]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$p] <- [$$p2] + -- ASSIGN |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + replicate + -- REPLICATE |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$p2]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + data-scan []<-[$$458, $$p2] <- test.col1 + -- DATASOURCE_SCAN |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + empty-tuple-source + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + exchange + -- HASH_PARTITION_EXCHANGE [$$600, $$601] |PARTITIONED| + project ([$$602, $$603, $$512, $$601, $$508, $$388, $$600]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$388] <- [{"join_key1": $$600, "wpdi": $$508, "wsc": $$512, "scKey": $$601, "wwlps": $$381, "wsd": $$602, "wsm": $$603}] + -- ASSIGN |PARTITIONED| + project ([$$512, $$508, $$381, $$603, $$602, $$601, $$600]) + -- STREAM_PROJECT |PARTITIONED| + assign [$$603, $$602, $$601, $$600] <- [substring($$515, 0, 7), substring($$515, 0, 10), uppercase(substring($$512, 0, position($$512, "_"))), substring($$510, 0, 38)] + -- ASSIGN |PARTITIONED| + project ([$$512, $$508, $$515, $$510, $$381]) + -- STREAM_PROJECT |PARTITIONED| + subplan { + aggregate [$$381] <- [listify($$380)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- AGGREGATE |LOCAL| + assign [$$380] <- [$$item.getField("wkps")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- ASSIGN |LOCAL| + unnest $$item <- scan-collection($$509) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- UNNEST |LOCAL| + nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- SUBPLAN |PARTITIONED| + project ([$$512, $$508, $$515, $$510, $$509]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + join (eq($$472, $$353)) + -- HYBRID_HASH_JOIN [$$353][$$472] |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$512, $$508, $$515, $$510, $$509, $$353]) + -- STREAM_PROJECT |PARTITIONED| + select (and(eq($$p2.getField("t"), "ak1"), not(is-missing($$508)), not(is-missing($$540)))) + -- STREAM_SELECT |PARTITIONED| + assign [$$515, $$512, $$510, $$509, $$508] <- [$$540.getField("ssatt"), $$540.getField("stchk"), $$p2.getField("ed"), $$540.getField("intib"), $$540.getField("coaed")] -- ASSIGN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - replicate - -- REPLICATE |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$p2]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$459, $$p2] <- test.col1 - -- DATASOURCE_SCAN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - empty-tuple-source - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - exchange - -- HASH_PARTITION_EXCHANGE [$$601, $$602] |PARTITIONED| - project ([$$603, $$604, $$513, $$602, $$509, $$388, $$601]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$388] <- [{"join_key1": $$601, "wpdi": $$509, "wsc": $$513, "scKey": $$602, "wwlps": $$381, "wsd": $$603, "wsm": $$604}] - -- ASSIGN |PARTITIONED| - project ([$$513, $$509, $$381, $$604, $$603, $$602, $$601]) - -- STREAM_PROJECT |PARTITIONED| - assign [$$604, $$603, $$602, $$601] <- [substring($$516, 0, 7), substring($$516, 0, 10), uppercase(substring($$513, 0, position($$513, "_"))), substring($$511, 0, 38)] - -- ASSIGN |PARTITIONED| - project ([$$513, $$509, $$516, $$511, $$381]) - -- STREAM_PROJECT |PARTITIONED| - subplan { - aggregate [$$381] <- [listify($$380)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- AGGREGATE |LOCAL| - assign [$$380] <- [$$item.getField("wkps")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- ASSIGN |LOCAL| - unnest $$item <- scan-collection($$510) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- UNNEST |LOCAL| - nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] - -- NESTED_TUPLE_SOURCE |LOCAL| - } - -- SUBPLAN |PARTITIONED| - project ([$$513, $$509, $$516, $$511, $$510]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - join (eq($$473, $$353)) - -- HYBRID_HASH_JOIN [$$353][$$473] |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$513, $$509, $$516, $$511, $$510, $$353]) - -- STREAM_PROJECT |PARTITIONED| - select (and(eq($$p2.getField("t"), "ak1"), not(is-missing($$509)), not(is-missing($$541)))) - -- STREAM_SELECT |PARTITIONED| - assign [$$516, $$513, $$511, $$510, $$509] <- [$$541.getField("ssatt"), $$541.getField("stchk"), $$p2.getField("ed"), $$541.getField("intib"), $$541.getField("coaed")] + assign [$$353, $$540] <- [$$p2.getField("ha"), $$p2.getField("kat")] -- ASSIGN |PARTITIONED| - assign [$$353, $$541] <- [$$p2.getField("ha"), $$p2.getField("kat")] - -- ASSIGN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - replicate - -- REPLICATE |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$p2]) - -- STREAM_PROJECT |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$459, $$p2] <- test.col1 - -- DATASOURCE_SCAN |PARTITIONED| - exchange - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - empty-tuple-source - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - exchange - -- BROADCAST_EXCHANGE |PARTITIONED| - unnest $$473 <- scan-collection(array: [ "l1", "l2" ]) - -- UNNEST |UNPARTITIONED| - empty-tuple-source - -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + replicate + -- REPLICATE |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$p2]) + -- STREAM_PROJECT |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + data-scan []<-[$$458, $$p2] <- test.col1 + -- DATASOURCE_SCAN |PARTITIONED| + exchange + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + empty-tuple-source + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + exchange + -- BROADCAST_EXCHANGE |PARTITIONED| + unnest $$472 <- scan-collection(array: [ "l1", "l2" ]) + -- UNNEST |UNPARTITIONED| + empty-tuple-source + -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| exchange - -- HASH_PARTITION_EXCHANGE [$$476] |PARTITIONED| - project ([$$525, $$526, $$476]) + -- HASH_PARTITION_EXCHANGE [$$475] |PARTITIONED| + project ([$$524, $$525, $$475]) -- STREAM_PROJECT |PARTITIONED| - assign [$$526, $$525] <- [$$454.getField("omaa"), $$454.getField("qaz")] + assign [$$525, $$524] <- [$$454.getField("omaa"), $$454.getField("qaz")] -- ASSIGN |PARTITIONED| select (not(is-missing($$454))) -- STREAM_SELECT |PARTITIONED| - project ([$$476, $$454]) + project ([$$475, $$454]) -- STREAM_PROJECT |PARTITIONED| - assign [$$476, $$454] <- [$$sbr.getField("ed"), $$sbr.getField("tohac")] + assign [$$475, $$454] <- [$$sbr.getField("ed"), $$sbr.getField("tohac")] -- ASSIGN |PARTITIONED| project ([$$sbr]) -- STREAM_PROJECT |PARTITIONED| @@ -340,9 +338,9 @@ distribute result [$$446] -- STREAM_PROJECT |PARTITIONED| exchange -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$459, $$p2] <- test.col1 + data-scan []<-[$$458, $$p2] <- test.col1 -- DATASOURCE_SCAN |PARTITIONED| exchange -- ONE_TO_ONE_EXCHANGE |PARTITIONED| empty-tuple-source - -- EMPTY_TUPLE_SOURCE |PARTITIONED| \ No newline at end of file + -- EMPTY_TUPLE_SOURCE |PARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.1.ddl.sqlpp new file mode 100644 index 0000000000..36024d85d8 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.1.ddl.sqlpp @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +drop dataverse test if exists; +create dataverse test; + +use test; + +create type prim as open { + id: bigint +}; + +create dataset A(prim) +primary key id; + diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.2.update.sqlpp new file mode 100644 index 0000000000..fe77706e1d --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.2.update.sqlpp @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +use test; + +INSERT INTO A( + SELECT VALUE {"id": intVal, "a": intVal%2, "b": intVal%5 , "d": intVal%25} + FROM range(1, 2) intVal +); diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.3.query.sqlpp new file mode 100644 index 0000000000..02ab319123 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/select-star/nested/nested.3.query.sqlpp @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +use test; + +SELECT sub.* FROM (SELECT a.* FROM A a) sub; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/select-star/nested/nested.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/select-star/nested/nested.3.adm new file mode 100644 index 0000000000..125daf12f9 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/select-star/nested/nested.3.adm @@ -0,0 +1,2 @@ +{ "id": 1, "a": 1, "b": 1, "d": 1 } +{ "id": 2, "a": 0, "b": 2, "d": 2 } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml index af63f0b1e4..eb46490c2f 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml @@ -10052,6 +10052,11 @@ <output-dir compare="Text">mixed</output-dir> </compilation-unit> </test-case> + <test-case FilePath="select-star"> + <compilation-unit name="nested"> + <output-dir compare="Text">nested</output-dir> + </compilation-unit> + </test-case> <test-case FilePath="select-star"> <compilation-unit name="no_star"> <output-dir compare="Text">no_star</output-dir> diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/DoNotExtractExpressionAnnotation.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/DoNotExtractExpressionAnnotation.java new file mode 100644 index 0000000000..fa19e22dbc --- /dev/null +++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/DoNotExtractExpressionAnnotation.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hyracks.algebricks.core.algebra.expressions; + +public class DoNotExtractExpressionAnnotation implements IExpressionAnnotation { + public static final DoNotExtractExpressionAnnotation INSTANCE = new DoNotExtractExpressionAnnotation(); + + private DoNotExtractExpressionAnnotation() { + + } +} diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/ExtractCommonExpressionsRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/ExtractCommonExpressionsRule.java index e2ba5571b7..7c4d62c56c 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/ExtractCommonExpressionsRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/ExtractCommonExpressionsRule.java @@ -39,6 +39,7 @@ import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression; +import org.apache.hyracks.algebricks.core.algebra.expressions.DoNotExtractExpressionAnnotation; import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression; import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; @@ -260,6 +261,14 @@ public class ExtractCommonExpressionsRule implements IAlgebraicRewriteRule { return modified; } + private static boolean isExprExtractable(ILogicalExpression expr) { + if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { + return true; + } + AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr; + return !funcExpr.hasAnnotation(DoNotExtractExpressionAnnotation.class); + } + private class CommonExpressionSubstitutionVisitor implements ILogicalExpressionReferenceTransform { private IOptimizationContext context; @@ -302,7 +311,7 @@ public class ExtractCommonExpressionsRule implements IAlgebraicRewriteRule { } } } else { - if (expr.isFunctional() && assignCommonExpression(exprEqClass, expr)) { + if (expr.isFunctional() && isExprExtractable(expr) && assignCommonExpression(exprEqClass, expr)) { modified = true; //re-obtain the live vars after rewriting in the method called in the if condition Set<LogicalVariable> liveVars = new HashSet<LogicalVariable>();
