You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2021/07/27 14:52:08 UTC

[asterixdb] branch master updated: [NO ISSUE][COMP] Support typed views

This is an automated email from the ASF dual-hosted git repository.

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 33c77f9  [NO ISSUE][COMP] Support typed views
33c77f9 is described below

commit 33c77f986ffbbf8c07f5f6357764c00b7885c295
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Wed Jul 21 15:59:04 2021 -0700

    [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 <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
 .../asterix/app/function/DatasetRewriter.java      |   5 +-
 .../asterix/app/translator/QueryTranslator.java    | 225 ++++++++++++---------
 .../create-index-6/create-index-6.1.ddl.sqlpp}     |  38 +++-
 .../create-index-6/create-index-6.2.ddl.sqlpp      |  60 ++++++
 .../create-view-3-typed.1.ddl.sqlpp                |  72 +++++++
 .../create-view-3-typed.2.update.sqlpp             |  79 ++++++++
 .../create-view-3-typed.3.query.sqlpp}             |  21 +-
 .../create-view-3-typed.4.query.sqlpp}             |  21 +-
 .../create-view-3-typed.5.query.sqlpp}             |  18 +-
 .../create-view-3-typed.6.query.sqlpp}             |  17 +-
 .../create-view-3-typed.7.query.sqlpp}             |  18 +-
 .../create-view-4-typed-warn.1.ddl.sqlpp}          |  18 +-
 .../create-view-4-typed-warn.2.update.sqlpp}       |  31 +--
 .../create-view-4-typed-warn.3.query.sqlpp}        |  22 +-
 .../create-view-5-typed-warn.1.ddl.sqlpp}          |  20 +-
 .../create-view-5-typed-warn.2.update.sqlpp}       |  20 +-
 .../create-view-5-typed-warn.3.query.sqlpp}        |  19 +-
 .../create-view-6-typed-negative.1.ddl.sqlpp}      |  17 +-
 .../create-view-6-typed-negative.2.ddl.sqlpp}      |  17 +-
 .../create-view-6-typed-negative.3.ddl.sqlpp}      |  19 +-
 .../create-view-6-typed-negative.4.ddl.sqlpp}      |  20 +-
 .../create-view-6-typed-negative.5.ddl.sqlpp}      |  17 +-
 .../create-view-6-typed-negative.6.ddl.sqlpp}      |  19 +-
 .../create-view-6-typed-negative.7.ddl.sqlpp}      |  22 +-
 .../create-view-6-typed-negative.8.ddl.sqlpp}      |  17 +-
 .../drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp  |   6 +-
 .../drop-dataverse-2-negative.6.ddl.sqlpp}         |  15 +-
 .../drop-view-1.3.ddl.sqlpp}                       |  21 +-
 .../drop-view-1.4.query.sqlpp}                     |  17 +-
 .../drop-view-1.5.query.sqlpp}                     |  18 +-
 .../drop-view-2-negative.17.ddl.sqlpp}             |  14 +-
 .../drop-view-2-negative.18.query.sqlpp}           |  18 +-
 .../view-2-negative.1.ddl.sqlpp}                   |  12 +-
 .../view-2-negative.2.update.sqlpp}                |  18 +-
 .../view-2-negative.3.update.sqlpp}                |  17 +-
 .../view-2-negative.4.update.sqlpp}                |  17 +-
 .../view-2-negative.5.update.sqlpp}                |  16 +-
 .../create-view-3-typed/create-view-3-typed.3.adm  |   5 +
 .../create-view-3-typed/create-view-3-typed.4.adm  |   5 +
 .../create-view-3-typed/create-view-3-typed.5.adm  |   3 +
 .../create-view-3-typed/create-view-3-typed.6.adm  |   3 +
 .../create-view-3-typed/create-view-3-typed.7.adm  |   4 +
 .../create-view-4-typed-warn.3.adm                 |   2 +
 .../create-view-5-typed-warn.3.adm                 |   1 +
 .../results/view/drop-view-1/drop-view-1.4.adm     |   1 +
 .../results/view/drop-view-1/drop-view-1.5.adm     |   1 +
 .../drop-view-2-negative.18.adm                    |   1 +
 .../test/resources/runtimets/testsuite_sqlpp.xml   |  76 ++++++-
 .../lang/common/statement/CreateViewStatement.java |  59 +++++-
 .../asterix/lang/common/statement/ViewDecl.java    |  17 +-
 .../common/util/DatasetDeclParametersUtil.java     |   2 +-
 .../asterix/lang/common/util/ExpressionUtils.java  |  10 +
 .../apache/asterix/lang/common/util/ViewUtil.java  | 182 +++++++++++++++++
 .../sqlpp/rewrites/SqlppFunctionBodyRewriter.java  |  69 +++++++
 .../lang/sqlpp/rewrites/SqlppQueryRewriter.java    |  82 +++++---
 .../asterix-lang-sqlpp/src/main/javacc/SQLPP.jj    |  32 ++-
 .../metadata/bootstrap/MetadataRecordTypes.java    |   1 +
 .../asterix/metadata/entities/ViewDetails.java     |  84 +++++++-
 .../DatasetTupleTranslator.java                    |  36 +++-
 59 files changed, 1192 insertions(+), 525 deletions(-)

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 @@ public class DatasetRewriter implements IFunctionToDataSourceRewriter, IResultTy
             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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
                 }
             }
 
