[NO ISSUE][COMP] Change typed view configuration syntax
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- Change how typed view configuration options are
specified in CREATE VIEW statement. Use sequence
of identifier / value pairs instead of WITH clause
- Update testcases to use the new syntax
Change-Id: I42fa7a5e45dced37857a9c08ebeafa8410d46476
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/12906
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: 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-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.1.ddl.sqlpp
index 406e53a..2e1f472 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.1.ddl.sqlpp
@@ -53,20 +53,20 @@
from t1
;
-/* custom date/time format (with clause) */
+/* custom date/time format */
create view v3_datetime_format(
c_id int32,
c_datetime datetime, c_date date, c_time time
-) default null with {
- 'datetime':'MM/DD/YYYY hh:mm:ss.nnna',
- 'date':'MM/DD/YYYY',
- 'time':'hh:mm:ss.nnna'
-} as t2;
+) default null
+ datetime 'MM/DD/YYYY hh:mm:ss.nnna'
+ date 'MM/DD/YYYY'
+ time 'hh:mm:ss.nnna'
+as t2;
-/* custom date format (with clause) */
+/* custom date format */
create view v4_date_format_only(
c_id int32,
c_datetime datetime, c_date date, c_time time
-) default null with {
- 'date':'MM/DD/YYYY'
-} as t2;
+) default null
+ date 'MM/DD/YYYY'
+as t2;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp
index 6e90398..d03801e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp
@@ -28,8 +28,8 @@
create view v1_invalid_datetime_format(
c_id int32,
c_datetime datetime, c_date date, c_time time
-) default null with {
- 'datetime':'XX.ZZ.11',
- 'date':'XX.ZZ.22',
- 'time':'XX.ZZ.33'
-} as t1;
+) default null
+ datetime 'XX.ZZ.11'
+ date 'XX.ZZ.22'
+ time 'XX.ZZ.33'
+as t1;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.7.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.7.ddl.sqlpp
index 6197dae..2e01c03 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.7.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.7.ddl.sqlpp
@@ -17,15 +17,13 @@
* under the License.
*/
---- Negative: invalid with clause
+--- Negative: invalid view parameter clause
drop dataverse test if exists;
create dataverse test;
create view test.v1(cd date) default null
-with {
- 'date':'YYYY-MM-DD',
- 'date-illegal-property-name':'YYYY-MM-DD'
-}
+ date 'YYYY-MM-DD'
+ date_illegal_property_name 'YYYY-MM-DD'
as
select string(current_date()) cd from range(1,2) r;
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 bdc2603..94c43ed 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -13160,7 +13160,7 @@
<expected-error>ASX1004: Unsupported type: view cannot process input type t1_a (in line 30, at column 1)</expected-error>
<expected-error><![CDATA[ASX1001: Syntax error: In line 25 >>create view test.v1(r bigint, a [bigint]) default null as<< Encountered "[" at column 33]]></expected-error>
<expected-error>ASX1079: Compilation error: Invalid type for field r. The type must allow MISSING and NULL (in line 29, at column 1)</expected-error>
- <expected-error>ASX1001: Syntax error: ASX1059: Field(s) [date-illegal-property-name] unsupported in the with clause (in line 25, at column 1)</expected-error>
+ <expected-error>ASX1001: Syntax error: ASX1092: Parameter date_illegal_property_name cannot be set (in line 25, at column 1)</expected-error>
<expected-error><![CDATA[ASX1001: Syntax error: In line 25 >>create view test.v1(r bigint) as<< Encountered "as" at column 31]]></expected-error>
<source-location>false</source-location>
</compilation-unit>
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateViewStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateViewStatement.java
index 688601c..ae3c50e 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateViewStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateViewStatement.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.common.statement;
+import java.util.Map;
import java.util.Objects;
import org.apache.asterix.common.exceptions.CompilationException;
@@ -26,11 +27,9 @@
import org.apache.asterix.lang.common.base.AbstractStatement;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Statement;
-import org.apache.asterix.lang.common.expression.RecordConstructor;
import org.apache.asterix.lang.common.expression.TypeExpression;
import org.apache.asterix.lang.common.util.ViewUtil;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
-import org.apache.asterix.object.base.AdmObjectNode;
public final class CreateViewStatement extends AbstractStatement {
@@ -44,7 +43,7 @@
private final Expression viewBodyExpression;
- private final AdmObjectNode withObjectNode;
+ private final Map<String, String> viewConfig;
private final Boolean defaultNull;
@@ -53,7 +52,7 @@
private final boolean ifNotExists;
public CreateViewStatement(DataverseName dataverseName, String viewName, TypeExpression itemType, String viewBody,
- Expression viewBodyExpression, Boolean defaultNull, RecordConstructor withRecord, boolean replaceIfExists,
+ Expression viewBodyExpression, Boolean defaultNull, Map<String, String> viewConfig, boolean replaceIfExists,
boolean ifNotExists) throws CompilationException {
this.dataverseName = dataverseName;
this.viewName = Objects.requireNonNull(viewName);
@@ -61,7 +60,7 @@
this.viewBody = Objects.requireNonNull(viewBody);
this.viewBodyExpression = Objects.requireNonNull(viewBodyExpression);
this.defaultNull = defaultNull;
- this.withObjectNode = ViewUtil.validateAndGetWithObjectNode(withRecord, itemType != null);
+ this.viewConfig = ViewUtil.validateViewConfiguration(viewConfig, itemType != null);
this.replaceIfExists = replaceIfExists;
this.ifNotExists = ifNotExists;
}
@@ -115,15 +114,15 @@
}
public String getDatetimeFormat() {
- return withObjectNode.getOptionalString(ViewUtil.DATETIME_PARAMETER_NAME);
+ return viewConfig.get(ViewUtil.DATETIME_PARAMETER_NAME);
}
public String getDateFormat() {
- return withObjectNode.getOptionalString(ViewUtil.DATE_PARAMETER_NAME);
+ return viewConfig.get(ViewUtil.DATE_PARAMETER_NAME);
}
public String getTimeFormat() {
- return withObjectNode.getOptionalString(ViewUtil.TIME_PARAMETER_NAME);
+ return viewConfig.get(ViewUtil.TIME_PARAMETER_NAME);
}
@Override
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ViewUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ViewUtil.java
index dfed99d..3dc08ee 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ViewUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ViewUtil.java
@@ -21,9 +21,9 @@
import java.io.StringReader;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.common.exceptions.ErrorCode;
@@ -37,7 +37,6 @@
import org.apache.asterix.lang.common.expression.CallExpr;
import org.apache.asterix.lang.common.expression.FieldAccessor;
import org.apache.asterix.lang.common.expression.LiteralExpr;
-import org.apache.asterix.lang.common.expression.RecordConstructor;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.literal.NullLiteral;
import org.apache.asterix.lang.common.literal.StringLiteral;
@@ -45,7 +44,6 @@
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.metadata.entities.ViewDetails;
-import org.apache.asterix.object.base.AdmObjectNode;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.ATypeTag;
@@ -63,18 +61,9 @@
public static final String DATE_PARAMETER_NAME = BuiltinType.ADATE.getTypeName();
public static final String TIME_PARAMETER_NAME = BuiltinType.ATIME.getTypeName();
- private static final ARecordType WITH_OBJECT_TYPE_FOR_TYPED_VIEW = getWithObjectTypeForTypedView();
-
private ViewUtil() {
}
- private static ARecordType getWithObjectTypeForTypedView() {
- String[] fieldNames = { DATETIME_PARAMETER_NAME, DATE_PARAMETER_NAME, TIME_PARAMETER_NAME };
- IAType[] fieldTypes = new IAType[fieldNames.length];
- Arrays.fill(fieldTypes, AUnionType.createUnknownableType(BuiltinType.ASTRING));
- return new ARecordType("withObject", fieldNames, fieldTypes, false);
- }
-
public static ViewDecl parseStoredView(DatasetFullyQualifiedName viewName, ViewDetails view,
IParserFactory parserFactory, IWarningCollector warningCollector, SourceLocation sourceLoc)
throws CompilationException {
@@ -138,22 +127,28 @@
}
}
- public static AdmObjectNode validateAndGetWithObjectNode(RecordConstructor withRecord, boolean hasItemType)
+ public static Map<String, String> validateViewConfiguration(Map<String, String> viewConfig, boolean hasItemType)
throws CompilationException {
- if (withRecord == null) {
- return DatasetDeclParametersUtil.EMPTY_WITH_OBJECT;
- }
- AdmObjectNode node = ExpressionUtils.toNode(withRecord);
- if (node.isEmpty()) {
- return DatasetDeclParametersUtil.EMPTY_WITH_OBJECT;
+ if (viewConfig == null) {
+ viewConfig = Collections.emptyMap();
}
if (hasItemType) {
- ConfigurationTypeValidator validator = new ConfigurationTypeValidator();
- validator.validateType(WITH_OBJECT_TYPE_FOR_TYPED_VIEW, node);
- return node;
- } else {
- throw new CompilationException(ErrorCode.COMPILATION_ERROR, "Invalid WITH clause in view definition");
+ for (Map.Entry<String, String> me : viewConfig.entrySet()) {
+ String name = me.getKey();
+ String value = me.getValue();
+ if (DATETIME_PARAMETER_NAME.equals(name) || DATE_PARAMETER_NAME.equals(name)
+ || TIME_PARAMETER_NAME.equals(name)) {
+ if (value == null) {
+ throw new CompilationException(ErrorCode.INVALID_REQ_PARAM_VAL, name, value);
+ }
+ } else {
+ throw new CompilationException(ErrorCode.ILLEGAL_SET_PARAMETER, name);
+ }
+ }
+ } else if (!viewConfig.isEmpty()) {
+ throw new CompilationException(ErrorCode.ILLEGAL_SET_PARAMETER, viewConfig.keySet().iterator().next());
}
+ return viewConfig;
}
public static Expression createTypeConvertExpression(Expression inExpr, IAType targetType,
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 3a29260..0e6bb5e 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -1437,20 +1437,20 @@
Token beginPos = null, endPos = null;
Expression viewBodyExpr = null;
Boolean defaultNull = null;
- RecordConstructor withRecord = null;
+ Map<String, String> viewConfig = null;
DataverseName currentDataverse = defaultDataverse;
}
{
nameComponents = QualifiedName()
(
- (
- typeExpr = DatasetTypeSpecification()
- ifNotExists = IfNotExists()
- <IDENTIFIER> { expectToken(DEFAULT); } <NULL> { defaultNull = true; }
- ( <WITH> withRecord = RecordConstructor() )?
- )
- |
- ( ifNotExists = IfNotExists() )
+ (
+ typeExpr = DatasetTypeSpecification()
+ ifNotExists = IfNotExists()
+ <IDENTIFIER> { expectToken(DEFAULT); } <NULL> { defaultNull = true; }
+ viewConfig = ViewConfiguration()
+ )
+ |
+ ( ifNotExists = IfNotExists() )
)
{
if (orReplace && ifNotExists) {
@@ -1474,7 +1474,7 @@
defaultDataverse = currentDataverse;
try {
CreateViewStatement stmt = new CreateViewStatement(nameComponents.first, nameComponents.second.getValue(),
- typeExpr, viewBody, viewBodyExpr, defaultNull, withRecord, orReplace, ifNotExists);
+ typeExpr, viewBody, viewBodyExpr, defaultNull, viewConfig, orReplace, ifNotExists);
return addSourceLocation(stmt, startStmtToken);
} catch (CompilationException e) {
throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
@@ -1496,6 +1496,27 @@
}
}
+Map<String, String> ViewConfiguration() throws ParseException:
+{
+ Map<String, String> config = null;
+ String name = null, value = null;
+}
+{
+ (
+ <IDENTIFIER> { name = token.image.toLowerCase(); }
+ value = StringLiteral()
+ {
+ if (config == null) {
+ config = new LinkedHashMap<String, String>();
+ }
+ config.put(name, value);
+ }
+ )*
+ {
+ return config;
+ }
+}
+
CreateFunctionStatement CreateFunctionStatement(Token startStmtToken, boolean orReplace) throws ParseException:
{
CreateFunctionStatement stmt = null;