Yingyi Bu has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/1584

Change subject: Add query parameter validation.
......................................................................

Add query parameter validation.

- Automatically adjust query parameters such as compiler.joinmemory
  compiler.sortmemory, compiler.groupmemory if they're too small;
- Validate if query parameters specified in a query are supported.

Change-Id: Ia9e2df274a0c5cf598da6c37d0241b6b9d35c84d
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/FuzzyUtils.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/unsupported_parameter/unsupported_parameter.1.query.sqlpp
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
M 
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
M 
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
M asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
7 files changed, 79 insertions(+), 13 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/84/1584/1

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/FuzzyUtils.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/FuzzyUtils.java
index 42a9c25..f888ee0 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/FuzzyUtils.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/FuzzyUtils.java
@@ -40,8 +40,8 @@
     private final static float JACCARD_DEFAULT_SIM_THRESHOLD = .8f;
     private final static int EDIT_DISTANCE_DEFAULT_SIM_THRESHOLD = 1;
 
-    private final static String SIM_FUNCTION_PROP_NAME = "simfunction";
-    private final static String SIM_THRESHOLD_PROP_NAME = "simthreshold";
+    public final static String SIM_FUNCTION_PROP_NAME = "simfunction";
+    public final static String SIM_THRESHOLD_PROP_NAME = "simthreshold";
 
     public final static String JACCARD_FUNCTION_NAME = "jaccard";
     public final static String EDIT_DISTANCE_FUNCTION_NAME = "edit-distance";
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
index 0759599..4ec2e2a 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
@@ -35,9 +35,10 @@
 import org.apache.asterix.common.config.CompilerProperties;
 import org.apache.asterix.common.config.ExternalProperties;
 import org.apache.asterix.common.config.OptimizationConfUtil;
-import org.apache.hyracks.control.common.config.OptionTypes;
 import org.apache.asterix.common.exceptions.ACIDException;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.utils.Job;
 import org.apache.asterix.common.utils.Job.SubmissionMode;
 import org.apache.asterix.compiler.provider.ILangCompilationProvider;
@@ -47,8 +48,10 @@
 import 
org.apache.asterix.dataflow.data.common.MergeAggregationExpressionFactory;
 import org.apache.asterix.dataflow.data.common.MissableTypeComputer;
 import org.apache.asterix.dataflow.data.common.PartialAggregationTypeComputer;
+import org.apache.asterix.external.feed.watch.FeedActivityDetails;
 import org.apache.asterix.formats.base.IDataFormat;
 import org.apache.asterix.jobgen.QueryLogicalExpressionJobGen;
+import org.apache.asterix.lang.aql.statement.SubscribeFeedStatement;
 import org.apache.asterix.lang.common.base.IAstPrintVisitorFactory;
 import org.apache.asterix.lang.common.base.IQueryRewriter;
 import org.apache.asterix.lang.common.base.IReturningStatement;
@@ -57,14 +60,16 @@
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.util.FunctionUtil;
 import org.apache.asterix.metadata.declared.MetadataProvider;
+import org.apache.asterix.optimizer.base.FuzzyUtils;
 import org.apache.asterix.runtime.job.listener.JobEventListenerFactory;
 import org.apache.asterix.runtime.utils.AppContextInfo;
 import 
org.apache.asterix.transaction.management.service.transaction.JobIdFactory;
+import org.apache.asterix.translator.SessionConfig;
 import org.apache.asterix.translator.CompiledStatements.ICompiledDmlStatement;
 import org.apache.asterix.translator.IStatementExecutor.Stats;
 import org.apache.asterix.utils.ResourceUtils;
-import org.apache.asterix.translator.SessionConfig;
 import 
org.apache.hyracks.algebricks.common.constraints.AlgebricksAbsolutePartitionConstraint;
 import 
org.apache.hyracks.algebricks.common.constraints.AlgebricksPartitionConstraint;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -74,12 +79,12 @@
 import org.apache.hyracks.algebricks.compiler.api.ICompilerFactory;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.ExpressionRuntimeProvider;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IConflictingTypeResolver;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionEvalSizeComputer;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionTypeComputer;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IMergeAggregationExpressionFactory;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IMissableTypeComputer;
