>From Peeyush Gupta <[email protected]>: Peeyush Gupta has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19730 )
Change subject: [ASTERIXDB-3603][FUN] Adding validation for transform functions ...................................................................... [ASTERIXDB-3603][FUN] Adding validation for transform functions - user model changes: no - storage format changes: no - interface changes: no Ext-ref: MB-63039 Change-Id: I524cbfb6685bd3c7ed269c2db48482e5aba1ce6c --- A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.005.ddl.sqlpp M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.002.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.004.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.003.ddl.sqlpp M asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.001.ddl.sqlpp A asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/visitor/FunctionCardinalityInferenceVisitor.java A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.002.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.000.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.005.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.003.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.000.ddl.sqlpp M asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.001.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.004.ddl.sqlpp M hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java 18 files changed, 459 insertions(+), 9 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/30/19730/1 diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/visitor/FunctionCardinalityInferenceVisitor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/visitor/FunctionCardinalityInferenceVisitor.java new file mode 100644 index 0000000..03ef29e --- /dev/null +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/visitor/FunctionCardinalityInferenceVisitor.java @@ -0,0 +1,61 @@ +/* + * 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.asterix.optimizer.rules.visitor; + +import org.apache.asterix.om.base.AInt64; +import org.apache.asterix.om.constants.AsterixConstantValue; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; +import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression; +import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.CardinalityInferenceVisitor; + +public class FunctionCardinalityInferenceVisitor extends CardinalityInferenceVisitor { + + private FunctionCardinalityInferenceVisitor() { + super(); + } + + public static boolean isCardinalityZeroOrOne(ILogicalOperator operator) throws AlgebricksException { + FunctionCardinalityInferenceVisitor visitor = new FunctionCardinalityInferenceVisitor(); + long cardinality = operator.accept(visitor, null); + return cardinality == ZERO_OR_ONE || cardinality == ONE; + } + + @Override + public Long visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException { + // While translation a limit expression is encapsulated as a switch-case expression. + // switch-case(treat-as-integer(user_value_expr) > 0, true, treat-as-integer(user_value_expr), 0) + // Here we extract the user_value_expr from the switch-case expression + ScalarFunctionCallExpression inputExpr = (ScalarFunctionCallExpression) op.getMaxObjects().getValue(); + ILogicalExpression expr = ((ScalarFunctionCallExpression) inputExpr.getArguments().get(2).getValue()) + .getArguments().get(0).getValue(); + if (expr.getExpressionTag() == LogicalExpressionTag.CONSTANT) { + AsterixConstantValue constantValue = (AsterixConstantValue) ((ConstantExpression) expr).getValue(); + if (constantValue.getObject() instanceof AInt64 + && ((AInt64) constantValue.getObject()).getLongValue() <= 1) { + return ZERO_OR_ONE; + } + } + return adjustCardinalityForTupleReductionOperator(op.getInputs().get(0).getValue().accept(this, arg)); + } +} diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java index dcfd810..b50a911 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java @@ -48,6 +48,8 @@ import org.apache.asterix.active.EntityId; import org.apache.asterix.active.IActiveEntityEventsListener; import org.apache.asterix.active.NoRetryPolicyFactory; +import org.apache.asterix.algebra.base.ILangExpressionToPlanTranslator; +import org.apache.asterix.algebra.base.ILangExpressionToPlanTranslatorFactory; import org.apache.asterix.algebra.extension.ExtensionStatement; import org.apache.asterix.api.common.APIFramework; import org.apache.asterix.api.http.server.AbstractQueryApiServlet; @@ -223,6 +225,7 @@ import org.apache.asterix.om.types.IAType; import org.apache.asterix.om.types.TypeSignature; import org.apache.asterix.om.utils.RecordUtil; +import org.apache.asterix.optimizer.rules.visitor.FunctionCardinalityInferenceVisitor; import org.apache.asterix.runtime.fulltext.AbstractFullTextFilterDescriptor; import org.apache.asterix.runtime.fulltext.FullTextConfigDescriptor; import org.apache.asterix.runtime.fulltext.StopwordsFullTextFilterDescriptor; @@ -258,6 +261,9 @@ import org.apache.hyracks.algebricks.common.utils.Pair; import org.apache.hyracks.algebricks.common.utils.Triple; import org.apache.hyracks.algebricks.core.algebra.base.Counter; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil; @@ -3344,6 +3350,10 @@ } else { List<Pair<VarIdentifier, TypeExpression>> paramList = cfs.getParameters(); int paramCount = paramList.size(); + if (cfs.isTransform() && paramCount != 1) { + throw new CompilationException(ErrorCode.INVALID_TRANSFORM_FUNCTION, sourceLoc, + "Transform function should have exactly one parameter"); + } List<VarIdentifier> paramVars = new ArrayList<>(paramCount); List<String> paramNames = new ArrayList<>(paramCount); for (Pair<VarIdentifier, TypeExpression> paramPair : paramList) { @@ -3370,11 +3380,19 @@ metadataProvider.setDefaultNamespace(ns); LangRewritingContext langRewritingContext = createLangRewritingContext(metadataProvider, fdList, null, null, warningCollector, wrappedQuery.getVarCounter()); - apiFramework.reWriteQuery(langRewritingContext, wrappedQuery, sessionOutput, false, false, - Collections.emptyList()); + List<VarIdentifier> externalVars = new ArrayList<>(); + Pair<IReturningStatement, Integer> rewrittenQuery = apiFramework.reWriteQuery(langRewritingContext, + wrappedQuery, sessionOutput, false, true, externalVars); List<List<DependencyFullyQualifiedName>> dependencies = FunctionUtil.getFunctionDependencies(metadataProvider, fd, queryRewriter); + if (cfs.isTransform()) { + if (!dependencies.get(0).isEmpty()) { + throw new CompilationException(ErrorCode.INVALID_TRANSFORM_FUNCTION, sourceLoc, + "Transform function definition can not use collections/views"); + } + validateTransformFunction(metadataProvider, rewrittenQuery, sourceLoc); + } appCtx.getReceptionist().ensureAuthorized(requestParameters, metadataProvider); newInlineTypes = Collections.emptyMap(); @@ -3419,6 +3437,31 @@ } } + private void validateTransformFunction(MetadataProvider metadataProvider, + Pair<IReturningStatement, Integer> rewrittenResult, SourceLocation sourceLoc) throws AlgebricksException { + ILangExpressionToPlanTranslatorFactory translatorFactory = + compilationProvider.getExpressionToPlanTranslatorFactory(); + ILangExpressionToPlanTranslator t = + translatorFactory.createExpressionToPlanTranslator(metadataProvider, rewrittenResult.second, null); + org.apache.asterix.translator.ResultMetadata resultMetadata = + new org.apache.asterix.translator.ResultMetadata(sessionOutput.config().fmt()); + ILogicalPlan plan = t.translate((Query) rewrittenResult.first, null, null, resultMetadata); + if (plan.getRoots().size() != 1) { + throw new CompilationException(ErrorCode.INVALID_TRANSFORM_FUNCTION, sourceLoc, + "Transform function cannot have more than one root"); + } + ILogicalOperator op = plan.getRoots().get(0).getValue().getInputs().get(0).getValue(); + if (op.getOperatorTag() == LogicalOperatorTag.AGGREGATE) { + if (!FunctionCardinalityInferenceVisitor.isCardinalityZeroOrOne(op.getInputs().get(0).getValue())) { + throw new CompilationException(ErrorCode.INVALID_TRANSFORM_FUNCTION, sourceLoc, + "Transform function cannot return more than one row"); + } + } else { + throw new CompilationException(ErrorCode.INVALID_TRANSFORM_FUNCTION, sourceLoc, + "Transform function should always contain a query"); + } + } + private Triple<TypeSignature, TypeSignature, Datatype> translateFunctionParameterType( FunctionSignature functionSignature, int paramIdx, TypeExpression paramTypeExpr, SourceLocation sourceLoc, MetadataProvider metadataProvider, MetadataTransactionContext mdTxnCtx) throws AlgebricksException { diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.000.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.000.ddl.sqlpp new file mode 100644 index 0000000..39b0abd --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.000.ddl.sqlpp @@ -0,0 +1,31 @@ +/* + * 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 T1 AS { + a: int32, + b: int32 +}; + +CREATE COLLECTION test_collection(T1) PRIMARY KEY a; + +CREATE VIEW test_view AS + SELECT * FROM test_collection; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.001.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.001.ddl.sqlpp new file mode 100644 index 0000000..07f2fb1 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.001.ddl.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; + +-- Fail: More than one argument + +CREATE TRANSFORM FUNCTION transformTest(a, b) { + SELECT * FROM [{"a": 1, "b": 2}] t +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.002.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.002.ddl.sqlpp new file mode 100644 index 0000000..61696ad --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.002.ddl.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; + +-- Fail: Less than one argument + +CREATE TRANSFORM FUNCTION transformTest() { + SELECT * FROM [{"a": 1, "b": 2}] t +}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.003.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.003.ddl.sqlpp new file mode 100644 index 0000000..dc1a277 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.003.ddl.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; + +-- Fail: Using a collection in the definition + +CREATE TRANSFORM FUNCTION transformTest(doc) { + SELECT count(*) as count FROM test_collection +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.004.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.004.ddl.sqlpp new file mode 100644 index 0000000..7ad55bd --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.004.ddl.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; + +-- Fail: Using a view in the definition + +CREATE TRANSFORM FUNCTION transformTest(doc) { + SELECT count(*) FROM test_view +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.005.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.005.ddl.sqlpp new file mode 100644 index 0000000..9e4e7b9 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/negative/transform.005.ddl.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. + */ +drop dataverse test if exists; +create dataverse test; +use test; + +CREATE TRANSFORM FUNCTION transformTest(doc) { + SELECT * FROM [doc] d UNNEST d.a +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.000.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.000.ddl.sqlpp new file mode 100644 index 0000000..39b0abd --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.000.ddl.sqlpp @@ -0,0 +1,31 @@ +/* + * 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 T1 AS { + a: int32, + b: int32 +}; + +CREATE COLLECTION test_collection(T1) PRIMARY KEY a; + +CREATE VIEW test_view AS + SELECT * FROM test_collection; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.001.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.001.ddl.sqlpp new file mode 100644 index 0000000..0ab3ace --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.001.ddl.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; + +-- Fail: More than one argument + +CREATE TRANSFORM FUNCTION transformTest1(doc) { + SELECT count(*) as count FROM [doc] t UNNEST t.a +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.002.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.002.ddl.sqlpp new file mode 100644 index 0000000..6d55991 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.002.ddl.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; + +-- Fail: Less than one argument + +CREATE TRANSFORM FUNCTION transformTest2(doc) { + SELECT (SELECT * FROM [doc] t UNNEST t.a) as tt +}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.003.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.003.ddl.sqlpp new file mode 100644 index 0000000..c38bd72 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.003.ddl.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; + +-- Fail: Using a collection in the definition + +CREATE TRANSFORM FUNCTION transformTest3(doc) { + SELECT * FROM [doc] t UNNEST t.a LIMIT 1 +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.004.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.004.ddl.sqlpp new file mode 100644 index 0000000..10cfb4e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.004.ddl.sqlpp @@ -0,0 +1,28 @@ +/* + * 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; + +-- Fail: Using a view in the definition + +CREATE TRANSFORM FUNCTION transformTest4(cust) { + SELECT VALUE c + FROM [cust] AS c + WHERE c.address.zipcode IS NOT MISSING + LIMIT 1 +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.005.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.005.ddl.sqlpp new file mode 100644 index 0000000..77153ce --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/function/transform/positive/transform.005.ddl.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; + +CREATE TRANSFORM FUNCTION transformTest5(ord) { + SELECT o.orderno, i.itemno, i.qty AS item_qty, i.price AS item_price + FROM [ord] AS o UNNEST o.items AS i + LIMIT 1 +}; 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 10e8302..9f5f8d1 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml @@ -14229,6 +14229,21 @@ <output-dir compare="Text">drop_if_exists</output-dir> </compilation-unit> </test-case> + <test-case FilePath="function/transform"> + <compilation-unit name="negative"> + <output-dir compare="Text">negative</output-dir> + <expected-error>ASX1223: Failed to create transform function. Encountered error: 'Transform function should have exactly one parameter'</expected-error> + <expected-error>ASX1223: Failed to create transform function. Encountered error: 'Transform function should have exactly one parameter'</expected-error> + <expected-error>ASX1223: Failed to create transform function. Encountered error: 'Transform function definition can not use collections/views'</expected-error> + <expected-error>ASX1223: Failed to create transform function. Encountered error: 'Transform function definition can not use collections/views'</expected-error> + <expected-error>ASX1223: Failed to create transform function. Encountered error: 'Transform function cannot return more than one row'</expected-error> + </compilation-unit> + </test-case> + <test-case FilePath="function/transform"> + <compilation-unit name="positive"> + <output-dir compare="Text">positive</output-dir> + </compilation-unit> + </test-case> </test-group> <test-group name="feeds"> <test-case FilePath="feeds"> diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java index 463695e..260617a 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java @@ -328,6 +328,7 @@ CANNOT_TRUNCATE_DATASET_TYPE(1220), NO_VALID_AUTHENTICATION_PARAMS_PROVIDED(1221), NO_VALID_AUTHENTICATION_PARAMS_PROVIDED_TO_IMPERSONATE_SERVICE_ACCOUNT(1222), + INVALID_TRANSFORM_FUNCTION(1223), // Feed errors DATAFLOW_ILLEGAL_STATE(3001), diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties index df08016..68c23c7 100644 --- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties +++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties @@ -330,6 +330,7 @@ 1220 = Cannot truncate %1$s '%2$s' 1221 = No valid authentication parameters were provided 1222 = No valid authentication parameters were provided to impersonate service account +1223 = Failed to create transform function. Encountered error: '%1$s' # Feed Errors 3001 = Illegal state. diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java index 6b25b1f..21d9ea2 100644 --- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java +++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java @@ -84,15 +84,15 @@ * 5. the cardinality is some unknown value. */ public class CardinalityInferenceVisitor implements ILogicalOperatorVisitor<Long, Void> { - private static final long ZERO_OR_ONE = 0L; - private static final long ONE = 1L; - private static final long ZERO_OR_ONE_GROUP = 2L; - private static final long ONE_GROUP = 3L; - private static final long UNKNOWN = 100L; // so it fits into the auto-boxing cache + protected static final long ZERO_OR_ONE = 0L; + protected static final long ONE = 1L; + protected static final long ZERO_OR_ONE_GROUP = 2L; + protected static final long ONE_GROUP = 3L; + protected static final long UNKNOWN = 100L; // so it fits into the auto-boxing cache private final Set<LogicalVariable> keyVariables = new HashSet<>(); - private CardinalityInferenceVisitor() { + public CardinalityInferenceVisitor() { } @Override @@ -379,7 +379,7 @@ } // For operators including SELECT and LIMIT. - private long adjustCardinalityForTupleReductionOperator(long inputCardinality) { + protected long adjustCardinalityForTupleReductionOperator(long inputCardinality) { if (inputCardinality == ONE) { return ZERO_OR_ONE; } -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19730 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: I524cbfb6685bd3c7ed269c2db48482e5aba1ce6c Gerrit-Change-Number: 19730 Gerrit-PatchSet: 1 Gerrit-Owner: Peeyush Gupta <[email protected]> Gerrit-MessageType: newchange
