[NO ISSUE][COMP] Support typed views
- user model changes: yes
- storage format changes: no
- interface changes: no
Details:
- Support views that define their output type
- View output type can be specified inline or
as a reference to an existing data type
- Add testcases for typed views and expand
testcases for regular views
Change-Id: Ic6f86a6bf8ab9dbe458ec8280616a4a8207fc11d
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/12443
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
index e25c530..b1c2f0a 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/function/DatasetRewriter.java
@@ -19,6 +19,7 @@
package org.apache.asterix.app.function;
import static org.apache.asterix.common.api.IIdentifierMapper.Modifier.PLURAL;
+import static org.apache.asterix.common.api.IIdentifierMapper.Modifier.SINGULAR;
import static org.apache.asterix.common.utils.IdentifierUtil.dataset;
import java.util.ArrayList;
@@ -88,8 +89,8 @@
default:
// VIEWS are not expected at this point
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, unnest.getSourceLocation(),
- "Unexpected dataset type " + dataset.getDatasetType() + " for dataset "
- + DatasetUtil.getFullyQualifiedDisplayName(dataset));
+ String.format("Unexpected %s type %s for %s %s", dataset(SINGULAR), dataset.getDatasetType(),
+ dataset(SINGULAR), DatasetUtil.getFullyQualifiedDisplayName(dataset)));
}
variables.add(unnest.getVariable());
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 3571d88..267bd76 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
@@ -648,50 +648,22 @@
metadataProvider.validateDatabaseObjectName(dd.getDataverse(), datasetName, stmt.getSourceLocation());
DataverseName dataverseName = getActiveDataverseName(dd.getDataverse());
TypeExpression itemTypeExpr = dd.getItemType();
- DataverseName itemTypeDataverseName;
- String itemTypeName;
- boolean itemTypeAnonymous;
- switch (itemTypeExpr.getTypeKind()) {
- case TYPEREFERENCE:
- TypeReferenceExpression itemTypeRefExpr = (TypeReferenceExpression) itemTypeExpr;
- Pair<DataverseName, Identifier> itemTypeIdent = itemTypeRefExpr.getIdent();
- itemTypeDataverseName = itemTypeIdent.first != null ? itemTypeIdent.first : dataverseName;
- itemTypeName = itemTypeRefExpr.getIdent().second.getValue();
- itemTypeAnonymous = false;
- break;
- case RECORD:
- itemTypeDataverseName = dataverseName;
- itemTypeName = TypeUtil.createDatasetInlineTypeName(datasetName, false);
- itemTypeAnonymous = true;
- break;
- default:
- throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, stmt.getSourceLocation(),
- String.valueOf(itemTypeExpr.getTypeKind()));
- }
+ Triple<DataverseName, String, Boolean> itemTypeQualifiedName =
+ extractDatasetItemTypeName(dataverseName, datasetName, itemTypeExpr, false, stmt.getSourceLocation());
+ DataverseName itemTypeDataverseName = itemTypeQualifiedName.first;
+ String itemTypeName = itemTypeQualifiedName.second;
+ boolean itemTypeAnonymous = itemTypeQualifiedName.third;
TypeExpression metaItemTypeExpr = dd.getMetaItemType();
DataverseName metaItemTypeDataverseName = null;
String metaItemTypeName = null;
boolean metaItemTypeAnonymous;
if (metaItemTypeExpr != null) {
- switch (metaItemTypeExpr.getTypeKind()) {
- case TYPEREFERENCE:
- TypeReferenceExpression metaItemTypeRefExpr = (TypeReferenceExpression) metaItemTypeExpr;
- Pair<DataverseName, Identifier> metaItemTypeIdent = metaItemTypeRefExpr.getIdent();
- metaItemTypeDataverseName =
- metaItemTypeIdent.first != null ? metaItemTypeIdent.first : dataverseName;
- metaItemTypeName = metaItemTypeRefExpr.getIdent().second.getValue();
- metaItemTypeAnonymous = false;
- break;
- case RECORD:
- metaItemTypeDataverseName = dataverseName;
- metaItemTypeName = TypeUtil.createDatasetInlineTypeName(datasetName, true);
- metaItemTypeAnonymous = true;
- break;
- default:
- throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, stmt.getSourceLocation(),
- String.valueOf(metaItemTypeExpr.getTypeKind()));
- }
+ Triple<DataverseName, String, Boolean> metaItemTypeQualifiedName = extractDatasetItemTypeName(dataverseName,
+ datasetName, metaItemTypeExpr, true, stmt.getSourceLocation());
+ metaItemTypeDataverseName = metaItemTypeQualifiedName.first;
+ metaItemTypeName = metaItemTypeQualifiedName.second;
+ metaItemTypeAnonymous = metaItemTypeQualifiedName.third;
} else {
metaItemTypeAnonymous = true; // doesn't matter
}
@@ -754,29 +726,12 @@
}
}
- IAType itemType;
- boolean itemTypeIsInline = false;
- switch (itemTypeExpr.getTypeKind()) {
- case TYPEREFERENCE:
- itemTypeEntity = metadataProvider.findTypeEntity(itemTypeDataverseName, itemTypeName);
- if (itemTypeEntity == null || itemTypeEntity.getIsAnonymous()) {
- // anonymous types cannot be referred from CREATE DATASET
- throw new AsterixException(ErrorCode.UNKNOWN_TYPE, sourceLoc,
- DatasetUtil.getFullyQualifiedDisplayName(itemTypeDataverseName, itemTypeName));
- }
- itemType = itemTypeEntity.getDatatype();
- validateDatasetItemType(dsType, itemType, false, sourceLoc);
- break;
- case RECORD:
- itemType = translateType(itemTypeDataverseName, itemTypeName, itemTypeExpr, mdTxnCtx);
- validateDatasetItemType(dsType, itemType, false, sourceLoc);
- itemTypeEntity = new Datatype(itemTypeDataverseName, itemTypeName, itemType, true);
- itemTypeIsInline = true;
- break;
- default:
- throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
- String.valueOf(itemTypeExpr.getTypeKind()));
- }
+ Pair<Datatype, Boolean> itemTypePair = fetchDatasetItemType(mdTxnCtx, dsType, itemTypeDataverseName,
+ itemTypeName, itemTypeExpr, false, metadataProvider, sourceLoc);
+ itemTypeEntity = itemTypePair.first;
+ IAType itemType = itemTypeEntity.getDatatype();
+ boolean itemTypeIsInline = itemTypePair.second;
+
String ngName = ngNameId != null ? ngNameId
: configureNodegroupForDataset(appCtx, dd.getHints(), dataverseName, datasetName, metadataProvider,
sourceLoc);
@@ -793,30 +748,12 @@
switch (dsType) {
case INTERNAL:
if (metaItemTypeExpr != null) {
- switch (metaItemTypeExpr.getTypeKind()) {
- case TYPEREFERENCE:
- metaItemTypeEntity =
- metadataProvider.findTypeEntity(metaItemTypeDataverseName, metaItemTypeName);
- if (metaItemTypeEntity == null || metaItemTypeEntity.getIsAnonymous()) {
- // anonymous types cannot be referred from CREATE DATASET
- throw new AsterixException(ErrorCode.UNKNOWN_TYPE, sourceLoc, DatasetUtil
- .getFullyQualifiedDisplayName(metaItemTypeDataverseName, metaItemTypeName));
- }
- metaItemType = metaItemTypeEntity.getDatatype();
- validateDatasetItemType(dsType, metaItemType, true, sourceLoc);
- break;
- case RECORD:
- metaItemType = translateType(metaItemTypeDataverseName, metaItemTypeName,
- metaItemTypeExpr, mdTxnCtx);
- validateDatasetItemType(dsType, metaItemType, true, sourceLoc);
- metaItemTypeEntity =
- new Datatype(metaItemTypeDataverseName, metaItemTypeName, metaItemType, true);
- metaItemTypeIsInline = true;
- break;
- default:
- throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
- String.valueOf(metaItemTypeExpr.getTypeKind()));
- }
+ Pair<Datatype, Boolean> metaItemTypePair =
+ fetchDatasetItemType(mdTxnCtx, dsType, metaItemTypeDataverseName, metaItemTypeName,
+ metaItemTypeExpr, true, metadataProvider, sourceLoc);
+ metaItemTypeEntity = metaItemTypePair.first;
+ metaItemType = metaItemTypeEntity.getDatatype();
+ metaItemTypeIsInline = metaItemTypePair.second;
}
ARecordType metaRecType = (ARecordType) metaItemType;
@@ -963,13 +900,63 @@
}
}
+ protected Triple<DataverseName, String, Boolean> extractDatasetItemTypeName(DataverseName datasetDataverseName,
+ String datasetName, TypeExpression itemTypeExpr, boolean isMetaItemType, SourceLocation sourceLoc)
+ throws CompilationException {
+ switch (itemTypeExpr.getTypeKind()) {
+ case TYPEREFERENCE:
+ TypeReferenceExpression itemTypeRefExpr = (TypeReferenceExpression) itemTypeExpr;
+ Pair<DataverseName, Identifier> itemTypeIdent = itemTypeRefExpr.getIdent();
+ DataverseName typeDataverseName =
+ itemTypeIdent.first != null ? itemTypeIdent.first : datasetDataverseName;
+ String typeName = itemTypeRefExpr.getIdent().second.getValue();
+ return new Triple<>(typeDataverseName, typeName, false);
+ case RECORD:
+ String inlineTypeName = TypeUtil.createDatasetInlineTypeName(datasetName, isMetaItemType);
+ return new Triple<>(datasetDataverseName, inlineTypeName, true);
+ default:
+ throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
+ String.valueOf(itemTypeExpr.getTypeKind()));
+ }
+ }
+
+ protected Pair<Datatype, Boolean> fetchDatasetItemType(MetadataTransactionContext mdTxnCtx, DatasetType datasetType,
+ DataverseName itemTypeDataverseName, String itemTypeName, TypeExpression itemTypeExpr,
+ boolean isMetaItemType, MetadataProvider metadataProvider, SourceLocation sourceLoc)
+ throws AlgebricksException {
+ switch (itemTypeExpr.getTypeKind()) {
+ case TYPEREFERENCE:
+ Datatype itemTypeEntity = metadataProvider.findTypeEntity(itemTypeDataverseName, itemTypeName);
+ if (itemTypeEntity == null || itemTypeEntity.getIsAnonymous()) {
+ // anonymous types cannot be referred from CREATE DATASET/VIEW
+ throw new AsterixException(ErrorCode.UNKNOWN_TYPE, sourceLoc,
+ DatasetUtil.getFullyQualifiedDisplayName(itemTypeDataverseName, itemTypeName));
+ }
+ IAType itemType = itemTypeEntity.getDatatype();
+ validateDatasetItemType(datasetType, itemType, isMetaItemType, sourceLoc);
+ return new Pair<>(itemTypeEntity, false);
+ case RECORD:
+ itemType = translateType(itemTypeDataverseName, itemTypeName, itemTypeExpr, mdTxnCtx);
+ validateDatasetItemType(datasetType, itemType, isMetaItemType, sourceLoc);
+ itemTypeEntity = new Datatype(itemTypeDataverseName, itemTypeName, itemType, true);
+ return new Pair<>(itemTypeEntity, true);
+ default:
+ throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
+ String.valueOf(itemTypeExpr.getTypeKind()));
+ }
+ }
+
protected void validateDatasetItemType(DatasetType datasetType, IAType itemType, boolean isMetaItemType,
SourceLocation sourceLoc) throws AlgebricksException {
if (itemType.getTypeTag() != ATypeTag.OBJECT) {
throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc,
- String.format(StringUtils.capitalize(dataset()) + " %s has to be a record type.",
+ String.format("%s %s has to be a record type.",
+ datasetType == DatasetType.VIEW ? "view" : StringUtils.capitalize(dataset()),
isMetaItemType ? "meta type" : "type"));
}
+ if (datasetType == DatasetType.VIEW) {
+ ViewUtil.validateViewItemType((ARecordType) itemType, sourceLoc);
+ }
}
protected Map<String, String> createExternalDatasetProperties(DataverseName dataverseName, DatasetDecl dd,
@@ -2439,15 +2426,31 @@
public void handleCreateViewStatement(MetadataProvider metadataProvider, Statement stmt,
IStatementRewriter stmtRewriter, IRequestParameters requestParameters) throws Exception {
CreateViewStatement cvs = (CreateViewStatement) stmt;
- metadataProvider.validateDatabaseObjectName(cvs.getDataverseName(), cvs.getViewName(),
- stmt.getSourceLocation());
+ String viewName = cvs.getViewName();
+ metadataProvider.validateDatabaseObjectName(cvs.getDataverseName(), viewName, stmt.getSourceLocation());
DataverseName dataverseName = getActiveDataverseName(cvs.getDataverseName());
- lockUtil.createDatasetBegin(lockManager, metadataProvider.getLocks(), dataverseName, cvs.getViewName(),
- MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDataverseName(),
- MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDatatypeName(), false, null, null, false, null, null,
- true, DatasetType.VIEW, null);
+
+ DataverseName viewItemTypeDataverseName;
+ String viewItemTypeName;
+ boolean viewItemTypeAnonymous;
+ if (cvs.hasItemType()) {
+ Triple<DataverseName, String, Boolean> viewTypeQualifiedName = extractDatasetItemTypeName(dataverseName,
+ viewName, cvs.getItemType(), false, stmt.getSourceLocation());
+ viewItemTypeDataverseName = viewTypeQualifiedName.first;
+ viewItemTypeName = viewTypeQualifiedName.second;
+ viewItemTypeAnonymous = viewTypeQualifiedName.third;
+ } else {
+ viewItemTypeDataverseName = MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDataverseName();
+ viewItemTypeName = MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDatatypeName();
+ viewItemTypeAnonymous = false;
+ }
+
+ lockUtil.createDatasetBegin(lockManager, metadataProvider.getLocks(), dataverseName, viewName,
+ viewItemTypeDataverseName, viewItemTypeName, viewItemTypeAnonymous, null, null, false, null, null, true,
+ DatasetType.VIEW, null);
try {
- doCreateView(metadataProvider, cvs, dataverseName, cvs.getViewName(), stmtRewriter, requestParameters);
+ doCreateView(metadataProvider, cvs, dataverseName, viewName, viewItemTypeDataverseName, viewItemTypeName,
+ stmtRewriter, requestParameters);
} finally {
metadataProvider.getLocks().unlock();
metadataProvider.setDefaultDataverse(activeDataverse);
@@ -2455,7 +2458,8 @@
}
protected void doCreateView(MetadataProvider metadataProvider, CreateViewStatement cvs, DataverseName dataverseName,
- String viewName, IStatementRewriter stmtRewriter, IRequestParameters requestParameters) throws Exception {
+ String viewName, DataverseName itemTypeDataverseName, String itemTypeName, IStatementRewriter stmtRewriter,
+ IRequestParameters requestParameters) throws Exception {
SourceLocation sourceLoc = cvs.getSourceLocation();
MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -2479,6 +2483,15 @@
}
}
+ Datatype itemTypeEntity = null;
+ boolean itemTypeIsInline = false;
+ if (cvs.hasItemType()) {
+ Pair<Datatype, Boolean> itemTypePair = fetchDatasetItemType(mdTxnCtx, DatasetType.VIEW,
+ itemTypeDataverseName, itemTypeName, cvs.getItemType(), false, metadataProvider, sourceLoc);
+ itemTypeEntity = itemTypePair.first;
+ itemTypeIsInline = itemTypePair.second;
+ }
+
// Check whether the view is usable:
// create a view declaration for this function,
// and a query body that queries this view:
@@ -2494,16 +2507,23 @@
List<List<Triple<DataverseName, String, String>>> dependencies =
ViewUtil.getViewDependencies(viewDecl, queryRewriter);
- ViewDetails viewDetails = new ViewDetails(cvs.getViewBody(), dependencies);
+ ViewDetails viewDetails = cvs.hasItemType()
+ ? new ViewDetails(cvs.getViewBody(), dependencies, cvs.getDefaultNull(), cvs.getDatetimeFormat(),
+ cvs.getDateFormat(), cvs.getTimeFormat())
+ : new ViewDetails(cvs.getViewBody(), dependencies, null, null, null, null);
- Dataset view =
- new Dataset(dataverseName, viewName, MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDataverseName(),
- MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDatatypeName(),
- MetadataConstants.METADATA_NODEGROUP_NAME, "", Collections.emptyMap(), viewDetails,
- Collections.emptyMap(), DatasetType.VIEW, 0, MetadataUtil.PENDING_NO_OP);
+ Dataset view = new Dataset(dataverseName, viewName, itemTypeDataverseName, itemTypeName,
+ MetadataConstants.METADATA_NODEGROUP_NAME, "", Collections.emptyMap(), viewDetails,
+ Collections.emptyMap(), DatasetType.VIEW, 0, MetadataUtil.PENDING_NO_OP);
if (existingDataset == null) {
+ if (itemTypeIsInline) {
+ MetadataManager.INSTANCE.addDatatype(mdTxnCtx, itemTypeEntity);
+ }
MetadataManager.INSTANCE.addDataset(mdTxnCtx, view);
} else {
+ if (itemTypeIsInline) {
+ MetadataManager.INSTANCE.updateDatatype(mdTxnCtx, itemTypeEntity);
+ }
MetadataManager.INSTANCE.updateDataset(mdTxnCtx, view);
}
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
@@ -2562,6 +2582,11 @@
DatasetUtil.getFullyQualifiedDisplayName(dataverseName, viewName));
}
MetadataManager.INSTANCE.dropDataset(mdTxnCtx, dataverseName, viewName, false);
+ if (TypeUtil.isDatasetInlineTypeName(dataset, dataset.getItemTypeDataverseName(),
+ dataset.getItemTypeName())) {
+ MetadataManager.INSTANCE.dropDatatype(mdTxnCtx, dataset.getItemTypeDataverseName(),
+ dataset.getItemTypeName());
+ }
MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
return true;
} catch (Exception e) {
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.1.ddl.sqlpp
new file mode 100644
index 0000000..bcf65d2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.1.ddl.sqlpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+/*
+ * Description : Create index on a view
+ * Expected Res : Failure
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type test.LineItemType as
+ closed {
+ l_orderkey : bigint,
+ l_partkey : bigint,
+ l_suppkey : bigint,
+ l_linenumber : bigint,
+ l_quantity : double,
+ l_extendedprice : double,
+ l_discount : double,
+ l_tax : double,
+ l_returnflag : string,
+ l_linestatus : string,
+ l_shipdate : string,
+ l_commitdate : string,
+ l_receiptdate : string,
+ l_shipinstruct : string,
+ l_shipmode : string,
+ l_comment : string
+};
+
+create dataset LineItem(LineItemType) primary key l_orderkey;
+
+create view LineItemView1 as LineItem;
+
+--- Failure: cannot create index on a view
+
+create index idx1 on LineItemView1(l_partkey : bigint);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.2.ddl.sqlpp
new file mode 100644
index 0000000..e86ce88
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.2.ddl.sqlpp
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+/*
+ * Description : Create index on a typed view
+ * Expected Res : Failure
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type test.LineItemType as
+ open {
+ l_orderkey : bigint
+};
+
+create type test.LineItemType2 as
+ closed {
+ l_orderkey : bigint?,
+ l_partkey : bigint?,
+ l_suppkey : bigint?,
+ l_linenumber : bigint?,
+ l_quantity : double?,
+ l_extendedprice : double?,
+ l_discount : double?,
+ l_tax : double?,
+ l_returnflag : string?,
+ l_linestatus : string?,
+ l_shipdate : string?,
+ l_commitdate : string?,
+ l_receiptdate : string?,
+ l_shipinstruct : string?,
+ l_shipmode : string?,
+ l_comment : string?
+};
+
+create dataset LineItem(LineItemType) primary key l_orderkey;
+
+create view LineItemView2(LineItemType2) default null as LineItem;
+
+--- Failure: cannot create index on a typed view
+
+create index idx1 on LineItemView2(l_partkey);
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
new file mode 100644
index 0000000..406e53a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.1.ddl.sqlpp
@@ -0,0 +1,72 @@
+/*
+ * 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 test1 if exists;
+create dataverse test1;
+
+use test1;
+
+create dataset t1(c_id int32 not unknown) open type primary key c_id;
+
+create dataset t2(c_id int32 not unknown) open type primary key c_id;
+
+/* inline type */
+create view v1(
+ c_id int32,
+ c_i8 int8, c_i16 int16, c_i32 int32, c_i64 int64, c_f float, c_d double,
+ c_b boolean, c_s string,
+ c_datetime datetime, c_date date, c_time time,
+ c_dur duration, c_ymdur year_month_duration, c_dtdur day_time_duration
+) default null as t1;
+
+create type t2 as closed {
+ c_id:int32?,
+ c_i8:int8?, c_i16:int16?, c_i32:int32?, c_i64:int64?, c_f:float?, c_d:double?,
+ c_b:boolean?, c_s:string?,
+ c_datetime:datetime?, c_date:date?, c_time:time?,
+ c_dur:duration?, c_ymdur:year_month_duration?, c_dtdur:day_time_duration?
+};
+
+/* type reference, query body */
+create view v2_ref_type(t2) default null as
+ select c_id,
+ c_i8, c_i16, c_i32, c_i64, c_f, c_d,
+ c_b, c_s,
+ c_datetime, c_date, c_time,
+ c_dur, c_ymdur, c_dtdur
+ from t1
+;
+
+/* custom date/time format (with clause) */
+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;
+
+/* custom date format (with clause) */
+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;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.2.update.sqlpp
new file mode 100644
index 0000000..4c91491
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.2.update.sqlpp
@@ -0,0 +1,79 @@
+/*
+ * 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 test1;
+
+insert into t1 ([
+ {
+ 'c_id':0,
+ 'c_i8':'8','c_i16':'16','c_i32':'32','c_i64':'64','c_f':'1.5','c_d':'2.25',
+ 'c_b':false,'c_s':'abc',
+ 'c_datetime':'2020-02-03T10:11:12.001','c_date':'2020-02-03','c_time':'10:11:12.001',
+ 'c_dur':'P30Y10M25DT13H12M50S','c_ymdur':'P30Y10M','c_dtdur':'P25DT13H12M50S'
+ },
+
+ {
+ 'c_id':1,
+ 'c_i8':'-8','c_i16':'-16','c_i32':'-32','c_i64':'-64','c_f':'-1.5','c_d':'-2.25',
+ 'c_b':true,'c_s':'xyz',
+ 'c_datetime':'2021-04-05T01:02:03.999','c_date':'2021-04-05','c_time':'01:02:03.999',
+ 'c_dur':'P1Y2M3DT4H5M6S','c_ymdur':'P1Y2M','c_dtdur':'P3DT4H5M6S'
+ },
+
+ /* Null values */
+ {
+ 'c_id':2,
+ 'c_i8':null,'c_i16':null,'c_i32':null,'c_i64':null,'c_f':null,'c_d':null,
+ 'c_b':null,'c_s':null,
+ 'c_datetime':null,'c_date':null,'c_time':null,
+ 'c_dur':null,'c_ymdur':null,'c_dtdur':null
+ },
+
+ /* Missing values */
+ {
+ 'c_id':3
+ },
+
+ /* Invalid values */
+ {
+ 'c_id':4,
+ 'c_i8':'a','c_i16':'b','c_i32':'c','c_i64':'d','c_f':'e','c_d':'f',
+ 'c_b':99,'c_s':null,
+ 'c_datetime':'a','c_date':'b','c_time':'c',
+ 'c_dur':'x','c_ymdur':'y','c_dtdur':'z',
+ 'c_something_else':'something_else'
+ }
+]);
+
+/* Custom date/time format */
+insert into t2 ([
+ {
+ 'c_id':0,
+ 'c_datetime':'02/20/2020 11:40:41.001pm','c_date':'02/20/2020','c_time':'11:40:41.001pm'
+ },
+ {
+ 'c_id':1,
+ 'c_datetime':'11/25/2021 11:50:51.999am','c_date':'11/25/2021','c_time':'11:50:51.999am'
+ },
+ /* Invalid values */
+ {
+ 'c_id':2,
+ 'c_datetime':'a','c_date':'b','c_time':'c'
+ }
+]);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.3.query.sqlpp
new file mode 100644
index 0000000..c8126cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.3.query.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 test1;
+
+select c_id,
+ c_i8, c_i16, c_i32, c_i64, c_f, c_d,
+ c_b, c_s,
+ c_datetime, c_date, c_time,
+ c_dur, c_ymdur, c_dtdur
+from v1
+order by c_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.4.query.sqlpp
new file mode 100644
index 0000000..59a713a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.4.query.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 test1;
+
+select c_id,
+ c_i8, c_i16, c_i32, c_i64, c_f, c_d,
+ c_b, c_s,
+ c_datetime, c_date, c_time,
+ c_dur, c_ymdur, c_dtdur
+from v2_ref_type
+order by c_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.5.query.sqlpp
new file mode 100644
index 0000000..19be7a9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.5.query.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 test1;
+
+select c_id,
+ c_datetime, c_date, c_time
+from v3_datetime_format
+order by c_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.6.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.6.query.sqlpp
new file mode 100644
index 0000000..fd96010
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.6.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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 test1;
+
+select c_id, c_date
+from v4_date_format_only
+order by c_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.7.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.7.query.sqlpp
new file mode 100644
index 0000000..8c5d268
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.7.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+select DataverseName, DatasetName, ViewDetails
+from Metadata.`Dataset` d
+where DatasetType='VIEW'
+order by DataverseName, DatasetName;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.1.ddl.sqlpp
new file mode 100644
index 0000000..2c39dd1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.1.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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 test1 if exists;
+create dataverse test1;
+
+use test1;
+
+create dataset t1(c_id int32 not unknown) open type primary key c_id;
+
+create view v1(
+ c_id int32,
+ c_i8 int8, c_i16 int16, c_i32 int32, c_i64 int64, c_f float, c_d double,
+ c_b boolean, c_s string,
+ c_datetime datetime, c_date date, c_time time,
+ c_dur duration, c_ymdur year_month_duration, c_dtdur day_time_duration
+) default null as t1;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.2.update.sqlpp
new file mode 100644
index 0000000..644893f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.2.update.sqlpp
@@ -0,0 +1,40 @@
+/*
+ * 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 test1;
+
+insert into t1 ([
+ /* Invalid format (string values) */
+ {
+ 'c_id':0,
+ 'c_i8':'a','c_i16':'b','c_i32':'c','c_i64':'d','c_f':'e','c_d':'f',
+ 'c_b':null,'c_s':null,
+ 'c_datetime':'g','c_date':'h','c_time':'j',
+ 'c_dur':'k','c_ymdur':'m','c_dtdur':'n'
+ },
+ /* Invalid type */
+ {
+ 'c_id':1,
+ 'c_i8':duration('P1M8S'),'c_i16':duration('P1M16S'),'c_i32':duration('P1M32S'),'c_i64':duration('P1M64S'),'c_f':duration('P2M32S'),'c_d':duration('P2M64S'),
+ 'c_b':duration('P3M1S'),'c_s':null,
+ 'c_datetime':duration('P4M1S'),'c_date':duration('P5M1S'),'c_time':duration('P6M1S'),
+ 'c_dur':date('2020-01-02'),'c_ymdur':date('2020-01-02'),'c_dtdur':date('2020-01-02')
+ }
+]);
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.3.query.sqlpp
new file mode 100644
index 0000000..e600abd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.3.query.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.
+ */
+
+// requesttype=application/json
+// param max-warnings:json=100
+
+use test1;
+
+select c_id,
+ c_i8, c_i16, c_i32, c_i64, c_f, c_d,
+ c_b, c_s,
+ c_datetime, c_date, c_time,
+ c_dur, c_ymdur, c_dtdur
+from v1
+order by c_id;
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
new file mode 100644
index 0000000..6e90398
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * 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 test1 if exists;
+create dataverse test1;
+
+use test1;
+
+create dataset t1(c_id int32 not unknown) open type primary key c_id;
+
+/* invalid custom date/time format (in with clause) */
+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;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.2.update.sqlpp
new file mode 100644
index 0000000..3a6173f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.2.update.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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 test1;
+
+insert into t1 ([
+ /* Invalid format (string values) */
+ {
+ 'c_id':0,
+ 'c_datetime':'a','c_date':'b','c_time':'c'
+ }
+]);
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.3.query.sqlpp
new file mode 100644
index 0000000..dd71835
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.3.query.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.
+ */
+
+// requesttype=application/json
+// param max-warnings:json=100
+
+use test1;
+
+select c_id,
+ c_datetime, c_date, c_time
+from v1_invalid_datetime_format
+order by c_id;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.1.ddl.sqlpp
new file mode 100644
index 0000000..859b498
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.1.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+--- Negative: unknown datatype's dataverse
+
+drop dataverse test if exists;
+create dataverse test;
+
+create view test.v1(unknown_dv.t1) default null as
+ select * from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.2.ddl.sqlpp
new file mode 100644
index 0000000..571d3d9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.2.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+--- Negative: unknown datatype
+
+drop dataverse test if exists;
+create dataverse test;
+
+create view test.v1(t1_unknown) default null as
+ select * from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.3.ddl.sqlpp
new file mode 100644
index 0000000..73de71e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.3.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+--- Negative: view type is not closed
+
+drop dataverse test if exists;
+create dataverse test;
+
+create type test.t1 as open {
+ r:int64?
+};
+
+create view test.v1(t1) default null as
+ select r from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.4.ddl.sqlpp
new file mode 100644
index 0000000..e900a32
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.4.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.
+ */
+
+--- Negative: view type has non-primitive fields
+
+drop dataverse test if exists;
+create dataverse test;
+
+create type test.t1 as closed {
+ r:int64?,
+ a:[int64]?
+};
+
+create view test.v1(t1) default null as
+ select r, [r] a from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.5.ddl.sqlpp
new file mode 100644
index 0000000..4b814bf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.5.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+--- Negative: view inline type has non-primitive fields
+
+drop dataverse test if exists;
+create dataverse test;
+
+create view test.v1(r bigint, a [bigint]) default null as
+ select r, [r] a from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.6.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.6.ddl.sqlpp
new file mode 100644
index 0000000..dc344c3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.6.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+--- Negative: view type has non-optional fields
+
+drop dataverse test if exists;
+create dataverse test;
+
+create type test.t1 as closed {
+ r:int64
+};
+
+create view test.v1(t1) default null as
+ select r from range(1,2) r;
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
new file mode 100644
index 0000000..6197dae
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.7.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.
+ */
+
+--- Negative: invalid with 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'
+}
+as
+ select string(current_date()) cd from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.8.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.8.ddl.sqlpp
new file mode 100644
index 0000000..adb53a8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.8.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+--- Negative: default null is required
+
+drop dataverse test if exists;
+create dataverse test;
+
+create view test.v1(r bigint) as
+ select r from range(1,2) r;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
index 27ae6ab..41a64fc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
@@ -28,6 +28,10 @@
create view test1.v2 as
select v1.* from v1;
+create view test1.v3(r bigint) default null as v2;
+
+create type test1.t4 as closed { r:int64? };
+
+create view test1.v4(t4) default null as v2;
+
drop dataverse test1;
-
-
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-2-negative/drop-dataverse-2-negative.6.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-2-negative/drop-dataverse-2-negative.6.ddl.sqlpp
new file mode 100644
index 0000000..130e769
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-2-negative/drop-dataverse-2-negative.6.ddl.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.
+ */
+
+--- Test that DROP DATAVERSE fails due to cross-dataverse dependencies
+
+--- View depends on datatype
+
+drop dataverse test1 if exists;
+create dataverse test1;
+
+drop dataverse test2 if exists;
+create dataverse test2;
+
+create type test2.t1 as closed { r:int64? };
+
+create view test1.v1(test2.t1) default null as select r from range(1,2) r;
+
+drop dataverse test2;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.3.ddl.sqlpp
new file mode 100644
index 0000000..c64efbd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.3.ddl.sqlpp
@@ -0,0 +1,38 @@
+/*
+ * 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 views and inline types, user-defined datatype must remain in the dataverse */
+
+drop dataverse test if exists;
+create dataverse test;
+
+create view test.v1 as
+ select r from range(1,2) r;
+
+create view test.v2(r bigint) default null as v1;
+
+create type test.t3 as closed { r:int64? };
+
+create view test.v3(t3) default null as v1;
+
+drop view test.v3;
+
+drop view test.v2;
+
+drop view test.v1;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.4.query.sqlpp
new file mode 100644
index 0000000..4c8483e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.4.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.
+ */
+
+select count(*) cnt
+from Metadata.`Dataset`
+where DataverseName = "test" and DatasetType = "VIEW";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.5.query.sqlpp
new file mode 100644
index 0000000..5bf0799
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.5.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+select DatatypeName
+from Metadata.`Datatype`
+where DataverseName = "test"
+order by DatatypeName;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.17.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.17.ddl.sqlpp
new file mode 100644
index 0000000..0fbb626
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.17.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+--- Negative: drop type fails if a view depends on it
+
+drop dataverse test1 if exists;
+create dataverse test1;
+
+drop dataverse test2 if exists;
+create dataverse test2;
+
+create type test2.t1 as closed { r:int64? };
+
+create view test1.v1(test2.t1) default null as
+ select r from range(1,2) r;
+
+drop type test2.t1;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.18.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.18.query.sqlpp
new file mode 100644
index 0000000..29f7a8d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.18.query.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.
+ */
+
+-- check that the type was not dropped
+
+select DatatypeName
+from Metadata.`Datatype`
+where DataverseName = "test2"
+order by DatatypeName;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.1.ddl.sqlpp
new file mode 100644
index 0000000..90f0d31
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.1.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 test1 if exists;
+create dataverse test1;
+
+use test1;
+
+create dataset t1(id bigint not unknown, v string) primary key id;
+
+create view v1 as t1;
+
+create view v2 as t1;
+
+create view v3 as t1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.2.update.sqlpp
new file mode 100644
index 0000000..5e4b305
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.2.update.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 test1;
+
+insert into t1 ([
+ {'id':1,'v':'hello1'},
+ {'id':2,'v':'hello2'}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.3.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.3.update.sqlpp
new file mode 100644
index 0000000..89507a0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.3.update.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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 test1;
+
+--- Failure: cannot insert into a view
+
+insert into v1 ([
+ {'id':3,'v':'hello1'}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.4.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.4.update.sqlpp
new file mode 100644
index 0000000..103f7f1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.4.update.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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 test1;
+
+--- Failure: cannot upsert into a view
+
+upsert into v2 ([
+ {'id':2,'v':'hello22'}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.5.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.5.update.sqlpp
new file mode 100644
index 0000000..b3e5524
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.5.update.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 test1;
+
+--- Failure: cannot delete from a view
+
+delete from v3
+where id = 2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.3.adm
new file mode 100644
index 0000000..ccea22c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.3.adm
@@ -0,0 +1,5 @@
+{ "c_id": 0, "c_i8": 8, "c_i16": 16, "c_i32": 32, "c_i64": 64, "c_f": 1.5, "c_d": 2.25, "c_b": false, "c_s": "abc", "c_datetime": datetime("2020-02-03T10:11:12.001Z"), "c_date": date("2020-02-03"), "c_time": time("10:11:12.001Z"), "c_dur": duration("P30Y10M25DT13H12M50S"), "c_ymdur": year-month-duration("P30Y10M"), "c_dtdur": day-time-duration("P25DT13H12M50S") }
+{ "c_id": 1, "c_i8": -8, "c_i16": -16, "c_i32": -32, "c_i64": -64, "c_f": -1.5, "c_d": -2.25, "c_b": true, "c_s": "xyz", "c_datetime": datetime("2021-04-05T01:02:03.999Z"), "c_date": date("2021-04-05"), "c_time": time("01:02:03.999Z"), "c_dur": duration("P1Y2M3DT4H5M6S"), "c_ymdur": year-month-duration("P1Y2M"), "c_dtdur": day-time-duration("P3DT4H5M6S") }
+{ "c_id": 2, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": null, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
+{ "c_id": 3, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": null, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
+{ "c_id": 4, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": true, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.4.adm
new file mode 100644
index 0000000..ccea22c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.4.adm
@@ -0,0 +1,5 @@
+{ "c_id": 0, "c_i8": 8, "c_i16": 16, "c_i32": 32, "c_i64": 64, "c_f": 1.5, "c_d": 2.25, "c_b": false, "c_s": "abc", "c_datetime": datetime("2020-02-03T10:11:12.001Z"), "c_date": date("2020-02-03"), "c_time": time("10:11:12.001Z"), "c_dur": duration("P30Y10M25DT13H12M50S"), "c_ymdur": year-month-duration("P30Y10M"), "c_dtdur": day-time-duration("P25DT13H12M50S") }
+{ "c_id": 1, "c_i8": -8, "c_i16": -16, "c_i32": -32, "c_i64": -64, "c_f": -1.5, "c_d": -2.25, "c_b": true, "c_s": "xyz", "c_datetime": datetime("2021-04-05T01:02:03.999Z"), "c_date": date("2021-04-05"), "c_time": time("01:02:03.999Z"), "c_dur": duration("P1Y2M3DT4H5M6S"), "c_ymdur": year-month-duration("P1Y2M"), "c_dtdur": day-time-duration("P3DT4H5M6S") }
+{ "c_id": 2, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": null, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
+{ "c_id": 3, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": null, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
+{ "c_id": 4, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": true, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.5.adm
new file mode 100644
index 0000000..03a76e7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.5.adm
@@ -0,0 +1,3 @@
+{ "c_id": 0, "c_datetime": datetime("2020-02-20T23:40:41.001Z"), "c_date": date("2020-02-20"), "c_time": time("23:40:41.001Z") }
+{ "c_id": 1, "c_datetime": datetime("2021-11-25T11:50:51.999Z"), "c_date": date("2021-11-25"), "c_time": time("11:50:51.999Z") }
+{ "c_id": 2, "c_datetime": null, "c_date": null, "c_time": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.6.adm
new file mode 100644
index 0000000..4eab90a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.6.adm
@@ -0,0 +1,3 @@
+{ "c_id": 0, "c_date": date("2020-02-20") }
+{ "c_id": 1, "c_date": date("2021-11-25") }
+{ "c_id": 2, "c_date": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.7.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.7.adm
new file mode 100644
index 0000000..adcf41f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-3-typed/create-view-3-typed.7.adm
@@ -0,0 +1,4 @@
+{ "DataverseName": "test1", "DatasetName": "v1", "ViewDetails": { "Definition": "t1", "Dependencies": [ [ [ "test1", "t1" ] ], [ ], [ ] ], "Default": null } }
+{ "DataverseName": "test1", "DatasetName": "v2_ref_type", "ViewDetails": { "Definition": "select c_id,\n c_i8, c_i16, c_i32, c_i64, c_f, c_d,\n c_b, c_s,\n c_datetime, c_date, c_time,\n c_dur, c_ymdur, c_dtdur\n from t1", "Dependencies": [ [ [ "test1", "t1" ] ], [ ], [ ] ], "Default": null } }
+{ "DataverseName": "test1", "DatasetName": "v3_datetime_format", "ViewDetails": { "Definition": "t2", "Dependencies": [ [ [ "test1", "t2" ] ], [ ], [ ] ], "Default": null, "DataFormat": [ "MM/DD/YYYY hh:mm:ss.nnna", "MM/DD/YYYY", "hh:mm:ss.nnna" ] } }
+{ "DataverseName": "test1", "DatasetName": "v4_date_format_only", "ViewDetails": { "Definition": "t2", "Dependencies": [ [ [ "test1", "t2" ] ], [ ], [ ] ], "Default": null, "DataFormat": [ null, "MM/DD/YYYY", null ] } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-4-typed-warn/create-view-4-typed-warn.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-4-typed-warn/create-view-4-typed-warn.3.adm
new file mode 100644
index 0000000..3c45dd1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-4-typed-warn/create-view-4-typed-warn.3.adm
@@ -0,0 +1,2 @@
+{ "c_id": 0, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": null, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
+{ "c_id": 1, "c_i8": null, "c_i16": null, "c_i32": null, "c_i64": null, "c_f": null, "c_d": null, "c_b": null, "c_s": null, "c_datetime": null, "c_date": null, "c_time": null, "c_dur": null, "c_ymdur": null, "c_dtdur": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-5-typed-warn/create-view-5-typed-warn.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-5-typed-warn/create-view-5-typed-warn.3.adm
new file mode 100644
index 0000000..74333a2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/create-view-5-typed-warn/create-view-5-typed-warn.3.adm
@@ -0,0 +1 @@
+{ "c_id": 0, "c_datetime": null, "c_date": null, "c_time": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-1/drop-view-1.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-1/drop-view-1.4.adm
new file mode 100644
index 0000000..bacb60c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-1/drop-view-1.4.adm
@@ -0,0 +1 @@
+{ "cnt": 0 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-1/drop-view-1.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-1/drop-view-1.5.adm
new file mode 100644
index 0000000..0b280d1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-1/drop-view-1.5.adm
@@ -0,0 +1 @@
+{ "DatatypeName": "t3" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-2-negative/drop-view-2-negative.18.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-2-negative/drop-view-2-negative.18.adm
new file mode 100644
index 0000000..feec5ab
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/view/drop-view-2-negative/drop-view-2-negative.18.adm
@@ -0,0 +1 @@
+{ "DatatypeName": "t1" }
\ 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 c8b7d1d..b1549f6 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -4121,6 +4121,13 @@
</compilation-unit>
</test-case>
<test-case FilePath="ddl/create-index">
+ <compilation-unit name="create-index-6">
+ <output-dir compare="Text">none</output-dir>
+ <expected-error>ASX1050: Cannot find dataset with name LineItemView1 in dataverse test (in line 55, at column 1)</expected-error>
+ <expected-error>ASX1050: Cannot find dataset with name LineItemView2 in dataverse test (in line 60, at column 1)</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="ddl/create-index">
<compilation-unit name="create-inverted-index-with-variable-length-primary-key">
<output-dir compare="Text">create-inverted-index-with-variable-length-primary-key</output-dir>
</compilation-unit>
@@ -13022,13 +13029,70 @@
<expected-error>ASX1072: A dataset with name ds1 already exists in dataverse test (in line 30, at column 1)</expected-error>
<expected-error>ASX1072: A dataset with name ds2 already exists in dataverse test (in line 30, at column 1)</expected-error>
<expected-error>ASX1160: A view with this name test.ds1 already exists (in line 27, at column 1)</expected-error>
- <expected-error><![CDATA[ASX1001: Syntax error: Unexpected IF NOT EXISTS (in line 25, at column 39)]]></expected-error>
+ <expected-error><![CDATA[ASX1001: Syntax error: Unexpected IF NOT EXISTS (in line 25, at column 1)]]></expected-error>
<expected-error>ASX1149: Illegal function or view recursion (in line 31, at column 1)</expected-error>
<expected-error>ASX1149: Illegal function or view recursion (in line 32, at column 1)</expected-error>
<expected-error>ASX1149: Illegal function or view recursion (in line 33, at column 1)</expected-error>
</compilation-unit>
</test-case>
<test-case FilePath="view">
+ <compilation-unit name="create-view-3-typed">
+ <output-dir compare="Text">create-view-3-typed</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="view" check-warnings="true">
+ <compilation-unit name="create-view-4-typed-warn">
+ <output-dir compare="Text">create-view-4-typed-warn</output-dir>
+ <expected-warn>ASX0006: Invalid format for tinyint in a (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for smallint in b (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for integer in c (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for bigint in d (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for float in e (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for double in f (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for datetime in g (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for date in h (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for time in j (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for duration in k (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for yearmonthduration in m (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for daytimeduration in n (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: boolean() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: int8() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: int16() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: int32() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: int64() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: float() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: double() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: datetime() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: date() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: time() cannot process input type duration (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: duration() cannot process input type date (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: year-month-duration() cannot process input type date (in line 30, at column 6)</expected-warn>
+ <expected-warn>ASX0004: Unsupported type: day-time-duration() cannot process input type date (in line 30, at column 6)</expected-warn>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="view" check-warnings="true">
+ <compilation-unit name="create-view-5-typed-warn">
+ <output-dir compare="Text">create-view-5-typed-warn</output-dir>
+ <expected-warn>ASX0006: Invalid format for datetime in a (in line 27, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for date in b (in line 27, at column 6)</expected-warn>
+ <expected-warn>ASX0006: Invalid format for time in c (in line 27, at column 6)</expected-warn>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="view">
+ <compilation-unit name="create-view-6-typed-negative">
+ <output-dir compare="Text">none</output-dir>
+ <expected-error>ASX1082: Cannot find datatype with name unknown_dv.t1</expected-error>
+ <expected-error>ASX1082: Cannot find datatype with name test.t1_unknown</expected-error>
+ <expected-error>ASX1079: Compilation error: view type cannot have open fields (in line 29, at column 1)</expected-error>
+ <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><![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>
+ </test-case>
+ <test-case FilePath="view">
<compilation-unit name="drop-dataverse-1">
<output-dir compare="Text">none</output-dir>
</compilation-unit>
@@ -13041,6 +13105,7 @@
<expected-error>ASX1147: Cannot drop dataverse: dataset (or view) test2.ds2 being used by view test1.v1</expected-error>
<expected-error>ASX1147: Cannot drop dataverse: function test2.f2() being used by view test1.v1</expected-error>
<expected-error>ASX1147: Cannot drop dataverse: synonym test2.s3 being used by view test1.v1</expected-error>
+ <expected-error>ASX1147: Cannot drop dataverse: type test2.t1 being used by dataset test1.v1</expected-error>
<source-location>false</source-location>
</compilation-unit>
</test-case>
@@ -13061,6 +13126,7 @@
<expected-error>ASX1148: Cannot drop synonym test2.s2 being used by view test1.v1</expected-error>
<expected-error>ASX1148: Cannot drop view test2.v2 being used by view test1.v1</expected-error>
<expected-error>ASX1148: Cannot drop view test2.v2 being used by function test1.f1()</expected-error>
+ <expected-error>ASX1148: Cannot drop type test2.t1 being used by dataset test1.v1</expected-error>
<source-location>false</source-location>
</compilation-unit>
</test-case>
@@ -13069,6 +13135,14 @@
<output-dir compare="Text">view-1</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="view">
+ <compilation-unit name="view-2-negative">
+ <output-dir compare="Text">none</output-dir>
+ <expected-error>ASX1050: Cannot find dataset with name v1 in dataverse test1 (in line 24, at column 17)</expected-error>
+ <expected-error>ASX1050: Cannot find dataset with name v2 in dataverse test1 (in line 24, at column 17)</expected-error>
+ <expected-error>ASX1050: Cannot find dataset with name v3 in dataverse test1 (in line 24, at column 1)</expected-error>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="load">
<test-case FilePath="load">
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 97420ea..688601c 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,15 +19,18 @@
package org.apache.asterix.lang.common.statement;
-import static org.apache.asterix.lang.common.base.Statement.Kind.CREATE_VIEW;
-
import java.util.Objects;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.common.metadata.DataverseName;
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 {
@@ -35,24 +38,44 @@
private final String viewName;
+ private final TypeExpression itemType;
+
private final String viewBody;
private final Expression viewBodyExpression;
+ private final AdmObjectNode withObjectNode;
+
+ private final Boolean defaultNull;
+
private final boolean replaceIfExists;
private final boolean ifNotExists;
- public CreateViewStatement(DataverseName dataverseName, String viewName, String viewBody,
- Expression viewBodyExpression, boolean replaceIfExists, boolean ifNotExists) {
+ public CreateViewStatement(DataverseName dataverseName, String viewName, TypeExpression itemType, String viewBody,
+ Expression viewBodyExpression, Boolean defaultNull, RecordConstructor withRecord, boolean replaceIfExists,
+ boolean ifNotExists) throws CompilationException {
this.dataverseName = dataverseName;
this.viewName = Objects.requireNonNull(viewName);
+ this.itemType = itemType;
this.viewBody = Objects.requireNonNull(viewBody);
this.viewBodyExpression = Objects.requireNonNull(viewBodyExpression);
+ this.defaultNull = defaultNull;
+ this.withObjectNode = ViewUtil.validateAndGetWithObjectNode(withRecord, itemType != null);
this.replaceIfExists = replaceIfExists;
this.ifNotExists = ifNotExists;
}
+ @Override
+ public Kind getKind() {
+ return Statement.Kind.CREATE_VIEW;
+ }
+
+ @Override
+ public byte getCategory() {
+ return Category.DDL;
+ }
+
public DataverseName getDataverseName() {
return dataverseName;
}
@@ -61,6 +84,14 @@
return viewName;
}
+ public boolean hasItemType() {
+ return itemType != null;
+ }
+
+ public TypeExpression getItemType() {
+ return itemType;
+ }
+
public String getViewBody() {
return viewBody;
}
@@ -77,14 +108,22 @@
return ifNotExists;
}
- @Override
- public Kind getKind() {
- return CREATE_VIEW;
+ // Typed view parameters
+
+ public Boolean getDefaultNull() {
+ return defaultNull;
}
- @Override
- public byte getCategory() {
- return Category.DDL;
+ public String getDatetimeFormat() {
+ return withObjectNode.getOptionalString(ViewUtil.DATETIME_PARAMETER_NAME);
+ }
+
+ public String getDateFormat() {
+ return withObjectNode.getOptionalString(ViewUtil.DATE_PARAMETER_NAME);
+ }
+
+ public String getTimeFormat() {
+ return withObjectNode.getOptionalString(ViewUtil.TIME_PARAMETER_NAME);
}
@Override
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/ViewDecl.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/ViewDecl.java
index a3b1937..1e59f8d 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/ViewDecl.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/ViewDecl.java
@@ -31,7 +31,7 @@
private final DatasetFullyQualifiedName viewName;
- private Expression viewBody;
+ private final Expression viewBody;
private Expression viewBodyNormalized;
@@ -48,11 +48,6 @@
return viewBody;
}
- public void setViewBody(Expression expr) {
- viewBody = expr;
- viewBodyNormalized = null;
- }
-
public Expression getNormalizedViewBody() {
return viewBodyNormalized;
}
@@ -62,16 +57,6 @@
}
@Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
- ViewDecl viewDecl = (ViewDecl) o;
- return viewName.equals(viewDecl.viewName);
- }
-
- @Override
public Kind getKind() {
return Kind.VIEW_DECL;
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/DatasetDeclParametersUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/DatasetDeclParametersUtil.java
index 552ca39..8e91169 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/DatasetDeclParametersUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/DatasetDeclParametersUtil.java
@@ -62,7 +62,7 @@
* ***********************************************
*/
private static final ARecordType WITH_OBJECT_TYPE = getWithObjectType();
- private static final AdmObjectNode EMPTY_WITH_OBJECT = new AdmObjectNode();
+ static final AdmObjectNode EMPTY_WITH_OBJECT = new AdmObjectNode();
private DatasetDeclParametersUtil() {
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java
index 1fc7234..e6a3deb 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java
@@ -44,6 +44,7 @@
import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
import org.apache.asterix.lang.common.literal.StringLiteral;
import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.Query;
import org.apache.asterix.lang.common.statement.ViewDecl;
import org.apache.asterix.lang.common.visitor.GatherFunctionCallsVisitor;
import org.apache.asterix.object.base.AdmArrayNode;
@@ -55,6 +56,7 @@
import org.apache.asterix.object.base.AdmStringNode;
import org.apache.asterix.object.base.IAdmNode;
import org.apache.hyracks.algebricks.common.utils.Triple;
+import org.apache.hyracks.api.exceptions.SourceLocation;
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.Graphs;
@@ -246,4 +248,12 @@
}
}
}
+
+ public static Query createWrappedQuery(Expression expr, SourceLocation sourceLoc) {
+ Query wrappedQuery = new Query(false);
+ wrappedQuery.setSourceLocation(sourceLoc);
+ wrappedQuery.setBody(expr);
+ wrappedQuery.setTopLevel(false);
+ return wrappedQuery;
+ }
}
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 446b0ad..dfed99d 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,28 +21,60 @@
import java.io.StringReader;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.functions.FunctionSignature;
import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
import org.apache.asterix.common.metadata.DataverseName;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.IParser;
import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.IQueryRewriter;
+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;
import org.apache.asterix.lang.common.statement.ViewDecl;
+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;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.utils.Triple;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.api.exceptions.IWarningCollector;
import org.apache.hyracks.api.exceptions.SourceLocation;
public final class ViewUtil {
+ public static final String DATETIME_PARAMETER_NAME = BuiltinType.ADATETIME.getTypeName();
+ 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 {
@@ -79,4 +111,154 @@
return ViewDetails.createDependencies(datasetDependencies, functionDependencies, typeDependencies,
synonymDependencies);
}
+
+ public static void validateViewItemType(ARecordType recordType, SourceLocation sourceLoc)
+ throws CompilationException {
+ if (recordType.isOpen()) {
+ throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc, "view type cannot have open fields");
+ }
+ String[] fieldNames = recordType.getFieldNames();
+ IAType[] fieldTypes = recordType.getFieldTypes();
+ for (int i = 0, n = fieldNames.length; i < n; i++) {
+ IAType fieldType = fieldTypes[i];
+ if (fieldType.getTypeTag() != ATypeTag.UNION) {
+ throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc, String
+ .format("Invalid type for field %s. The type must allow MISSING and NULL", fieldNames[i]));
+ }
+ AUnionType unionType = (AUnionType) fieldType;
+ if (!unionType.isMissableType() || !unionType.isNullableType()) {
+ throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc, String
+ .format("Invalid type for field %s. The type must allow MISSING and NULL", fieldNames[i]));
+ }
+ IAType primeType = unionType.getActualType();
+ if (getTypeConstructor(primeType) == null) {
+ throw new CompilationException(ErrorCode.COMPILATION_TYPE_UNSUPPORTED, sourceLoc, "view",
+ primeType.getTypeName());
+ }
+ }
+ }
+
+ public static AdmObjectNode validateAndGetWithObjectNode(RecordConstructor withRecord, 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 (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");
+ }
+ }
+
+ public static Expression createTypeConvertExpression(Expression inExpr, IAType targetType,
+ Triple<String, String, String> temporalDataFormat, DatasetFullyQualifiedName viewName,
+ SourceLocation sourceLoc) throws CompilationException {
+ String format = temporalDataFormat != null ? getTemporalFormat(targetType, temporalDataFormat) : null;
+ boolean withFormat = format != null;
+ FunctionIdentifier constrFid =
+ withFormat ? getTypeConstructorWithFormat(targetType) : getTypeConstructor(targetType);
+ if (constrFid == null) {
+ throw new CompilationException(ErrorCode.COMPILATION_TYPE_UNSUPPORTED, sourceLoc, viewName.toString(),
+ targetType.getTypeName());
+ }
+ List<Expression> convertArgList = new ArrayList<>(2);
+ convertArgList.add(inExpr);
+ if (format != null) {
+ LiteralExpr formatExpr = new LiteralExpr(new StringLiteral(format));
+ formatExpr.setSourceLocation(sourceLoc);
+ convertArgList.add(formatExpr);
+ }
+ CallExpr convertExpr = new CallExpr(new FunctionSignature(constrFid), convertArgList);
+ convertExpr.setSourceLocation(inExpr.getSourceLocation());
+ return convertExpr;
+ }
+
+ public static Expression createMissingToNullExpression(Expression inExpr, SourceLocation sourceLoc) {
+ List<Expression> missing2NullArgs = new ArrayList<>(2);
+ missing2NullArgs.add(inExpr);
+ missing2NullArgs.add(new LiteralExpr(NullLiteral.INSTANCE));
+ CallExpr missing2NullExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.IF_MISSING), missing2NullArgs);
+ missing2NullExpr.setSourceLocation(sourceLoc);
+ return missing2NullExpr;
+ }
+
+ public static Expression createFieldAccessExpression(VarIdentifier inVar, String fieldName,
+ SourceLocation sourceLoc) {
+ VariableExpr inVarRef = new VariableExpr(inVar);
+ inVarRef.setSourceLocation(sourceLoc);
+ FieldAccessor fa = new FieldAccessor(inVarRef, new Identifier(fieldName));
+ fa.setSourceLocation(sourceLoc);
+ return fa;
+ }
+
+ public static FunctionIdentifier getTypeConstructor(IAType type) {
+ switch (type.getTypeTag()) {
+ case TINYINT:
+ return BuiltinFunctions.INT8_CONSTRUCTOR;
+ case SMALLINT:
+ return BuiltinFunctions.INT16_CONSTRUCTOR;
+ case INTEGER:
+ return BuiltinFunctions.INT32_CONSTRUCTOR;
+ case BIGINT:
+ return BuiltinFunctions.INT64_CONSTRUCTOR;
+ case FLOAT:
+ return BuiltinFunctions.FLOAT_CONSTRUCTOR;
+ case DOUBLE:
+ return BuiltinFunctions.DOUBLE_CONSTRUCTOR;
+ case BOOLEAN:
+ return BuiltinFunctions.BOOLEAN_CONSTRUCTOR;
+ case STRING:
+ return BuiltinFunctions.STRING_CONSTRUCTOR;
+ case DATE:
+ return BuiltinFunctions.DATE_CONSTRUCTOR;
+ case TIME:
+ return BuiltinFunctions.TIME_CONSTRUCTOR;
+ case DATETIME:
+ return BuiltinFunctions.DATETIME_CONSTRUCTOR;
+ case YEARMONTHDURATION:
+ return BuiltinFunctions.YEAR_MONTH_DURATION_CONSTRUCTOR;
+ case DAYTIMEDURATION:
+ return BuiltinFunctions.DAY_TIME_DURATION_CONSTRUCTOR;
+ case DURATION:
+ return BuiltinFunctions.DURATION_CONSTRUCTOR;
+ case UUID:
+ return BuiltinFunctions.UUID_CONSTRUCTOR;
+ case BINARY:
+ return BuiltinFunctions.BINARY_BASE64_CONSTRUCTOR;
+ default:
+ return null;
+ }
+ }
+
+ public static FunctionIdentifier getTypeConstructorWithFormat(IAType type) {
+ switch (type.getTypeTag()) {
+ case DATE:
+ return BuiltinFunctions.DATE_CONSTRUCTOR_WITH_FORMAT;
+ case TIME:
+ return BuiltinFunctions.TIME_CONSTRUCTOR_WITH_FORMAT;
+ case DATETIME:
+ return BuiltinFunctions.DATETIME_CONSTRUCTOR_WITH_FORMAT;
+ default:
+ return null;
+ }
+ }
+
+ public static String getTemporalFormat(IAType targetType, Triple<String, String, String> temporalFormatByType) {
+ switch (targetType.getTypeTag()) {
+ case DATETIME:
+ return temporalFormatByType.first;
+ case DATE:
+ return temporalFormatByType.second;
+ case TIME:
+ return temporalFormatByType.third;
+ default:
+ return null;
+ }
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
index 6287d2e..5ac1e2d 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
@@ -18,14 +18,36 @@
*/
package org.apache.asterix.lang.sqlpp.rewrites;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import org.apache.asterix.common.exceptions.CompilationException;
import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
+import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.IReturningStatement;
+import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.asterix.lang.common.util.ViewUtil;
+import org.apache.asterix.lang.sqlpp.clause.FromClause;
+import org.apache.asterix.lang.sqlpp.clause.FromTerm;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
+import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
+import org.apache.asterix.lang.sqlpp.clause.SelectClause;
+import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
+import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
+import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.utils.Triple;
+import org.apache.hyracks.api.exceptions.SourceLocation;
/**
* This rewriter is used to rewrite body expression of user defined functions and views
@@ -100,4 +122,51 @@
// Rewrites RIGHT OUTER JOINs into LEFT OUTER JOINs if possible
rewriteRightJoins();
}
+
+ static Expression castViewBodyAsType(LangRewritingContext context, Expression bodyExpr, IAType itemType,
+ Triple<String, String, String> temporalDataFormat, DatasetFullyQualifiedName viewName,
+ SourceLocation sourceLoc) throws CompilationException {
+ if (itemType.getTypeTag() != ATypeTag.OBJECT) {
+ throw new CompilationException(ErrorCode.COMPILATION_TYPE_UNSUPPORTED, sourceLoc, viewName,
+ itemType.getTypeName());
+ }
+ ARecordType recordType = (ARecordType) itemType;
+ if (recordType.isOpen()) {
+ throw new CompilationException(ErrorCode.COMPILATION_TYPE_UNSUPPORTED, sourceLoc, viewName,
+ itemType.getTypeName());
+ }
+ String[] fieldNames = recordType.getFieldNames();
+ IAType[] fieldTypes = recordType.getFieldTypes();
+ int n = fieldNames.length;
+ if (n == 0) {
+ throw new CompilationException(ErrorCode.COMPILATION_TYPE_UNSUPPORTED, sourceLoc, viewName,
+ itemType.getTypeName());
+ }
+ List<Projection> projections = new ArrayList<>(n);
+ VarIdentifier fromVar = context.newVariable();
+ for (int i = 0; i < n; i++) {
+ String fieldName = fieldNames[i];
+ IAType targetType = TypeComputeUtils.getActualType(fieldTypes[i]);
+ Expression expr = ViewUtil.createFieldAccessExpression(fromVar, fieldName, sourceLoc);
+ expr = ViewUtil.createMissingToNullExpression(expr, sourceLoc); // Default Null handling
+ Expression projectExpr =
+ ViewUtil.createTypeConvertExpression(expr, targetType, temporalDataFormat, viewName, sourceLoc);
+ projections.add(new Projection(projectExpr, fieldName, false, false));
+ }
+
+ VariableExpr fromVarRef = new VariableExpr(fromVar);
+ fromVarRef.setSourceLocation(sourceLoc);
+ FromClause fromClause =
+ new FromClause(Collections.singletonList(new FromTerm(bodyExpr, fromVarRef, null, null)));
+ fromClause.setSourceLocation(sourceLoc);
+ SelectClause selectClause = new SelectClause(null, new SelectRegular(projections), false);
+ selectClause.setSourceLocation(sourceLoc);
+ SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null);
+ selectBlock.setSourceLocation(sourceLoc);
+ SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
+ selectSetOperation.setSourceLocation(sourceLoc);
+ SelectExpression selectExpression = new SelectExpression(null, selectSetOperation, null, null, true);
+ selectExpression.setSourceLocation(sourceLoc);
+ return selectExpression;
+ }
}
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 f07e614..7b2e5e3 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
@@ -76,12 +76,15 @@
import org.apache.asterix.lang.sqlpp.rewrites.visitor.VariableCheckAndRewriteVisitor;
import org.apache.asterix.lang.sqlpp.util.SqlppAstPrintUtil;
import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+import org.apache.asterix.metadata.bootstrap.MetadataBuiltinEntities;
import org.apache.asterix.metadata.declared.MetadataProvider;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.Dataverse;
import org.apache.asterix.metadata.entities.Function;
import org.apache.asterix.metadata.entities.ViewDetails;
import org.apache.asterix.metadata.utils.DatasetUtil;
+import org.apache.asterix.metadata.utils.TypeUtil;
+import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.algebricks.common.utils.Triple;
@@ -396,10 +399,8 @@
DatasetFullyQualifiedName viewName = dsArgs.first;
if (!views.containsKey(viewName)) {
ViewDecl viewDecl = fetchViewDecl(viewName, fnCall.getSourceLocation());
- if (viewDecl != null) {
- views.put(viewName, viewDecl);
- viewDecl.getNormalizedViewBody().accept(callVisitor, null);
- }
+ views.put(viewName, viewDecl);
+ viewDecl.getNormalizedViewBody().accept(callVisitor, null);
}
}
}
@@ -451,6 +452,9 @@
private ViewDecl fetchViewDecl(DatasetFullyQualifiedName viewName, SourceLocation sourceLoc)
throws CompilationException {
+ IAType viewItemType = null;
+ Boolean defaultNull = false;
+ Triple<String, String, String> temporalDataFormat = null;
ViewDecl viewDecl = context.getDeclaredViews().get(viewName);
if (viewDecl == null) {
Dataset dataset;
@@ -465,10 +469,26 @@
ViewDetails viewDetails = (ViewDetails) dataset.getDatasetDetails();
viewDecl = ViewUtil.parseStoredView(viewName, viewDetails, parserFactory, context.getWarningCollector(),
sourceLoc);
+ DataverseName itemTypeDataverseName = dataset.getItemTypeDataverseName();
+ String itemTypeName = dataset.getItemTypeName();
+ boolean isAnyType =
+ MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDataverseName().equals(itemTypeDataverseName)
+ && MetadataBuiltinEntities.ANY_OBJECT_DATATYPE.getDatatypeName().equals(itemTypeName);
+ if (!isAnyType) {
+ try {
+ viewItemType = metadataProvider.findType(itemTypeDataverseName, itemTypeName);
+ } catch (AlgebricksException e) {
+ throw new CompilationException(ErrorCode.UNKNOWN_TYPE,
+ TypeUtil.getFullyQualifiedDisplayName(itemTypeDataverseName, itemTypeName));
+ }
+ defaultNull = viewDetails.getDefaultNull();
+ temporalDataFormat = new Triple<>(viewDetails.getDatetimeFormat(), viewDetails.getDateFormat(),
+ viewDetails.getTimeFormat());
+ }
}
Expression normBody = viewDecl.getNormalizedViewBody();
if (normBody == null) {
- normBody = rewriteViewBody(viewDecl);
+ normBody = rewriteViewBody(viewDecl, viewItemType, defaultNull, temporalDataFormat);
viewDecl.setNormalizedViewBody(normBody);
}
return viewDecl;
@@ -480,10 +500,21 @@
!fnDecl.isStored(), fnDecl.getSourceLocation());
}
- private Expression rewriteViewBody(ViewDecl viewDecl) throws CompilationException {
+ private Expression rewriteViewBody(ViewDecl viewDecl, IAType viewItemType, Boolean defaultNull,
+ Triple<String, String, String> temporalDataFormat) throws CompilationException {
DatasetFullyQualifiedName viewName = viewDecl.getViewName();
- return rewriteFunctionOrViewBody(viewName.getDataverseName(), viewName, viewDecl.getViewBody(),
- Collections.emptyList(), false, viewDecl.getSourceLocation());
+ SourceLocation sourceLoc = viewDecl.getSourceLocation();
+ Expression rewrittenBodyExpr = rewriteFunctionOrViewBody(viewName.getDataverseName(), viewName,
+ viewDecl.getViewBody(), Collections.emptyList(), false, sourceLoc);
+ if (viewItemType != null) {
+ if (!Boolean.TRUE.equals(defaultNull)) {
+ throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
+ "Default Null is required");
+ }
+ rewrittenBodyExpr = SqlppFunctionBodyRewriter.castViewBodyAsType(context, rewrittenBodyExpr, viewItemType,
+ temporalDataFormat, viewName, sourceLoc);
+ }
+ return rewrittenBodyExpr;
}
private Expression rewriteFunctionOrViewBody(DataverseName entityDataverseName, Object entityDisplayName,
@@ -503,7 +534,7 @@
metadataProvider.setDefaultDataverse(targetDataverse);
try {
- Query wrappedQuery = createWrappedQuery(bodyExpr, sourceLoc);
+ Query wrappedQuery = ExpressionUtils.createWrappedQuery(bodyExpr, sourceLoc);
getFunctionAndViewBodyRewriter().rewrite(context, wrappedQuery, allowNonStoredUdfCalls, false,
externalVars);
return wrappedQuery.getBody();
@@ -531,8 +562,7 @@
: Collections.nCopies(arity, new LiteralExpr(MissingLiteral.INSTANCE));
CallExpr fcall = new CallExpr(functionSignature, args);
fcall.setSourceLocation(functionDecl.getSourceLocation());
-
- return createWrappedQuery(fcall, functionDecl.getSourceLocation());
+ return ExpressionUtils.createWrappedQuery(fcall, functionDecl.getSourceLocation());
}
@Override
@@ -540,26 +570,22 @@
// dataverse_name.view_name
DataverseName dataverseName = viewDecl.getViewName().getDataverseName();
String viewName = viewDecl.getViewName().getDatasetName();
- SourceLocation sourceLoc = viewDecl.getSourceLocation();
- List<String> dataverseNameParts = dataverseName.getParts();
- AbstractExpression vAccessExpr = null;
- for (int i = 0, n = dataverseNameParts.size(); i < n; i++) {
- String part = dataverseNameParts.get(i);
- vAccessExpr = i == 0 ? new VariableExpr(new VarIdentifier(SqlppVariableUtil.toInternalVariableName(part)))
- : new FieldAccessor(vAccessExpr, new Identifier(part));
- vAccessExpr.setSourceLocation(sourceLoc);
- }
- vAccessExpr = new FieldAccessor(vAccessExpr, new Identifier(viewName));
- vAccessExpr.setSourceLocation(sourceLoc);
-
- return createWrappedQuery(vAccessExpr, viewDecl.getSourceLocation());
+ Expression vAccessExpr = createDatasetAccessExpression(dataverseName, viewName, viewDecl.getSourceLocation());
+ return ExpressionUtils.createWrappedQuery(vAccessExpr, viewDecl.getSourceLocation());
}
- private static Query createWrappedQuery(Expression expr, SourceLocation sourceLoc) {
- Query wrappedQuery = new Query(false);
- wrappedQuery.setSourceLocation(sourceLoc);
- wrappedQuery.setBody(expr);
- wrappedQuery.setTopLevel(false);
- return wrappedQuery;
+ private static Expression createDatasetAccessExpression(DataverseName dataverseName, String datasetName,
+ SourceLocation sourceLoc) {
+ AbstractExpression resultExpr = null;
+ List<String> dataverseNameParts = dataverseName.getParts();
+ for (int i = 0, n = dataverseNameParts.size(); i < n; i++) {
+ String part = dataverseNameParts.get(i);
+ resultExpr = i == 0 ? new VariableExpr(new VarIdentifier(SqlppVariableUtil.toInternalVariableName(part)))
+ : new FieldAccessor(resultExpr, new Identifier(part));
+ resultExpr.setSourceLocation(sourceLoc);
+ }
+ resultExpr = new FieldAccessor(resultExpr, new Identifier(datasetName));
+ resultExpr.setSourceLocation(sourceLoc);
+ return resultExpr;
}
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index b51dc3c..38529a5 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -225,6 +225,7 @@
// tokens parsed as identifiers
private static final String CUBE = "CUBE";
private static final String CURRENT = "CURRENT";
+ private static final String DEFAULT = "DEFAULT";
private static final String EXCLUDE = "EXCLUDE";
private static final String FIRST = "FIRST";
private static final String FOLLOWING = "FOLLOWING";
@@ -1043,7 +1044,7 @@
}
}
-TypeExpression DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
+RecordTypeDefinition DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
{
RecordTypeDefinition recordTypeDef = null;
RecordTypeDefinition.RecordKind recordKind = null;
@@ -1417,17 +1418,29 @@
CreateViewStatement ViewSpecification(Token startStmtToken, boolean orReplace) throws ParseException:
{
Pair<DataverseName, Identifier> nameComponents = null;
+ TypeExpression typeExpr = null;
boolean ifNotExists = false;
Token beginPos = null, endPos = null;
Expression viewBodyExpr = null;
+ Boolean defaultNull = null;
+ RecordConstructor withRecord = null;
DataverseName currentDataverse = defaultDataverse;
}
{
nameComponents = QualifiedName()
- ifNotExists = IfNotExists()
+ (
+ (
+ typeExpr = DatasetTypeSpecification()
+ ifNotExists = IfNotExists()
+ <IDENTIFIER> { expectToken(DEFAULT); } <NULL> { defaultNull = true; }
+ ( <WITH> withRecord = RecordConstructor() )?
+ )
+ |
+ ( ifNotExists = IfNotExists() )
+ )
{
if (orReplace && ifNotExists) {
- throw new SqlppParseException(getSourceLocation(token), "Unexpected IF NOT EXISTS");
+ throw new SqlppParseException(getSourceLocation(startStmtToken), "Unexpected IF NOT EXISTS");
}
}
<AS>
@@ -1445,9 +1458,13 @@
endPos.endColumn + 1);
removeCurrentScope();
defaultDataverse = currentDataverse;
- CreateViewStatement stmt = new CreateViewStatement(nameComponents.first, nameComponents.second.getValue(), viewBody,
- viewBodyExpr, orReplace, ifNotExists);
+ try {
+ CreateViewStatement stmt = new CreateViewStatement(nameComponents.first, nameComponents.second.getValue(),
+ typeExpr, viewBody, viewBodyExpr, defaultNull, withRecord, orReplace, ifNotExists);
return addSourceLocation(stmt, startStmtToken);
+ } catch (CompilationException e) {
+ throw new SqlppParseException(getSourceLocation(startStmtToken), e.getMessage());
+ }
}
}
@@ -1456,7 +1473,10 @@
Expression viewBodyExpr = null;
}
{
- viewBodyExpr = SelectExpression(true)
+ (
+ ( viewBodyExpr = VariableRef() ( viewBodyExpr = FieldAccessor(viewBodyExpr) )* )
+ | viewBodyExpr = SelectExpression(true)
+ )
{
return viewBodyExpr;
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
index ef9f5d7..567568d 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
@@ -48,6 +48,7 @@
public static final String FIELD_NAME_DATATYPE_NAME = "DatatypeName";
public static final String FIELD_NAME_DATAVERSE_NAME = "DataverseName";
public static final String FIELD_NAME_DATA_FORMAT = "DataFormat";
+ public static final String FIELD_NAME_DEFAULT = "Default";
public static final String FIELD_NAME_DEFINITION = "Definition";
public static final String FIELD_NAME_DEPENDENCIES = "Dependencies";
public static final String FIELD_NAME_DERIVED = "Derived";
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/ViewDetails.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/ViewDetails.java
index 5c884d9..4e6f96d 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/ViewDetails.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/ViewDetails.java
@@ -37,6 +37,7 @@
import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
import org.apache.asterix.metadata.entitytupletranslators.AbstractTupleTranslator;
import org.apache.asterix.om.base.AMutableString;
+import org.apache.asterix.om.base.ANull;
import org.apache.asterix.om.base.AString;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.utils.RecordUtil;
@@ -49,13 +50,36 @@
private static final long serialVersionUID = 1L;
+ public static List<DependencyKind> DEPENDENCIES_SCHEMA =
+ Arrays.asList(DependencyKind.DATASET, DependencyKind.FUNCTION, DependencyKind.TYPE, DependencyKind.SYNONYM);
+
private final String viewBody;
private final List<List<Triple<DataverseName, String, String>>> dependencies;
- public ViewDetails(String viewBody, List<List<Triple<DataverseName, String, String>>> dependencies) {
+ // Typed view parameters
+
+ private final Boolean defaultNull;
+
+ private final String datetimeFormat;
+
+ private final String dateFormat;
+
+ private final String timeFormat;
+
+ public ViewDetails(String viewBody, List<List<Triple<DataverseName, String, String>>> dependencies,
+ Boolean defaultNull, String datetimeFormat, String dateFormat, String timeFormat) {
this.viewBody = Objects.requireNonNull(viewBody);
this.dependencies = Objects.requireNonNull(dependencies);
+ this.defaultNull = defaultNull;
+ this.datetimeFormat = datetimeFormat;
+ this.dateFormat = dateFormat;
+ this.timeFormat = timeFormat;
+ }
+
+ @Override
+ public DatasetConfig.DatasetType getDatasetType() {
+ return DatasetConfig.DatasetType.VIEW;
}
public String getViewBody() {
@@ -66,9 +90,22 @@
return dependencies;
}
- @Override
- public DatasetConfig.DatasetType getDatasetType() {
- return DatasetConfig.DatasetType.VIEW;
+ // Typed view fields
+
+ public Boolean getDefaultNull() {
+ return defaultNull;
+ }
+
+ public String getDatetimeFormat() {
+ return datetimeFormat;
+ }
+
+ public String getDateFormat() {
+ return dateFormat;
+ }
+
+ public String getTimeFormat() {
+ return timeFormat;
}
@Override
@@ -84,6 +121,9 @@
ISerializerDeserializer<AString> stringSerde =
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ASTRING);
+ ISerializerDeserializer<ANull> nullSerde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ANULL);
+
// write field 'Definition'
fieldName.reset();
aString.setValue(MetadataRecordTypes.FIELD_NAME_DEFINITION);
@@ -130,12 +170,42 @@
viewRecordBuilder.addField(fieldName, fieldValue);
}
+ // write field 'DefaultNull'
+ if (defaultNull != null && defaultNull) {
+ fieldName.reset();
+ aString.setValue(MetadataRecordTypes.FIELD_NAME_DEFAULT);
+ stringSerde.serialize(aString, fieldName.getDataOutput());
+ fieldValue.reset();
+ nullSerde.serialize(ANull.NULL, fieldValue.getDataOutput());
+ viewRecordBuilder.addField(fieldName, fieldValue);
+ }
+
+ // write field 'Format'
+ if (datetimeFormat != null || dateFormat != null || timeFormat != null) {
+ fieldName.reset();
+ aString.setValue(MetadataRecordTypes.FIELD_NAME_DATA_FORMAT);
+ stringSerde.serialize(aString, fieldName.getDataOutput());
+
+ OrderedListBuilder formatListBuilder = new OrderedListBuilder();
+ formatListBuilder.reset(FULL_OPEN_ORDEREDLIST_TYPE);
+ for (String format : new String[] { datetimeFormat, dateFormat, timeFormat }) {
+ itemValue.reset();
+ if (format == null) {
+ nullSerde.serialize(ANull.NULL, itemValue.getDataOutput());
+ } else {
+ aString.setValue(format);
+ stringSerde.serialize(aString, itemValue.getDataOutput());
+ }
+ formatListBuilder.addItem(itemValue);
+ }
+ fieldValue.reset();
+ formatListBuilder.write(fieldValue.getDataOutput(), true);
+ viewRecordBuilder.addField(fieldName, fieldValue);
+ }
+
viewRecordBuilder.write(out, true);
}
- public static List<DependencyKind> DEPENDENCIES_SCHEMA =
- Arrays.asList(DependencyKind.DATASET, DependencyKind.FUNCTION, DependencyKind.TYPE, DependencyKind.SYNONYM);
-
public static List<List<Triple<DataverseName, String, String>>> createDependencies(
List<Triple<DataverseName, String, String>> datasetDependencies,
List<Triple<DataverseName, String, String>> functionDependencies,
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
index 51753f2..1fe51b3 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
@@ -59,9 +59,11 @@
import org.apache.asterix.om.base.AString;
import org.apache.asterix.om.base.AUnorderedList;
import org.apache.asterix.om.base.IACursor;
+import org.apache.asterix.om.base.IAObject;
import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
import org.apache.asterix.om.types.AOrderedListType;
import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.AUnorderedListType;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
@@ -263,7 +265,35 @@
}
}
- datasetDetails = new ViewDetails(definition, dependencies);
+ // Default Null
+ Boolean defaultNull = null;
+ int defaultFieldPos =
+ datasetDetailsRecord.getType().getFieldIndex(MetadataRecordTypes.FIELD_NAME_DEFAULT);
+ if (defaultFieldPos >= 0) {
+ IAObject defaultValue = datasetDetailsRecord.getValueByPos(defaultFieldPos);
+ defaultNull = defaultValue.getType().getTypeTag() == ATypeTag.NULL;
+ }
+
+ // Format fields
+ String datetimeFormat = null, dateFormat = null, timeFormat = null;
+ int formatFieldPos =
+ datasetDetailsRecord.getType().getFieldIndex(MetadataRecordTypes.FIELD_NAME_DATA_FORMAT);
+ if (formatFieldPos >= 0) {
+ IACursor formatCursor =
+ ((AOrderedList) datasetDetailsRecord.getValueByPos(formatFieldPos)).getCursor();
+ if (formatCursor.next()) {
+ datetimeFormat = getStringValue(formatCursor.get());
+ if (formatCursor.next()) {
+ dateFormat = getStringValue(formatCursor.get());
+ if (formatCursor.next()) {
+ timeFormat = getStringValue(formatCursor.get());
+ }
+ }
+ }
+ }
+
+ datasetDetails =
+ new ViewDetails(definition, dependencies, defaultNull, datetimeFormat, dateFormat, timeFormat);
break;
}
}
@@ -336,6 +366,10 @@
return CompressionManager.NONE;
}
+ private static String getStringValue(IAObject obj) {
+ return obj.getType().getTypeTag() == ATypeTag.STRING ? ((AString) obj).getStringValue() : null;
+ }
+
@Override
public ITupleReference getTupleFromMetadataEntity(Dataset dataset) throws HyracksDataException {
OrderedListBuilder listBuilder = new OrderedListBuilder();