-            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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
             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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         }
     }
 
+    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 class QueryTranslator extends AbstractLangTranslator implements IStatemen
     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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
     }
 
     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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
                 }
             }
 
+            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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
             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 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
                         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/view/drop-dataverse-1/drop-dataverse-1.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
similarity index 51%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/create-index/create-index-6/create-index-6.1.ddl.sqlpp
index 27ae6ab..bcf65d2 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/ddl/create-index/create-index-6/create-index-6.1.ddl.sqlpp
@@ -16,18 +16,40 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+/*
+ * Description  : Create index on a view
+ * Expected Res : Failure
+ */
 
---- test drop dataverse with views
+drop  dataverse test if exists;
+create  dataverse test;
 
-drop dataverse test1 if exists;
-create dataverse test1;
+use test;
 
-create view test1.v1 as
-  select r from range(0,2) r;
+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 view test1.v2 as
-  select v1.* from v1;
+create dataset LineItem(LineItemType) primary key l_orderkey;
 
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.3.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.3.query.sqlpp
index 27ae6ab..c8126cd 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/create-view-3-typed/create-view-3-typed.3.query.sqlpp
@@ -17,17 +17,12 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.4.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.4.query.sqlpp
index 27ae6ab..59a713a 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/create-view-3-typed/create-view-3-typed.4.query.sqlpp
@@ -17,17 +17,12 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.5.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.5.query.sqlpp
index 27ae6ab..19be7a9 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/create-view-3-typed/create-view-3-typed.5.query.sqlpp
@@ -17,17 +17,9 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.6.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.6.query.sqlpp
index 27ae6ab..fd96010 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/create-view-3-typed/create-view-3-typed.6.query.sqlpp
@@ -17,17 +17,8 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.7.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-3-typed/create-view-3-typed.7.query.sqlpp
index 27ae6ab..8c5d268 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/create-view-3-typed/create-view-3-typed.7.query.sqlpp
@@ -17,17 +17,7 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
-
+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/drop-dataverse-1/drop-dataverse-1.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
similarity index 70%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.1.ddl.sqlpp
index 27ae6ab..2c39dd1 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/create-view-4-typed-warn/create-view-4-typed-warn.1.ddl.sqlpp
@@ -17,17 +17,17 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
 drop dataverse test1 if exists;
 create dataverse test1;
 
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop 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/drop-dataverse-1/drop-dataverse-1.1.ddl.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
similarity index 53%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.2.update.sqlpp
index 27ae6ab..644893f 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/create-view-4-typed-warn/create-view-4-typed-warn.2.update.sqlpp
@@ -17,17 +17,24 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-4-typed-warn/create-view-4-typed-warn.3.query.sqlpp
index 27ae6ab..e600abd 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/create-view-4-typed-warn/create-view-4-typed-warn.3.query.sqlpp
@@ -17,17 +17,15 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+// 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/drop-dataverse-1/drop-dataverse-1.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
similarity index 72%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp
index 27ae6ab..6e90398 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/create-view-5-typed-warn/create-view-5-typed-warn.1.ddl.sqlpp
@@ -17,17 +17,19 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
 drop dataverse test1 if exists;
 create dataverse test1;
 
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop 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/drop-dataverse-1/drop-dataverse-1.1.ddl.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.2.update.sqlpp
index 27ae6ab..3a6173f 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/create-view-5-typed-warn/create-view-5-typed-warn.2.update.sqlpp
@@ -17,17 +17,13 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-5-typed-warn/create-view-5-typed-warn.3.query.sqlpp
index 27ae6ab..dd71835 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/create-view-5-typed-warn/create-view-5-typed-warn.3.query.sqlpp
@@ -17,17 +17,12 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+// 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/drop-dataverse-1/drop-dataverse-1.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.1.ddl.sqlpp
index 27ae6ab..859b498 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/create-view-6-typed-negative/create-view-6-typed-negative.1.ddl.sqlpp
@@ -17,17 +17,10 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+--- 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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.2.ddl.sqlpp
index 27ae6ab..571d3d9 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/create-view-6-typed-negative/create-view-6-typed-negative.2.ddl.sqlpp
@@ -17,17 +17,10 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+--- 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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.3.ddl.sqlpp
index 27ae6ab..73de71e 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/create-view-6-typed-negative/create-view-6-typed-negative.3.ddl.sqlpp
@@ -17,17 +17,14 @@
  * under the License.
  */
 