-import 
org.apache.hyracks.algebricks.core.algebra.expressions.ExpressionRuntimeProvider;
 import 
org.apache.hyracks.algebricks.core.algebra.prettyprint.AlgebricksAppendable;
 import 
org.apache.hyracks.algebricks.core.algebra.prettyprint.LogicalOperatorPrettyPrintVisitor;
 import org.apache.hyracks.algebricks.core.algebra.prettyprint.PlanPlotter;
@@ -90,18 +95,33 @@
 import org.apache.hyracks.api.client.IClusterInfoCollector;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.api.client.NodeControllerInfo;
+import org.apache.hyracks.api.config.IOptionType;
 import org.apache.hyracks.api.exceptions.HyracksException;
 import org.apache.hyracks.api.job.JobId;
 import org.apache.hyracks.api.job.JobSpecification;
+import org.apache.hyracks.control.common.config.OptionTypes;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.hyracks.api.config.IOptionType;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * Provides helper methods for compilation of a query into a JobSpec and 
submission
  * to Hyracks through the Hyracks client interface.
  */
 public class APIFramework {
+
+    private static final int MIN_FRAME_LIMIT_FOR_SORT_AND_GROUP_BY = 3;
+
+    private static final int MIN_FRAME_LIMIT_FOR_JOIN = 5;
+
+    // A white list of supported configurable parameters.
+    private static final Set<String> configurableParameterNames = 
ImmutableSet.of(
+            CompilerProperties.COMPILER_JOINMEMORY_KEY, 
CompilerProperties.COMPILER_GROUPMEMORY_KEY,
+            CompilerProperties.COMPILER_SORTMEMORY_KEY, 
CompilerProperties.COMPILER_PARALLELISM_KEY,
+            FunctionUtil.IMPORT_PRIVATE_FUNCTIONS, 
FuzzyUtils.SIM_FUNCTION_PROP_NAME,
+            FuzzyUtils.SIM_THRESHOLD_PROP_NAME, 
SubscribeFeedStatement.WAIT_FOR_COMPLETION,
+            FeedActivityDetails.FEED_POLICY_NAME, 
FeedActivityDetails.COLLECT_LOCATIONS, "inline_with", "hash_merge",
+            "output-record-type");
 
     private final IRewriterFactory rewriterFactory;
     private final IAstPrintVisitorFactory astPrintVisitorFactory;
@@ -215,12 +235,13 @@
         CompilerProperties compilerProperties = 
AppContextInfo.INSTANCE.getCompilerProperties();
         int frameSize = compilerProperties.getFrameSize();
         Map<String, String> querySpecificConfig = metadataProvider.getConfig();
+        validateConfig(querySpecificConfig); // Validates the user-overridden 
query parameters.
         int sortFrameLimit = 
getFrameLimit(querySpecificConfig.get(CompilerProperties.COMPILER_SORTMEMORY_KEY),
-                compilerProperties.getSortMemorySize(), frameSize);
+                compilerProperties.getSortMemorySize(), frameSize, false);
         int groupFrameLimit = 
getFrameLimit(querySpecificConfig.get(CompilerProperties.COMPILER_GROUPMEMORY_KEY),
-                compilerProperties.getGroupMemorySize(), frameSize);
+                compilerProperties.getGroupMemorySize(), frameSize, false);
         int joinFrameLimit = 
getFrameLimit(querySpecificConfig.get(CompilerProperties.COMPILER_JOINMEMORY_KEY),
-                compilerProperties.getJoinMemorySize(), frameSize);
+                compilerProperties.getJoinMemorySize(), frameSize, true);
         
OptimizationConfUtil.getPhysicalOptimizationConfig().setFrameSize(frameSize);
         
OptimizationConfUtil.getPhysicalOptimizationConfig().setMaxFramesExternalSort(sortFrameLimit);
         
