[NO ISSUE][API] Support sql-compat parameter in QueryServiceServlet
- user model changes: no
- storage format changes: no
- interface changes: yes
Details:
- QueryServiceServlet supports 'sql-compat' parameter which indicates
that a query should be evaluated in SQL-compatible mode
Change-Id: I3e0cfe3839e4bbdf1827cedf5f0abfaa536f78ff
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/13645
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
index ab1061f..c6022eb 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
@@ -78,6 +78,8 @@
boolean isPrintSignature();
+ boolean isSQLCompatMode();
+
/**
* @return canonical name of the default dataverse for this statement
*/
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 53137e6..f2bb66d 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
@@ -150,7 +150,7 @@
SqlppExpressionToPlanTranslator.REWRITE_IN_AS_OR_OPTION, "hash_merge", "output-record-type",
DisjunctivePredicateToJoinRule.REWRITE_OR_AS_JOIN_OPTION,
SetAsterixPhysicalOperatorsRule.REWRITE_ATTEMPT_BATCH_ASSIGN,
- EquivalenceClassUtils.REWRITE_INTERNAL_QUERYUID_PK);
+ EquivalenceClassUtils.REWRITE_INTERNAL_QUERYUID_PK, SqlppQueryRewriter.SQL_COMPAT_OPTION);
private final IRewriterFactory rewriterFactory;
private final IAstPrintVisitorFactory astPrintVisitorFactory;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
index e6ba15f..5bcde3d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
@@ -140,11 +140,13 @@
Map<String, String> optionalParameters, Map<String, byte[]> statementParameters, INCServiceContext ncCtx,
MessageFuture responseFuture, ILangExtension.Language queryLanguage, String handleUrl,
int stmtCategoryRestrictionMask, boolean forceDropDataset) {
- return new ExecuteStatementRequestMessage(ncCtx.getNodeId(), responseFuture.getFutureId(), queryLanguage,
- statementsText, sessionOutput.config(), resultProperties.getNcToCcResultProperties(),
- param.getClientContextID(), param.getDataverse(), handleUrl, optionalParameters, statementParameters,
- param.isMultiStatement(), param.getProfileType(), stmtCategoryRestrictionMask, requestReference,
- forceDropDataset);
+ ExecuteStatementRequestMessage requestMessage = new ExecuteStatementRequestMessage(ncCtx.getNodeId(),
+ responseFuture.getFutureId(), queryLanguage, statementsText, sessionOutput.config(),
+ resultProperties.getNcToCcResultProperties(), param.getClientContextID(), param.getDataverse(),
+ handleUrl, optionalParameters, statementParameters, param.isMultiStatement(), param.getProfileType(),
+ stmtCategoryRestrictionMask, requestReference, forceDropDataset);
+ requestMessage.setSQLCompatMode(param.isSQLCompatMode());
+ return requestMessage;
}
private void cancelQuery(INCMessageBroker messageBroker, String nodeId, String uuid, String clientContextID,
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
index 084bca7..df068c0 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
@@ -79,7 +79,8 @@
PROFILE("profile"),
SIGNATURE("signature"),
MULTI_STATEMENT("multi-statement"),
- MAX_WARNINGS("max-warnings");
+ MAX_WARNINGS("max-warnings"),
+ SQL_COMPAT("sql-compat");
private final String str;
@@ -142,6 +143,7 @@
private boolean isCSVWithHeader = false;
private boolean signature = true;
private boolean multiStatement = true;
+ private boolean sqlCompatMode = false;
private long timeout = TimeUnit.MILLISECONDS.toMillis(Long.MAX_VALUE);
private long maxResultReads = 1L;
private long maxWarnings = 0L;
@@ -358,6 +360,14 @@
this.multiStatement = multiStatement;
}
+ public boolean isSQLCompatMode() {
+ return sqlCompatMode;
+ }
+
+ public void setSQLCompatMode(boolean sqlCompatMode) {
+ this.sqlCompatMode = sqlCompatMode;
+ }
+
public void setMaxWarnings(long maxWarnings) {
this.maxWarnings = maxWarnings;
}
@@ -391,6 +401,7 @@
object.put("parseOnly", parseOnly);
object.put("readOnly", readOnly);
object.put("maxWarnings", maxWarnings);
+ object.put("sqlCompat", sqlCompatMode);
if (statementParams != null) {
for (Map.Entry<String, JsonNode> statementParam : statementParams.entrySet()) {
object.set('$' + statementParam.getKey(), statementParam.getValue());
@@ -474,6 +485,7 @@
setJob(parseBoolean(req, Parameter.JOB.str(), valGetter, isJob()));
setSignature(parseBoolean(req, Parameter.SIGNATURE.str(), valGetter, isSignature()));
setClientType(parseIfExists(req, Parameter.CLIENT_TYPE.str(), valGetter, getClientType(), clientTypes::get));
+ setSQLCompatMode(parseBoolean(req, Parameter.SQL_COMPAT.str(), valGetter, isSQLCompatMode()));
}
protected void setExtraParams(JsonNode jsonRequest) throws HyracksDataException {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index b46c299..9f83aa8 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -519,6 +519,7 @@
resultProperties, stats, statementProperties, null, param.getClientContextID(), param.getDataverse(),
optionalParameters, stmtParams, param.isMultiStatement(), stmtCategoryRestriction);
requestParameters.setPrintSignature(param.isSignature());
+ requestParameters.setSQLCompatMode(param.isSQLCompatMode());
return requestParameters;
}
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
index fa05870..0a5e033 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
@@ -66,7 +66,7 @@
import org.apache.logging.log4j.Logger;
public class ExecuteStatementRequestMessage implements ICcAddressedMessage {
- private static final long serialVersionUID = 3L;
+ private static final long serialVersionUID = 4L;
private static final Logger LOGGER = LogManager.getLogger();
//TODO: Make configurable: https://issues.apache.org/jira/browse/ASTERIXDB-2062
public static final long DEFAULT_NC_TIMEOUT_MILLIS = TimeUnit.MILLISECONDS.toMillis(Long.MAX_VALUE);
@@ -89,6 +89,7 @@
private final IRequestReference requestReference;
private final boolean forceDropDataset;
private final boolean skipAdmissionPolicy;
+ private boolean sqlCompatMode;
public ExecuteStatementRequestMessage(String requestNodeId, long requestMessageId, ILangExtension.Language lang,
String statementsText, SessionConfig sessionConfig, ResultProperties resultProperties,
@@ -126,6 +127,14 @@
this.defaultDataverseName = defaultDataverseName;
}
+ public boolean isSQLCompatMode() {
+ return sqlCompatMode;
+ }
+
+ public void setSQLCompatMode(boolean sqlCompatMode) {
+ this.sqlCompatMode = sqlCompatMode;
+ }
+
@Override
public void handle(ICcApplicationContext ccAppCtx) throws HyracksDataException, InterruptedException {
ICCServiceContext ccSrvContext = ccAppCtx.getServiceContext();
@@ -166,10 +175,8 @@
final IStatementExecutor.Stats stats = new IStatementExecutor.Stats();
stats.setProfileType(profileType);
Map<String, IAObject> stmtParams = RequestParameters.deserializeParameterValues(statementParameters);
- final IRequestParameters requestParameters = new RequestParameters(requestReference, statementsText, null,
- resultProperties, stats, statementProperties, outMetadata, clientContextID, defaultDataverseName,
- optionalParameters, stmtParams, multiStatement, statementCategoryRestrictionMask, forceDropDataset,
- skipAdmissionPolicy);
+ final IRequestParameters requestParameters =
+ createRequestParameters(statementProperties, stmtParams, outMetadata, stats);
translator.compileAndExecute(ccApp.getHcc(), requestParameters);
translator.getWarnings(warnings, maxWarnings - warnings.size());
stats.updateTotalWarningsCount(parserTotalWarningsCount);
@@ -194,6 +201,17 @@
}
}
+ protected IRequestParameters createRequestParameters(IStatementExecutor.StatementProperties statementProperties,
+ Map<String, IAObject> stmtParams, IStatementExecutor.ResultMetadata outMetadata,
+ IStatementExecutor.Stats stats) {
+ RequestParameters requestParameters = new RequestParameters(requestReference, statementsText, null,
+ resultProperties, stats, statementProperties, outMetadata, clientContextID, defaultDataverseName,
+ optionalParameters, stmtParams, multiStatement, statementCategoryRestrictionMask, forceDropDataset,
+ skipAdmissionPolicy);
+ requestParameters.setSQLCompatMode(sqlCompatMode);
+ return requestParameters;
+ }
+
protected CCMessageBroker getMessageBroker(ICcApplicationContext ccAppCtx) {
ICCServiceContext ccSrvContext = ccAppCtx.getServiceContext();
return (CCMessageBroker) ccSrvContext.getMessageBroker();
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 0529c15..70ac386 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
@@ -158,6 +158,7 @@
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.lang.common.util.ViewUtil;
+import org.apache.asterix.lang.sqlpp.rewrites.SqlppQueryRewriter;
import org.apache.asterix.metadata.IDatasetDetails;
import org.apache.asterix.metadata.MetadataManager;
import org.apache.asterix.metadata.MetadataTransactionContext;
@@ -350,7 +351,7 @@
validateOperation(appCtx, activeDataverse, stmt);
MetadataProvider metadataProvider = MetadataProvider.create(appCtx, activeDataverse);
configureMetadataProvider(metadataProvider, config, resultSerializerFactoryProvider, writerFactory,
- outputFile);
+ outputFile, requestParameters, stmt);
IStatementRewriter stmtRewriter = rewriterFactory.createStatementRewriter();
rewriteStatement(stmt, stmtRewriter, metadataProvider); // Rewrite the statement's AST.
Statement.Kind kind = stmt.getKind();
@@ -519,7 +520,10 @@
protected void configureMetadataProvider(MetadataProvider metadataProvider, Map<String, String> config,
IResultSerializerFactoryProvider resultSerializerFactoryProvider, IAWriterFactory writerFactory,
- FileSplit outputFile) {
+ FileSplit outputFile, IRequestParameters requestParameters, Statement statement) {
+ if (statement.getKind() == Statement.Kind.QUERY && requestParameters.isSQLCompatMode()) {
+ metadataProvider.getConfig().put(SqlppQueryRewriter.SQL_COMPAT_OPTION, Boolean.TRUE.toString());
+ }
metadataProvider.getConfig().putAll(config);
metadataProvider.setWriterFactory(writerFactory);
metadataProvider.setResultSerializerFactoryProvider(resultSerializerFactoryProvider);
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
index 7b634bd..8bc6b76 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
@@ -64,6 +64,7 @@
private final boolean forceDropDataset;
private final boolean skipAdmissionPolicy;
private boolean printSignature;
+ private boolean sqlCompatMode;
public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
@@ -199,6 +200,15 @@
this.printSignature = printSignature;
}
+ @Override
+ public boolean isSQLCompatMode() {
+ return sqlCompatMode;
+ }
+
+ public void setSQLCompatMode(boolean sqlCompatMode) {
+ this.sqlCompatMode = sqlCompatMode;
+ }
+
public static Map<String, byte[]> serializeParameterValues(Map<String, JsonNode> inParams,
SessionConfig.OutputFormat format) throws HyracksDataException {
if (inParams == null || inParams.isEmpty()) {
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index 7b2e5e3..b6fd9da 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -100,6 +100,10 @@
public static final String INLINE_WITH_OPTION = "inline_with";
private static final boolean INLINE_WITH_OPTION_DEFAULT = true;
+
+ public static final String SQL_COMPAT_OPTION = "sql_compat";
+ private static final boolean SQL_COMPAT_OPTION_DEFAULT = false;
+
private final IParserFactory parserFactory;
private SqlppFunctionBodyRewriter functionAndViewBodyRewriter;
private IReturningStatement topStatement;