---- test drop dataverse with views
+--- Negative: view type is not closed
 
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 77%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.4.ddl.sqlpp
index 27ae6ab..e900a32 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/create-view-6-typed-negative/create-view-6-typed-negative.4.ddl.sqlpp
@@ -17,17 +17,15 @@
  * under the License.
  */
 
---- test drop dataverse with views
+--- Negative: view type has non-primitive fields
 
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.5.ddl.sqlpp
index 27ae6ab..4b814bf 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/create-view-6-typed-negative/create-view-6-typed-negative.5.ddl.sqlpp
@@ -17,17 +17,10 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+--- 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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.6.ddl.sqlpp
index 27ae6ab..dc344c3 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/create-view-6-typed-negative/create-view-6-typed-negative.6.ddl.sqlpp
@@ -17,17 +17,14 @@
  * under the License.
  */
 
---- test drop dataverse with views
+--- Negative: view type has non-optional fields
 
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 75%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.7.ddl.sqlpp
index 27ae6ab..6197dae 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/create-view-6-typed-negative/create-view-6-typed-negative.7.ddl.sqlpp
@@ -17,17 +17,15 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+--- 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/drop-dataverse-1/drop-dataverse-1.1.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
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/create-view-6-typed-negative/create-view-6-typed-negative.8.ddl.sqlpp
index 27ae6ab..adb53a8 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/create-view-6-typed-negative/create-view-6-typed-negative.8.ddl.sqlpp
@@ -17,17 +17,10 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+--- 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.v1 as
 create view test1.v2 as
   select v1.* from v1;
 
-drop dataverse test1;
+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-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-2-negative/drop-dataverse-2-negative.6.ddl.sqlpp
similarity index 74%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-2-negative/drop-dataverse-2-negative.6.ddl.sqlpp
index 27ae6ab..130e769 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-2-negative/drop-dataverse-2-negative.6.ddl.sqlpp
@@ -17,17 +17,18 @@
  * under the License.
  */
 