OptimizationConfUtil.getPhysicalOptimizationConfig().setMaxFramesExternalGroupBy(groupFrameLimit);
@@ -450,11 +471,14 @@
     }
 
     // Gets the frame limit.
-    private int getFrameLimit(String parameter, long memBudgetInConfiguration, 
int frameSize) {
+    private int getFrameLimit(String parameter, long memBudgetInConfiguration, 
int frameSize, boolean joinOp)
+            throws AlgebricksException {
         IOptionType<Long> longBytePropertyInterpreter = 
OptionTypes.LONG_BYTE_UNIT;
         long memBudget =
                 parameter == null ? memBudgetInConfiguration : 
longBytePropertyInterpreter.parse(parameter);
-        return (int) (memBudget / frameSize);
+        int frameLimit = (int) (memBudget / frameSize);
+        int minframeLimit = joinOp ? MIN_FRAME_LIMIT_FOR_JOIN : 
MIN_FRAME_LIMIT_FOR_SORT_AND_GROUP_BY;
+        return Math.max(frameLimit, minframeLimit);
     }
 
     // Gets the parallelism parameter.
@@ -462,4 +486,12 @@
         IOptionType<Integer> integerIPropertyInterpreter = OptionTypes.INTEGER;
         return parameter == null ? parallelismInConfiguration : 
integerIPropertyInterpreter.parse(parameter);
     }
+
+    private void validateConfig(Map<String, String> config) throws 
AlgebricksException {
+        for (String parameterName : config.keySet()) {
+            if (!configurableParameterNames.contains(parameterName)) {
+                throw 
AsterixException.create(ErrorCode.COMPILATION_UNSUPPORTED_QUERY_PARAMETER, 
parameterName);
+            }
+        }
+    }
 }
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/unsupported_parameter/unsupported_parameter.1.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/unsupported_parameter/unsupported_parameter.1.query.sqlpp
new file mode 100644
index 0000000..b0c83c4
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/unsupported_parameter/unsupported_parameter.1.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.
+ */
+
+SET `compiler.joinmem` "4MB"
+
+SELECT 1;
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 d26e0d5..40c8c80 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -3276,6 +3276,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="misc">
+      <compilation-unit name="unsupported_parameter">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>Query parameter compiler.joinmem is not 
supported</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
       <compilation-unit name="uuid">
         <output-dir compare="Text">uuid</output-dir>
       </compilation-unit>
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
index 7a73705..7cb7d8a 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
@@ -18,9 +18,9 @@
  */
 package org.apache.asterix.common.exceptions;
 
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-
 import java.io.Serializable;
+
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 
 public class AsterixException extends AlgebricksException {
     private static final long serialVersionUID = 1L;
@@ -34,6 +34,10 @@
 
     }
 
+    public static AsterixException create(int errorCode, Serializable... 
params) {
+        return new AsterixException(errorCode, params);
+    }
+
     public AsterixException(Throwable cause) {
         super(cause);
     }
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 8f859c7..9717fe5 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
@@ -85,6 +85,7 @@
     public static final int COMPILATION_AQLPLUS_NO_SUCH_JOIN_TYPE = 1025;
     public static final int COMPILATION_FUNC_EXPRESSION_CANNOT_UTILIZE_INDEX = 
1026;
     public static final int 
COMPILATION_DATASET_TYPE_DOES_NOT_HAVE_PRIMARY_INDEX = 1027;
+    public static final int COMPILATION_UNSUPPORTED_QUERY_PARAMETER = 1028;
 
     // Feed errors
     public static final int 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 bf9c6f9..55c4de5 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -71,6 +71,7 @@
 1025 = There is no such join type in AQL+
 1026 = The given function expression %1$s cannot utilize index
 1027 = Dataset of type %1$s doesn't have a primary index
+1028 = Query parameter %1$s is not supported
 
 # Feed Errors
 3001 = Illegal state.

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/1584
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9e2df274a0c5cf598da6c37d0241b6b9d35c84d
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Yingyi Bu <[email protected]>

Reply via email to