>From Peeyush Gupta <[email protected]>: Peeyush Gupta has submitted this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17778 )
Change subject: [ASTERIXDB-3263][COMP] Incorrect data inserted when optional field in closed type ...................................................................... [ASTERIXDB-3263][COMP] Incorrect data inserted when optional field in closed type - user model changes: no - storage format changes: no - interface changes: no Details: - Update the dynamic type cast rule to correctly check type compatibility in case of insert/upsert. - Update the constant folding rule to allow constant fold closed records. Change-Id: I3469da3f4f70759886fe9b98faf99eaaceff1edc Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17778 Reviewed-by: Peeyush Gupta <[email protected]> Reviewed-by: Ali Alsuliman <[email protected]> Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> --- A asterixdb/asterix-app/src/test/resources/runtimets/results/dml/insert-closed/insert-closed.1.adm M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.1.ddl.sqlpp M asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan M asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.5.plan A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.3.query.sqlpp M asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java M asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FullTextContainsParameterCheckAndSetRule.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.2.update.sqlpp 13 files changed, 314 insertions(+), 165 deletions(-) Approvals: Ali Alsuliman: Looks good to me, approved Peeyush Gupta: Looks good to me, but someone else must approve Jenkins: Verified; Verified Objections: Anon. E. Moose #1000171: Violations found diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java index 9fe1ba4..3b39d7c 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java @@ -395,12 +395,14 @@ if (fi.isExternal()) { return false; } + IAType returnType = (IAType) _emptyTypeEnv.getType(function); // skip all functions that would produce records/arrays/multisets (derived types) in their open format // this is because constant folding them will make them closed (currently) if (function.getFunctionIdentifier().equals(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)) { - return false; + if (returnType.getTypeTag() != ATypeTag.OBJECT || ((ARecordType) returnType).isOpen()) { + return false; + } } - IAType returnType = (IAType) _emptyTypeEnv.getType(function); return canConstantFoldType(returnType); } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FullTextContainsParameterCheckAndSetRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FullTextContainsParameterCheckAndSetRule.java index 3e4e563..3b2153c 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FullTextContainsParameterCheckAndSetRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FullTextContainsParameterCheckAndSetRule.java @@ -26,9 +26,11 @@ import org.apache.asterix.common.metadata.DataverseName; import org.apache.asterix.metadata.declared.MetadataProvider; import org.apache.asterix.metadata.utils.FullTextUtil; +import org.apache.asterix.om.base.ARecord; import org.apache.asterix.om.base.AString; import org.apache.asterix.om.constants.AsterixConstantValue; import org.apache.asterix.om.functions.BuiltinFunctions; +import org.apache.asterix.om.types.ARecordType; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.utils.ConstantExpressionUtil; import org.apache.asterix.runtime.evaluators.functions.FullTextContainsFunctionDescriptor; @@ -239,82 +241,111 @@ List<Mutable<ILogicalExpression>> newArgs, String functionName) throws AlgebricksException { String ftConfigName = null; - // Get the last parameter - this should be a record-constructor. - AbstractFunctionCallExpression openRecConsExpr = (AbstractFunctionCallExpression) expr.getValue(); - FunctionIdentifier openRecConsFi = openRecConsExpr.getFunctionIdentifier(); - if (openRecConsFi != BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR - && openRecConsFi != BuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR) { - throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, openRecConsExpr.getSourceLocation(), - functionName, openRecConsFi); - } - - // We multiply 2 because the layout of the arguments are: [expr, val, expr1, val1, ...] - if (openRecConsExpr.getArguments().size() > FullTextContainsFunctionDescriptor.getParamTypeMap().size() - * 2) { - throw CompilationException.create(ErrorCode.TOO_MANY_OPTIONS_FOR_FUNCTION, - openRecConsExpr.getSourceLocation(), functionName); - } - - if (openRecConsExpr.getArguments().size() % 2 != 0) { - throw CompilationException.create(ErrorCode.COMPILATION_INVALID_PARAMETER_NUMBER, - openRecConsExpr.getSourceLocation(), functionName); - } - - for (int i = 0; i < openRecConsExpr.getArguments().size(); i = i + 2) { - ILogicalExpression optionExpr = openRecConsExpr.getArguments().get(i).getValue(); - ILogicalExpression optionExprVal = openRecConsExpr.getArguments().get(i + 1).getValue(); - - String option = ConstantExpressionUtil.getStringConstant(optionExpr); - - if (optionExpr.getExpressionTag() != LogicalExpressionTag.CONSTANT || option == null) { - throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExpr.getSourceLocation(), - functionName, optionExpr.getExpressionTag()); + // Get the last parameter - this should be a record-constructor or a constant expression. + if (expr.getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT) { + ConstantExpression constantExpression = (ConstantExpression) expr.getValue(); + ARecord record = + (ARecord) ConstantExpressionUtil.getConstantIaObject(constantExpression, ATypeTag.OBJECT); + if (record == null) { + throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, + constantExpression.getSourceLocation(), functionName, + constantExpression.getExpressionTag()); + } + ARecordType recordType = record.getType(); + if (record.numberOfFields() > FullTextContainsFunctionDescriptor.getParamTypeMap().size()) { + throw CompilationException.create(ErrorCode.TOO_MANY_OPTIONS_FOR_FUNCTION, + constantExpression.getSourceLocation(), functionName); + } + for (int i = 0; i < record.numberOfFields(); i++) { + String option = recordType.getFieldNames()[i].toLowerCase(); + ILogicalExpression optionExpr = + new ConstantExpression(new AsterixConstantValue(new AString(option))); + ILogicalExpression optionExprVal = + new ConstantExpression(new AsterixConstantValue(record.getValueByPos(i))); + ftConfigName = handleThirdParameterOptions(optionExpr, optionExprVal, newArgs, functionName); + } + } else { + AbstractFunctionCallExpression openRecConsExpr = (AbstractFunctionCallExpression) expr.getValue(); + FunctionIdentifier openRecConsFi = openRecConsExpr.getFunctionIdentifier(); + if (openRecConsFi != BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR + && openRecConsFi != BuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR) { + throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, openRecConsExpr.getSourceLocation(), + functionName, openRecConsFi); } - option = option.toLowerCase(); - if (!FullTextContainsFunctionDescriptor.getParamTypeMap().containsKey(option)) { - throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExprVal.getSourceLocation(), - functionName, option); + // We multiply 2 because the layout of the arguments are: [expr, val, expr1, val1, ...] + if (openRecConsExpr.getArguments().size() > FullTextContainsFunctionDescriptor.getParamTypeMap().size() + * 2) { + throw CompilationException.create(ErrorCode.TOO_MANY_OPTIONS_FOR_FUNCTION, + openRecConsExpr.getSourceLocation(), functionName); } - String optionTypeStringVal = null; - // If the option value is a constant, then we can check here. - if (optionExprVal.getExpressionTag() == LogicalExpressionTag.CONSTANT) { - switch (FullTextContainsFunctionDescriptor.getParamTypeMap().get(option)) { - case STRING: - optionTypeStringVal = ConstantExpressionUtil.getStringConstant(optionExprVal); - if (optionTypeStringVal == null) { - throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, - optionExprVal.getSourceLocation(), functionName, option); - } - optionTypeStringVal = optionTypeStringVal.toLowerCase(); - break; - default: - // Currently, we only have a string parameter. So, the flow doesn't reach here. + if (openRecConsExpr.getArguments().size() % 2 != 0) { + throw CompilationException.create(ErrorCode.COMPILATION_INVALID_PARAMETER_NUMBER, + openRecConsExpr.getSourceLocation(), functionName); + } + + for (int i = 0; i < openRecConsExpr.getArguments().size(); i = i + 2) { + ILogicalExpression optionExpr = openRecConsExpr.getArguments().get(i).getValue(); + ILogicalExpression optionExprVal = openRecConsExpr.getArguments().get(i + 1).getValue(); + ftConfigName = handleThirdParameterOptions(optionExpr, optionExprVal, newArgs, functionName); + } + } + return ftConfigName; + } + + private String handleThirdParameterOptions(ILogicalExpression optionExpr, ILogicalExpression optionExprVal, + List<Mutable<ILogicalExpression>> newArgs, String functionName) throws AlgebricksException { + String ftConfigName = null; + String option = ConstantExpressionUtil.getStringConstant(optionExpr); + + if (optionExpr.getExpressionTag() != LogicalExpressionTag.CONSTANT || option == null) { + throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExpr.getSourceLocation(), + functionName, optionExpr.getExpressionTag()); + } + + option = option.toLowerCase(); + if (!FullTextContainsFunctionDescriptor.getParamTypeMap().containsKey(option)) { + throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExprVal.getSourceLocation(), + functionName, option); + } + + String optionTypeStringVal = null; + // If the option value is a constant, then we can check here. + if (optionExprVal.getExpressionTag() == LogicalExpressionTag.CONSTANT) { + switch (FullTextContainsFunctionDescriptor.getParamTypeMap().get(option)) { + case STRING: + optionTypeStringVal = ConstantExpressionUtil.getStringConstant(optionExprVal); + if (optionTypeStringVal == null) { throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExprVal.getSourceLocation(), functionName, option); - } - - // Check the validity of option value - switch (option) { - case FullTextContainsFunctionDescriptor.SEARCH_MODE_OPTION: - checkSearchModeOption(optionTypeStringVal, functionName, optionExprVal.getSourceLocation()); - break; - case FullTextContainsFunctionDescriptor.FULLTEXT_CONFIG_OPTION: - checkFullTextConfigOption(optionTypeStringVal, functionName, - optionExprVal.getSourceLocation()); - ftConfigName = optionTypeStringVal; - break; - default: - throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, - optionExprVal.getSourceLocation(), functionName, option); - } + } + optionTypeStringVal = optionTypeStringVal.toLowerCase(); + break; + default: + // Currently, we only have a string parameter. So, the flow doesn't reach here. + throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExprVal.getSourceLocation(), + functionName, option); } - // Add this option as arguments to the ftcontains(). - newArgs.add(new MutableObject<ILogicalExpression>(optionExpr)); - newArgs.add(new MutableObject<ILogicalExpression>(optionExprVal)); + // Check the validity of option value + switch (option) { + case FullTextContainsFunctionDescriptor.SEARCH_MODE_OPTION: + checkSearchModeOption(optionTypeStringVal, functionName, optionExprVal.getSourceLocation()); + break; + case FullTextContainsFunctionDescriptor.FULLTEXT_CONFIG_OPTION: + checkFullTextConfigOption(optionTypeStringVal, functionName, optionExprVal.getSourceLocation()); + ftConfigName = optionTypeStringVal; + break; + default: + throw CompilationException.create(ErrorCode.TYPE_UNSUPPORTED, optionExprVal.getSourceLocation(), + functionName, option); + } } + + // Add this option as arguments to the ftcontains(). + newArgs.add(new MutableObject<>(optionExpr)); + newArgs.add(new MutableObject<>(optionExprVal)); return ftConfigName; } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java index 22d87ac..e8f9048 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java @@ -81,8 +81,7 @@ reqArgType = ((ExternalFunctionInfo) funcCallExpr.getFunctionInfo()).getParameterTypes().get(i); if (reqArgType.getTypeTag() == ATypeTag.OBJECT) { - castFlag = !IntroduceDynamicTypeCastRule.compatible((ARecordType) reqArgType, inputType, - argExpr.getValue().getSourceLocation()); + castFlag = !IntroduceDynamicTypeCastRule.compatible((ARecordType) reqArgType, inputType, op); } else if (reqArgType.getTypeTag() == ATypeTag.ANY) { IAType inputPrimeType = TypeComputeUtils.getActualType(inputType); castFlag = inputPrimeType.getTypeTag().isDerivedType(); diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java index 4044965..a9ad7ce 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java @@ -167,7 +167,7 @@ } /** see whether the input record type needs to be casted */ - boolean cast = !compatible(requiredRecordType, inputRecordType, op.getSourceLocation()); + boolean cast = !compatible(requiredRecordType, inputRecordType, op); if (checkUnknown) { recordVar = addWrapperFunction(requiredRecordType, recordVar, op, context, BuiltinFunctions.CHECK_UNKNOWN); @@ -252,8 +252,9 @@ * @return true if compatible; false otherwise * @throws AlgebricksException */ - public static boolean compatible(ARecordType reqType, IAType inputType, SourceLocation sourceLoc) + public static boolean compatible(ARecordType reqType, IAType inputType, ILogicalOperator op) throws AlgebricksException { + SourceLocation sourceLoc = op.getSourceLocation(); if (inputType.getTypeTag() == ATypeTag.ANY) { return false; } @@ -279,19 +280,25 @@ return false; } IAType reqTypeInside = reqTypes[i]; - if (NonTaggedFormatUtil.isOptional(reqTypes[i])) { - reqTypeInside = ((AUnionType) reqTypes[i]).getActualType(); - } IAType inputTypeInside = inputTypes[i]; - if (NonTaggedFormatUtil.isOptional(inputTypes[i])) { - if (!NonTaggedFormatUtil.isOptional(reqTypes[i])) { - /** if the required type is not optional, the two types are incompatible */ + if (op.getOperatorTag() == LogicalOperatorTag.INSERT_DELETE_UPSERT) { + if (!reqTypeInside.equals(inputTypeInside)) { return false; } - inputTypeInside = ((AUnionType) inputTypes[i]).getActualType(); - } - if (inputTypeInside.getTypeTag() != ATypeTag.MISSING && !reqTypeInside.equals(inputTypeInside)) { - return false; + } else { + if (NonTaggedFormatUtil.isOptional(reqTypes[i])) { + reqTypeInside = ((AUnionType) reqTypes[i]).getActualType(); + } + if (NonTaggedFormatUtil.isOptional(inputTypes[i])) { + if (!NonTaggedFormatUtil.isOptional(reqTypes[i])) { + /** if the required type is not optional, the two types are incompatible */ + return false; + } + inputTypeInside = ((AUnionType) inputTypes[i]).getActualType(); + } + if (inputTypeInside.getTypeTag() != ATypeTag.MISSING && !reqTypeInside.equals(inputTypeInside)) { + return false; + } } } return true; diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan index 1d2e55b..9b51cb0 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan @@ -2,46 +2,38 @@ -- ONE_TO_ONE_EXCHANGE |PARTITIONED| -- STREAM_PROJECT |PARTITIONED| -- ASSIGN |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- NESTED_LOOP |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- HYBRID_HASH_JOIN [$$82][$$83] |PARTITIONED| - -- HASH_PARTITION_EXCHANGE [$$82] |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- STREAM_SELECT |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- BTREE_SEARCH (Test.Users.Users) |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STABLE_SORT [$$106(ASC)] |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- BTREE_SEARCH (Test.Users.usersNameIdx) |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - -- HASH_PARTITION_EXCHANGE [$$83] |PARTITIONED| - -- STREAM_SELECT |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- BTREE_SEARCH (Test.Users.Users) |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STABLE_SORT [$$110(ASC)] |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- BTREE_SEARCH (Test.Users.usersNameIdx) |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - -- BROADCAST_EXCHANGE |PARTITIONED| - -- STREAM_SELECT |UNPARTITIONED| - -- ASSIGN |UNPARTITIONED| - -- UNNEST |UNPARTITIONED| - -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| \ No newline at end of file + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- HYBRID_HASH_JOIN [$$88][$$89] |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$88] |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- BTREE_SEARCH (Test.Users.Users) |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STABLE_SORT [$$110(ASC)] |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- BTREE_SEARCH (Test.Users.usersNameIdx) |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$89] |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- BTREE_SEARCH (Test.Users.Users) |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STABLE_SORT [$$114(ASC)] |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- BTREE_SEARCH (Test.Users.usersNameIdx) |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan index 9a296a5..5f89a6d 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan @@ -4,7 +4,7 @@ -- INSERT_DELETE |PARTITIONED| -- HASH_PARTITION_EXCHANGE [$$3] |PARTITIONED| -- ASSIGN |UNPARTITIONED| - -- STREAM_PROJECT |UNPARTITIONED| - -- ASSIGN |UNPARTITIONED| + -- ASSIGN |UNPARTITIONED| + -- STREAM_PROJECT |UNPARTITIONED| -- ASSIGN |UNPARTITIONED| -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan index 75a50b4..a7f92e3 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan @@ -2,40 +2,32 @@ -- ONE_TO_ONE_EXCHANGE |PARTITIONED| -- STREAM_PROJECT |PARTITIONED| -- ASSIGN |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- NESTED_LOOP |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- HYBRID_HASH_JOIN [$$88][$$89] |PARTITIONED| - -- HASH_PARTITION_EXCHANGE [$$88] |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- STREAM_SELECT |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- REPLICATE |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- DATASOURCE_SCAN (Test.Users) |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - -- HASH_PARTITION_EXCHANGE [$$89] |PARTITIONED| - -- STREAM_SELECT |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- HYBRID_HASH_JOIN [$$88][$$89] |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$88] |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| -- ASSIGN |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- REPLICATE |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- DATASOURCE_SCAN (Test.Users) |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- EMPTY_TUPLE_SOURCE |PARTITIONED| - -- BROADCAST_EXCHANGE |PARTITIONED| - -- STREAM_SELECT |UNPARTITIONED| - -- ASSIGN |UNPARTITIONED| - -- UNNEST |UNPARTITIONED| - -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- REPLICATE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN (Test.Users) |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$89] |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- REPLICATE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN (Test.Users) |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.1.ddl.sqlpp new file mode 100644 index 0000000..b3ab9eb --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.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 testtype01 as + closed { + id : string, + name : string? +}; + +create dataset testds01(testtype01) primary key id; + diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.2.update.sqlpp new file mode 100644 index 0000000..8f7d83e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.2.update.sqlpp @@ -0,0 +1,34 @@ +/* + * 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 testds01([{"id":"1", "name":"John1"}]); + +insert into testds01 {"id":"2", "name":"John2"}; + +insert into testds01([{"id":"3", "name":"John3"}, {"id":"4", "name":"John4"}]); + +insert into testds01([{"id":"5", "name":"John5"}, {"id":"6"}]); + +insert into testds01([{"id":"7"}, {"id":"8", "name":"John8"}]); + +insert into testds01([{"id":"9"}]); + +insert into testds01 select element {"id":"10", "name":"John10"}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.3.query.sqlpp new file mode 100644 index 0000000..be5fb5d --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dml/insert-closed/insert-closed.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 * from testds01 order by id; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.5.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.5.plan index 0100d55..5b6ddc1 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.5.plan +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.5.plan @@ -2,7 +2,7 @@ -- DISTRIBUTE_RESULT |UNPARTITIONED| exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |UNPARTITIONED| - unnest $$d <- scan-collection(ordered-list-constructor({"id": 1, "t1": array-remove(ordered-list-constructor(1, 2, 3, ordered-list-constructor(9, 8), ordered-list-constructor("str1", "str2"), ordered-list-constructor(90, 100)), array: [ 9, 8 ], array: [ 90, 100 ])}, {"id": 2, "t2": cast(array: [ array: [ 5, 1, 2 ], array: [ 90, 100 ] ])}, {"id": 3, "t3": cast(array-remove(ordered-list-constructor({"id": 1, "age": 34}, {"id": 2, "age": 29}, {"id": 3, "age": 90}), {"id": 4, "age": 90}, {"id": 2, "age": 29}))})) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + unnest $$d <- scan-collection(ordered-list-constructor({"id": 1, "t1": array-remove(ordered-list-constructor(1, 2, 3, ordered-list-constructor(9, 8), ordered-list-constructor("str1", "str2"), ordered-list-constructor(90, 100)), array: [ 9, 8 ], array: [ 90, 100 ])}, {"id": 2, "t2": cast(array: [ array: [ 5, 1, 2 ], array: [ 90, 100 ] ])}, {"id": 3, "t3": cast(array: [ { "id": 1, "age": 34 }, { "id": 3, "age": 90 } ])})) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- UNNEST |UNPARTITIONED| empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/dml/insert-closed/insert-closed.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/dml/insert-closed/insert-closed.1.adm new file mode 100644 index 0000000..4166875 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/dml/insert-closed/insert-closed.1.adm @@ -0,0 +1,10 @@ +{ "testds01": { "id": "1", "name": "John1" } } +{ "testds01": { "id": "10", "name": "John10" } } +{ "testds01": { "id": "2", "name": "John2" } } +{ "testds01": { "id": "3", "name": "John3" } } +{ "testds01": { "id": "4", "name": "John4" } } +{ "testds01": { "id": "5", "name": "John5" } } +{ "testds01": { "id": "6" } } +{ "testds01": { "id": "7" } } +{ "testds01": { "id": "8", "name": "John8" } } +{ "testds01": { "id": "9" } } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml index 6d83fb5..1800d47 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -4570,6 +4570,11 @@ </compilation-unit> </test-case> <test-case FilePath="dml"> + <compilation-unit name="insert-closed"> + <output-dir compare="Text">insert-closed</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="dml"> <compilation-unit name="insert-duplicated-keys"> <output-dir compare="Text">insert-duplicated-keys</output-dir> <expected-error>Inserting duplicate keys into the primary storage</expected-error> -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17778 To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Change-Id: I3469da3f4f70759886fe9b98faf99eaaceff1edc Gerrit-Change-Number: 17778 Gerrit-PatchSet: 8 Gerrit-Owner: Peeyush Gupta <[email protected]> Gerrit-Reviewer: Ali Alsuliman <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Murtadha Hubail <[email protected]> Gerrit-Reviewer: Peeyush Gupta <[email protected]> Gerrit-MessageType: merged