---- test drop dataverse with views
+--- Test that DROP DATAVERSE fails due to cross-dataverse dependencies
+
+--- View depends on datatype
 
 drop dataverse test1 if exists;
 create dataverse test1;
 
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
+drop dataverse test2 if exists;
+create dataverse test2;
 
-drop dataverse test1;
+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-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.3.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.3.ddl.sqlpp
index 27ae6ab..c64efbd 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-view-1/drop-view-1.3.ddl.sqlpp
@@ -17,17 +17,22 @@
  * under the License.
  */
 
---- test drop dataverse with views
+/* Drop views and inline types, user-defined datatype must remain in the dataverse */
 
-drop dataverse test1 if exists;
-create dataverse test1;
+drop dataverse test if exists;
+create dataverse test;
 
-create view test1.v1 as
-  select r from range(0,2) r;
+create view test.v1 as
+  select r from range(1,2) r;
 
-create view test1.v2 as
-  select v1.* from v1;
+create view test.v2(r bigint) default null as v1;
 
-drop dataverse test1;
+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-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.4.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.4.query.sqlpp
index 27ae6ab..4c8483e 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-view-1/drop-view-1.4.query.sqlpp
@@ -17,17 +17,6 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
-
+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-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.5.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-1/drop-view-1.5.query.sqlpp
index 27ae6ab..5bf0799 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-view-1/drop-view-1.5.query.sqlpp
@@ -17,17 +17,7 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
-
+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-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.17.ddl.sqlpp
similarity index 77%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.17.ddl.sqlpp
index 27ae6ab..0fbb626 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-view-2-negative/drop-view-2-negative.17.ddl.sqlpp
@@ -17,17 +17,17 @@
  * under the License.
  */
 
---- test drop dataverse with views
+--- Negative: drop type fails if a view depends on it
 
 drop dataverse test1 if exists;
 create dataverse test1;
 
-create view test1.v1 as
-  select r from range(0,2) r;
+drop dataverse test2 if exists;
+create dataverse test2;
 
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.18.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-view-2-negative/drop-view-2-negative.18.query.sqlpp
index 27ae6ab..29f7a8d 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-view-2-negative/drop-view-2-negative.18.query.sqlpp
@@ -17,17 +17,9 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
+-- 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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.1.ddl.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.1.ddl.sqlpp
index 27ae6ab..90f0d31 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/view-2-negative/view-2-negative.1.ddl.sqlpp
@@ -17,17 +17,15 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
 drop dataverse test1 if exists;
 create dataverse test1;
 
-create view test1.v1 as
-  select r from range(0,2) r;
+use test1;
 
-create view test1.v2 as
-  select v1.* from v1;
+create dataset t1(id bigint not unknown, v string) primary key id;
 
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.2.update.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.2.update.sqlpp
index 27ae6ab..5e4b305 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/view-2-negative/view-2-negative.2.update.sqlpp
@@ -17,17 +17,9 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
-
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.3.update.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.3.update.sqlpp
index 27ae6ab..89507a0 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/view-2-negative/view-2-negative.3.update.sqlpp
@@ -17,17 +17,10 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.4.update.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.4.update.sqlpp
index 27ae6ab..103f7f1 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/view-2-negative/view-2-negative.4.update.sqlpp
@@ -17,17 +17,10 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.5.update.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/drop-dataverse-1/drop-dataverse-1.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/view/view-2-negative/view-2-negative.5.update.sqlpp
index 27ae6ab..b3e5524 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/view-2-negative/view-2-negative.5.update.sqlpp
@@ -17,17 +17,9 @@
  * under the License.
  */
 
---- test drop dataverse with views
-
-drop dataverse test1 if exists;
-create dataverse test1;
-
-create view test1.v1 as
-  select r from range(0,2) r;
-
-create view test1.v2 as
-  select v1.* from v1;
-
-drop dataverse test1;
+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 @@ public final class CreateViewStatement extends AbstractStatement {
 
     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 @@ public final class CreateViewStatement extends AbstractStatement {
         return viewName;
     }
 
+    public boolean hasItemType() {
+        return itemType != null;
+    }
+
+    public TypeExpression getItemType() {
+        return itemType;
+    }
+
     public String getViewBody() {
         return viewBody;
     }
@@ -77,14 +108,22 @@ public final class CreateViewStatement extends AbstractStatement {
         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 @@ public final class ViewDecl extends AbstractStatement {
 
     private final DatasetFullyQualifiedName viewName;
 
-    private Expression viewBody;
+    private final Expression viewBody;
 
     private Expression viewBodyNormalized;
 
@@ -48,11 +48,6 @@ public final class ViewDecl extends AbstractStatement {
         return viewBody;
     }
 
-    public void setViewBody(Expression expr) {
-        viewBody = expr;
-        viewBodyNormalized = null;
-    }
-
     public Expression getNormalizedViewBody() {
         return viewBodyNormalized;
     }
@@ -62,16 +57,6 @@ public final class ViewDecl extends AbstractStatement {
     }
 
     @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 @@ public class DatasetDeclParametersUtil {
      * ***********************************************
      */
     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.DoubleLiteral;
 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.AdmObjectNode;
 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 class ExpressionUtils {
             }
         }
     }
+
+    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 @@ package org.apache.asterix.lang.common.util;
 
 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 @@ public final class ViewUtil {
         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 @@ class SqlppFunctionBodyRewriter extends SqlppQueryRewriter {
         // 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.SubstituteGroupbyExpressio
 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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
                                 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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
 
     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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
             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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
                 !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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
 
         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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
                 : 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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
         // dataverse_name.view_name
         DataverseName dataverseName = viewDecl.getViewName().getDataverseName();
         String viewName = viewDecl.getViewName().getDatasetName();
-        SourceLocation sourceLoc = viewDecl.getSourceLocation();
+        Expression vAccessExpr = createDatasetAccessExpression(dataverseName, viewName, viewDecl.getSourceLocation());
+        return ExpressionUtils.createWrappedQuery(vAccessExpr, viewDecl.getSourceLocation());
+    }
+
+    private static Expression createDatasetAccessExpression(DataverseName dataverseName, String datasetName,
+            SourceLocation sourceLoc) {
+        AbstractExpression resultExpr = null;
         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);
+            resultExpr = i == 0 ? new VariableExpr(new VarIdentifier(SqlppVariableUtil.toInternalVariableName(part)))
+                    : new FieldAccessor(resultExpr, new Identifier(part));
+            resultExpr.setSourceLocation(sourceLoc);
         }
-        vAccessExpr = new FieldAccessor(vAccessExpr, new Identifier(viewName));
-        vAccessExpr.setSourceLocation(sourceLoc);
-
-        return 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;
+        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 @@ class SQLPPParser extends ScopeChecker implements IParser {
     // 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 DatasetReferenceTypeSpecification() throws ParseException:
   }
 }
 
-TypeExpression DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
+RecordTypeDefinition DatasetRecordTypeSpecification(boolean allowRecordKindModifier) throws ParseException:
 {
   RecordTypeDefinition recordTypeDef = null;
   RecordTypeDefinition.RecordKind recordKind = null;
@@ -1417,17 +1418,29 @@ CreateViewStatement CreateViewStatement(Token startStmtToken, boolean orReplace)
 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 @@ CreateViewStatement ViewSpecification(Token startStmtToken, boolean orReplace) t
       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 ViewBody() throws ParseException:
   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 final class MetadataRecordTypes {
     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.IDatasetDetails;
 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 @@ public class ViewDetails implements IDatasetDetails {
 
     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 @@ public class ViewDetails implements IDatasetDetails {
         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 @@ public class ViewDetails implements IDatasetDetails {
         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 @@ public class ViewDetails implements IDatasetDetails {
             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.ARecord;
 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 @@ public class DatasetTupleTranslator extends AbstractTupleTranslator<Dataset> {
                     }
                 }
 
-                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 @@ public class DatasetTupleTranslator extends AbstractTupleTranslator<Dataset> {
         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();