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

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

commit eb5c8d6884f1c1bb3de66809e9ec59173072d5e8
Author: wzhou-code <wz...@cloudera.com>
AuthorDate: Tue Feb 27 11:56:05 2024 -0800

    IMPALA-12802: Support ALTER TABLE for JDBC tables
    
    IMPALA-12793 changes the syntax for creating JDBC table. The
    configurations of connection credentials - url, username, password,
    jdbc driver, etc, are set as table properties.
    
    This patch allows user to change these table properties, or edit
    columns via ALTER TABLE statement.
    
    Testing:
     - Added frontend analysis unit-tests.
     - Added end-to-end unit-test.
     - Passed Core tests
    
    Change-Id: I5ebb5de2c686d2015db78641f78299dd5f33621e
    Reviewed-on: http://gerrit.cloudera.org:8080/21088
    Reviewed-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
    Tested-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
---
 .../impala/analysis/AlterTableAddColsStmt.java     |  10 ++
 .../AlterTableAddDropRangePartitionStmt.java       |   3 +
 .../analysis/AlterTableAddPartitionStmt.java       |   8 ++
 .../impala/analysis/AlterTableAlterColStmt.java    |  12 ++
 .../impala/analysis/AlterTableDropColStmt.java     |   3 +
 .../analysis/AlterTableDropPartitionStmt.java      |   8 ++
 .../AlterTableExecuteExpireSnapshotsStmt.java      |   3 +
 .../analysis/AlterTableExecuteRollbackStmt.java    |   3 +
 .../impala/analysis/AlterTableExecuteStmt.java     |   3 +
 .../analysis/AlterTableOrViewRenameStmt.java       |   3 +
 .../analysis/AlterTableOrViewSetOwnerStmt.java     |   3 +
 .../analysis/AlterTableRecoverPartitionsStmt.java  |   3 +
 .../impala/analysis/AlterTableReplaceColsStmt.java |   3 +
 .../impala/analysis/AlterTableSetCachedStmt.java   |   5 +
 .../impala/analysis/AlterTableSetColumnStats.java  |   3 +
 .../analysis/AlterTableSetFileFormatStmt.java      |   3 +
 .../impala/analysis/AlterTableSetLocationStmt.java |   3 +
 .../impala/analysis/AlterTableSetOwnerStmt.java    |   3 +
 .../analysis/AlterTableSetPartitionSpecStmt.java   |   3 +
 .../analysis/AlterTableSetRowFormatStmt.java       |   3 +
 .../apache/impala/analysis/AlterTableSetStmt.java  |   4 +-
 .../analysis/AlterTableSetTblProperties.java       |  44 ++++++-
 .../impala/analysis/AlterTableSortByStmt.java      |   3 +
 .../org/apache/impala/analysis/AlterTableStmt.java |  17 ++-
 .../analysis/AlterTableUnSetTblProperties.java     |  32 +++++
 .../impala/analysis/AlterViewSetOwnerStmt.java     |   3 +
 .../impala/analysis/AlterViewSetTblProperties.java |   3 +
 .../analysis/AlterViewUnSetTblProperties.java      |   3 +
 .../org/apache/impala/catalog/DataSourceTable.java |  18 +++
 .../apache/impala/catalog/FeDataSourceTable.java   |   1 +
 .../impala/catalog/local/LocalDataSourceTable.java |   6 +
 .../org/apache/impala/analysis/AnalyzeDDLTest.java | 145 +++++++++++++++++----
 .../queries/QueryTest/jdbc-data-source.test        | 120 +++++++++++++++++
 33 files changed, 452 insertions(+), 35 deletions(-)

diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableAddColsStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableAddColsStmt.java
index dece3c4f8..f23d15166 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableAddColsStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableAddColsStmt.java
@@ -21,6 +21,8 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import org.apache.hadoop.hive.metastore.api.FieldSchema;
 import org.apache.impala.catalog.Column;
+import org.apache.impala.catalog.DataSourceTable;
+import org.apache.impala.catalog.FeDataSourceTable;
 import org.apache.impala.catalog.FeHBaseTable;
 import org.apache.impala.catalog.FeKuduTable;
 import org.apache.impala.catalog.FeTable;
@@ -54,6 +56,9 @@ public class AlterTableAddColsStmt extends AlterTableStmt {
     columnDefs_ = Lists.newArrayList(columnDefs);
   }
 
+  @Override
+  public String getOperation() { return "ADD COLUMNS"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     super.analyze(analyzer);
@@ -115,6 +120,11 @@ public class AlterTableAddColsStmt extends AlterTableStmt {
       } else if (c.hasKuduOptions()) {
         throw new AnalysisException("The specified column options are only 
supported " +
             "in Kudu tables: " + c.toString());
+      } else if (t instanceof FeDataSourceTable) {
+        if (!DataSourceTable.isSupportedColumnType(c.getType())) {
+          throw new AnalysisException("Tables stored by JDBC do not support 
the " +
+              "column type: " + c.getType());
+        }
       }
     }
   }
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableAddDropRangePartitionStmt.java
 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableAddDropRangePartitionStmt.java
index 64fbf3be3..e0f76cfa5 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableAddDropRangePartitionStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableAddDropRangePartitionStmt.java
@@ -63,6 +63,9 @@ public class AlterTableAddDropRangePartitionStmt extends 
AlterTableStmt {
     operation_ = op;
   }
 
+  @Override
+  public String getOperation() { return operation_.name().toUpperCase(); }
+
   @Override
   public String toSql(ToSqlOptions options) {
     StringBuilder sb = new StringBuilder("ALTER TABLE " + getTbl());
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableAddPartitionStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableAddPartitionStmt.java
index 4ea4b9353..1f3919eed 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableAddPartitionStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableAddPartitionStmt.java
@@ -67,6 +67,14 @@ public class AlterTableAddPartitionStmt extends 
AlterTableStmt {
 
   public boolean getIfNotExists() { return ifNotExists_; }
 
+  @Override
+  public String getOperation() {
+    StringBuilder sb = new StringBuilder("ADD ");
+    if (ifNotExists_) sb.append("IF NOT EXISTS ");
+    sb.append("PARTITION");
+    return sb.toString();
+  }
+
   @Override
   public String toSql(ToSqlOptions options) {
     StringBuilder sb = new StringBuilder("ALTER TABLE ");
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableAlterColStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableAlterColStmt.java
index 6293c36f7..8c7308fc1 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableAlterColStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableAlterColStmt.java
@@ -21,6 +21,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.impala.catalog.Column;
+import org.apache.impala.catalog.DataSourceTable;
+import org.apache.impala.catalog.FeDataSourceTable;
 import org.apache.impala.catalog.FeHBaseTable;
 import org.apache.impala.catalog.FeIcebergTable;
 import org.apache.impala.catalog.FeKuduTable;
@@ -87,6 +89,9 @@ public class AlterTableAlterColStmt extends AlterTableStmt {
   public String getColName() { return colName_; }
   public ColumnDef getNewColDef() { return newColDef_; }
 
+  @Override
+  public String getOperation() { return "CHANGE COLUMN"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
@@ -187,5 +192,12 @@ public class AlterTableAlterColStmt extends AlterTableStmt 
{
             "is not supported for complex types in Iceberg tables."));
       }
     }
+
+    if (t instanceof FeDataSourceTable) {
+      if (!DataSourceTable.isSupportedColumnType(newColDef_.getType())) {
+        throw new AnalysisException("Tables stored by JDBC do not support the 
" +
+            "column type: " + newColDef_.getType());
+      }
+    }
   }
 }
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableDropColStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableDropColStmt.java
index 8b9e875c3..fb7b14aae 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableDropColStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableDropColStmt.java
@@ -51,6 +51,9 @@ public class AlterTableDropColStmt extends AlterTableStmt {
     return params;
   }
 
+  @Override
+  public String getOperation() { return "DROP COLUMN"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     super.analyze(analyzer);
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableDropPartitionStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableDropPartitionStmt.java
index 8e75f077f..a3b40a998 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableDropPartitionStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableDropPartitionStmt.java
@@ -79,6 +79,14 @@ public class AlterTableDropPartitionStmt extends 
AlterTableStmt {
 
   public boolean getIfNotExists() { return ifExists_; }
 
+  @Override
+  public String getOperation() {
+    StringBuilder sb = new StringBuilder("DROP ");
+    if (ifExists_) sb.append("IF EXISTS ");
+    sb.append("PARTITION");
+    return sb.toString();
+  }
+
   @Override
   public String toSql(ToSqlOptions options) {
     StringBuilder sb = new StringBuilder("ALTER TABLE " + getTbl());
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteExpireSnapshotsStmt.java
 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteExpireSnapshotsStmt.java
index 16d8a3753..a51621daa 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteExpireSnapshotsStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteExpireSnapshotsStmt.java
@@ -45,6 +45,9 @@ public class AlterTableExecuteExpireSnapshotsStmt extends 
AlterTableExecuteStmt
     super(tableName, fnCallExpr);
   }
 
+  @Override
+  public String getOperation() { return "EXECUTE EXPIRE_SNAPSHOTS"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     super.analyze(analyzer);
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteRollbackStmt.java
 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteRollbackStmt.java
index ea4da0b67..0ddb57cbc 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteRollbackStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteRollbackStmt.java
@@ -53,6 +53,9 @@ public class AlterTableExecuteRollbackStmt extends 
AlterTableExecuteStmt {
     super(tableName, fnCallExpr);
   }
 
+  @Override
+  public String getOperation() { return "EXECUTE ROLLBACK"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     super.analyze(analyzer);
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteStmt.java
index 0a0e33206..3ae47dcf0 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableExecuteStmt.java
@@ -41,6 +41,9 @@ public class AlterTableExecuteStmt extends AlterTableStmt {
     fnCallExpr_ = (FunctionCallExpr) fnCallExpr;
   }
 
+  @Override
+  public String getOperation() { return "EXECUTE"; }
+
   /**
    * Return an instance of a subclass of AlterTableExecuteStmt that can 
analyze the
    * execute statement for the function call expression in 'expr'.
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewRenameStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewRenameStmt.java
index ba0c90a11..65265e353 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewRenameStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewRenameStmt.java
@@ -56,6 +56,9 @@ public class AlterTableOrViewRenameStmt extends 
AlterTableStmt {
     return newDbName_;
   }
 
+  @Override
+  public String getOperation() { return "RENAME"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewSetOwnerStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewSetOwnerStmt.java
index 25d9ecb12..cd052698e 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewSetOwnerStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableOrViewSetOwnerStmt.java
@@ -43,6 +43,9 @@ public abstract class AlterTableOrViewSetOwnerStmt extends 
AlterTableStmt {
     owner_ = owner;
   }
 
+  @Override
+  public String getOperation() { return "SET OWNER"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     String ownerName = owner_.getOwnerName();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableRecoverPartitionsStmt.java
 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableRecoverPartitionsStmt.java
index fe2b617fd..5fd2c3185 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableRecoverPartitionsStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableRecoverPartitionsStmt.java
@@ -32,6 +32,9 @@ public class AlterTableRecoverPartitionsStmt extends 
AlterTableStmt {
     super(tableName);
   }
 
+  @Override
+  public String getOperation() { return "RECOVER PARTITIONS"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableReplaceColsStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableReplaceColsStmt.java
index aeeca2431..8f39b91ea 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableReplaceColsStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableReplaceColsStmt.java
@@ -46,6 +46,9 @@ public class AlterTableReplaceColsStmt extends AlterTableStmt 
{
     columnDefs_ = Lists.newArrayList(columnDefs);
   }
 
+  @Override
+  public String getOperation() { return "REPLACE COLUMNS"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     super.analyze(analyzer);
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetCachedStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetCachedStmt.java
index 0bcd2bf09..0cc82247c 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetCachedStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetCachedStmt.java
@@ -41,6 +41,11 @@ public class AlterTableSetCachedStmt extends 
AlterTableSetStmt {
     cacheOp_ = cacheOp;
   }
 
+  @Override
+  public String getOperation() {
+    return cacheOp_.shouldCache() ? "SET CACHED" : "SET UNCACHED";
+  }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetColumnStats.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetColumnStats.java
index 7aa6f1ff6..b642f44c3 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetColumnStats.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetColumnStats.java
@@ -53,6 +53,9 @@ public class AlterTableSetColumnStats extends AlterTableStmt {
     statsMap_ = statsMap;
   }
 
+  @Override
+  public String getOperation() { return "SET COLUMN STATS"; }
+
   @Override
   public void analyze(Analyzer analyzer) throws AnalysisException {
     super.analyze(analyzer);
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetFileFormatStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetFileFormatStmt.java
index a45da9563..488fbc215 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetFileFormatStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetFileFormatStmt.java
@@ -40,6 +40,9 @@ public class AlterTableSetFileFormatStmt extends 
AlterTableSetStmt {
 
   public THdfsFileFormat getFileFormat() { return fileFormat_; }
 
+  @Override
+  public String getOperation() { return "SET FILEFORMAT"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetLocationStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetLocationStmt.java
index 01898d100..ac198df4a 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetLocationStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetLocationStmt.java
@@ -55,6 +55,9 @@ public class AlterTableSetLocationStmt extends 
AlterTableSetStmt {
 
   public HdfsUri getLocation() { return location_; }
 
+  @Override
+  public String getOperation() { return "SET LOCATION"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetOwnerStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetOwnerStmt.java
index 5932affed..c1424e8fc 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetOwnerStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetOwnerStmt.java
@@ -27,6 +27,9 @@ public class AlterTableSetOwnerStmt extends 
AlterTableOrViewSetOwnerStmt {
     super(tableName, owner);
   }
 
+  @Override
+  public String getOperation() { return "SET OWNER"; }
+
   @Override
   protected void validateType(TableRef tableRef) throws AnalysisException {
     if (tableRef instanceof InlineViewRef) {
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetPartitionSpecStmt.java
 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetPartitionSpecStmt.java
index 39d6a9728..b2cbf436c 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetPartitionSpecStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetPartitionSpecStmt.java
@@ -43,6 +43,9 @@ public class AlterTableSetPartitionSpecStmt extends 
AlterTableStmt {
     icebergPartSpec_ = icebergPartSpec;
   }
 
+  @Override
+  public String getOperation() { return "SET PARTITION SPEC"; }
+
   @Override
   public String toSql(ToSqlOptions options) {
     StringBuilder sb = new StringBuilder("ALTER TABLE ");
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetRowFormatStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetRowFormatStmt.java
index 2dcce78c8..56fc84766 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetRowFormatStmt.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetRowFormatStmt.java
@@ -42,6 +42,9 @@ public class AlterTableSetRowFormatStmt extends 
AlterTableSetStmt {
 
   public RowFormat getRowFormat() { return rowFormat_; }
 
+  @Override
+  public String getOperation() { return "SET ROW FORMAT"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetStmt.java
index 4d6a10aca..6a3713907 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetStmt.java
@@ -25,10 +25,10 @@ import org.apache.impala.common.AnalysisException;
 /**
  * Base class for all ALTER TABLE ... SET statements
  */
-public class AlterTableSetStmt extends AlterTableStmt {
+public abstract class AlterTableSetStmt extends AlterTableStmt {
   protected final PartitionSet partitionSet_;
 
-  public AlterTableSetStmt(TableName tableName, PartitionSet partitionSet) {
+  protected AlterTableSetStmt(TableName tableName, PartitionSet partitionSet) {
     super(tableName);
     partitionSet_ = partitionSet;
     if (partitionSet_ != null) partitionSet_.setTableName(tableName);
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetTblProperties.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetTblProperties.java
index 46d6d271e..9191c41f4 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSetTblProperties.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSetTblProperties.java
@@ -28,6 +28,8 @@ import org.apache.iceberg.DataFile;
 import org.apache.iceberg.mr.Catalogs;
 import org.apache.iceberg.mr.InputFormatConfig;
 import org.apache.impala.authorization.AuthorizationConfig;
+import org.apache.impala.catalog.DataSourceTable;
+import org.apache.impala.catalog.FeDataSourceTable;
 import org.apache.impala.catalog.FeFsTable;
 import org.apache.impala.catalog.FeHBaseTable;
 import org.apache.impala.catalog.FeIcebergTable;
@@ -75,6 +77,12 @@ public class AlterTableSetTblProperties extends 
AlterTableSetStmt {
 
   public Map<String, String> getTblProperties() { return tblProperties_; }
 
+  @Override
+  public String getOperation() {
+    return (targetProperty_ == TTablePropertyType.TBL_PROPERTY)
+        ? "SET TBLPROPERTIES" : "SET SERDEPROPERTIES";
+  }
+
   @Override
   public TAlterTableParams toThrift() {
    TAlterTableParams params = super.toThrift();
@@ -106,6 +114,8 @@ public class AlterTableSetTblProperties extends 
AlterTableSetStmt {
       analyzeKuduTable(analyzer);
     } else if (getTargetTable() instanceof FeIcebergTable) {
       analyzeIcebergTable(analyzer);
+    } else if (getTargetTable() instanceof FeDataSourceTable) {
+      analyzeDataSourceTable(analyzer);
     }
 
     // Check avro schema when it is set in avro.schema.url or 
avro.schema.literal to
@@ -208,6 +218,28 @@ public class AlterTableSetTblProperties extends 
AlterTableSetStmt {
     }
   }
 
+  private void analyzeDataSourceTable(Analyzer analyzer) throws 
AnalysisException {
+    if (partitionSet_ != null) {
+      throw new AnalysisException("Partition is not supported for DataSource 
table.");
+    } else if (targetProperty_ == TTablePropertyType.SERDE_PROPERTY) {
+      throw new AnalysisException("ALTER TABLE SET SERDEPROPERTIES is not 
supported " +
+          "for DataSource table.");
+    }
+    // Cannot change internal properties of DataSource.
+    dataSourcePropertyCheck(DataSourceTable.TBL_PROP_DATA_SRC_NAME);
+    dataSourcePropertyCheck(DataSourceTable.TBL_PROP_INIT_STRING);
+    dataSourcePropertyCheck(DataSourceTable.TBL_PROP_LOCATION);
+    dataSourcePropertyCheck(DataSourceTable.TBL_PROP_CLASS);
+    dataSourcePropertyCheck(DataSourceTable.TBL_PROP_API_VER);
+  }
+
+  private void dataSourcePropertyCheck(String property) throws 
AnalysisException {
+    if (tblProperties_.containsKey(property)) {
+      throw new AnalysisException(String.format("Changing the '%s' table 
property is " +
+          "not supported for DataSource table.", property));
+    }
+  }
+
   /**
    * Check that Avro schema provided in avro.schema.url or avro.schema.literal 
is valid
    * Json and contains only supported Impala types. If both properties are 
set, then
@@ -279,10 +311,14 @@ public class AlterTableSetTblProperties extends 
AlterTableSetStmt {
     boolean containsSortingColumnProperties = tblProperties
         .containsKey(AlterTableSortByStmt.TBL_PROP_SORT_COLUMNS);
 
-    if ((containsOrderingProperties || containsSortingColumnProperties) &&
-        table instanceof FeKuduTable) {
-      throw new AnalysisException("'sort.*' table properties are not "
-          + "supported for Kudu tables.");
+    if (containsOrderingProperties || containsSortingColumnProperties) {
+      if (table instanceof FeKuduTable) {
+        throw new AnalysisException("'sort.*' table properties are not "
+            + "supported for Kudu tables.");
+      } else if (table instanceof FeDataSourceTable) {
+        throw new AnalysisException("'sort.*' table properties are not "
+            + "supported for DataSource tables.");
+      }
     }
 
     TSortingOrder sortingOrder = TSortingOrder.LEXICAL;
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableSortByStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableSortByStmt.java
index 1a07a5d1d..576ca3289 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableSortByStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableSortByStmt.java
@@ -53,6 +53,9 @@ public class AlterTableSortByStmt extends AlterTableStmt {
     sortingOrder_ = sortingOrder;
   }
 
+  @Override
+  public String getOperation() { return "SORT BY"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
diff --git a/fe/src/main/java/org/apache/impala/analysis/AlterTableStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableStmt.java
index 249987ed2..c5aa16a4a 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterTableStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterTableStmt.java
@@ -43,6 +43,11 @@ public abstract class AlterTableStmt extends StatementBase {
     table_ = null;
   }
 
+  /*
+   * Returns the operation name of the ALTER TABLE statement.
+   */
+  public abstract String getOperation();
+
   public String getTbl() { return tableName_.getTbl(); }
 
   /**
@@ -101,10 +106,16 @@ public abstract class AlterTableStmt extends 
StatementBase {
     // column statistics.
     checkTransactionalTable();
     if (table_ instanceof FeDataSourceTable
-        && !(this instanceof AlterTableSetColumnStats)) {
+        && !(this instanceof AlterTableSetColumnStats
+            || this instanceof AlterTableAddColsStmt
+            || this instanceof AlterTableAlterColStmt
+            || this instanceof AlterTableDropColStmt
+            || this instanceof AlterTableSetTblProperties
+            || this instanceof AlterTableUnSetTblProperties)) {
+      boolean storedByJdbc = 
((FeDataSourceTable)table_).isJdbcDataSourceTable();
       throw new AnalysisException(String.format(
-          "ALTER TABLE not allowed on a table produced by a data source: %s",
-          tableName_));
+          "ALTER TABLE %s not allowed on a table %s: %s", getOperation(),
+          (storedByJdbc ? "STORED BY JDBC": "PRODUCED BY DATA SOURCE"), 
tableName_));
     }
   }
 
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableUnSetTblProperties.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableUnSetTblProperties.java
index 4d1d28da8..183cf4ef0 100644
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterTableUnSetTblProperties.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterTableUnSetTblProperties.java
@@ -19,6 +19,8 @@ package org.apache.impala.analysis;
 
 import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
 import org.apache.hadoop.hive.serde2.avro.AvroSerdeUtils;
+import org.apache.impala.catalog.DataSourceTable;
+import org.apache.impala.catalog.FeDataSourceTable;
 import org.apache.impala.catalog.FeIcebergTable;
 import org.apache.impala.catalog.FeKuduTable;
 import org.apache.impala.catalog.IcebergTable;
@@ -58,6 +60,12 @@ public class AlterTableUnSetTblProperties extends 
AlterTableStmt {
 
   public List<String> getTblPropertyKeys() { return tblPropertyKeys_; }
 
+  @Override
+  public String getOperation() {
+    return (targetProperty_ == TTablePropertyType.TBL_PROPERTY)
+        ? "UNSET TBLPROPERTIES" : "UNSET SERDEPROPERTIES";
+  }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = super.toThrift();
@@ -93,6 +101,8 @@ public class AlterTableUnSetTblProperties extends 
AlterTableStmt {
       analyzeKuduTable(analyzer);
     } else if (getTargetTable() instanceof FeIcebergTable) {
       analyzeIcebergTable(analyzer);
+    } else if (getTargetTable() instanceof FeDataSourceTable) {
+      analyzeDataSourceTable(analyzer);
     }
 
     // Unsetting avro.schema.url or avro.schema.literal are not allowed to
@@ -128,6 +138,28 @@ public class AlterTableUnSetTblProperties extends 
AlterTableStmt {
     propertyCheck(IcebergTable.METADATA_LOCATION, "Iceberg");
   }
 
+  private void analyzeDataSourceTable(Analyzer analyzer) throws 
AnalysisException {
+    if (partitionSet_ != null) {
+      throw new AnalysisException("Partition is not supported for DataSource 
table.");
+    } else if (targetProperty_ == TTablePropertyType.SERDE_PROPERTY) {
+      throw new AnalysisException("ALTER TABLE UNSET SERDEPROPERTIES is not 
supported " +
+          "for DataSource table.");
+    }
+    // Cannot unset internal properties of DataSource.
+    propertyCheck(DataSourceTable.TBL_PROP_DATA_SRC_NAME, "DataSource");
+    propertyCheck(DataSourceTable.TBL_PROP_INIT_STRING, "DataSource");
+    propertyCheck(DataSourceTable.TBL_PROP_LOCATION, "DataSource");
+    propertyCheck(DataSourceTable.TBL_PROP_CLASS, "DataSource");
+    propertyCheck(DataSourceTable.TBL_PROP_API_VER, "DataSource");
+    // Cannot unset properties which are required JDBC parameters.
+    for (String property : tblPropertyKeys_) {
+      if (DataSourceTable.isRequiredJdbcParameter(property)) {
+        throw new AnalysisException(String.format("Unsetting the '%s' table 
property " +
+            "is not supported for JDBC DataSource table.", property));
+      }
+    }
+  }
+
   private void propertyCheck(String property, String tableType) throws 
AnalysisException {
     if (tblPropertyKeys_.contains(property)) {
       throw new AnalysisException(String.format("Unsetting the '%s' table 
property is " +
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterViewSetOwnerStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterViewSetOwnerStmt.java
index 4e1fc52f5..b544131ed 100644
--- a/fe/src/main/java/org/apache/impala/analysis/AlterViewSetOwnerStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterViewSetOwnerStmt.java
@@ -27,6 +27,9 @@ public class AlterViewSetOwnerStmt extends 
AlterTableOrViewSetOwnerStmt {
     super(tableName, owner);
   }
 
+  @Override
+  public String getOperation() { return "SET OWNER"; }
+
   @Override
   protected void validateType(TableRef tableRef) throws AnalysisException {
     if (!(tableRef instanceof InlineViewRef)) {
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterViewSetTblProperties.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterViewSetTblProperties.java
index 85408ca05..701e092be 100755
--- a/fe/src/main/java/org/apache/impala/analysis/AlterViewSetTblProperties.java
+++ b/fe/src/main/java/org/apache/impala/analysis/AlterViewSetTblProperties.java
@@ -47,6 +47,9 @@ public class AlterViewSetTblProperties extends 
AlterTableSetStmt {
     CreateTableStmt.unescapeProperties(tblProperties_);
   }
 
+  @Override
+  public String getOperation() { return "SET TBLPROPERTIES"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = new TAlterTableParams();
diff --git 
a/fe/src/main/java/org/apache/impala/analysis/AlterViewUnSetTblProperties.java 
b/fe/src/main/java/org/apache/impala/analysis/AlterViewUnSetTblProperties.java
index ea6cb4617..6e42f9fc2 100755
--- 
a/fe/src/main/java/org/apache/impala/analysis/AlterViewUnSetTblProperties.java
+++ 
b/fe/src/main/java/org/apache/impala/analysis/AlterViewUnSetTblProperties.java
@@ -48,6 +48,9 @@ public class AlterViewUnSetTblProperties extends 
AlterTableStmt {
     ifExists_ = ifExist;
   }
 
+  @Override
+  public String getOperation() { return "UNSET TBLPROPERTIES"; }
+
   @Override
   public TAlterTableParams toThrift() {
     TAlterTableParams params = new TAlterTableParams();
diff --git a/fe/src/main/java/org/apache/impala/catalog/DataSourceTable.java 
b/fe/src/main/java/org/apache/impala/catalog/DataSourceTable.java
index 642ca481c..2be5411ae 100644
--- a/fe/src/main/java/org/apache/impala/catalog/DataSourceTable.java
+++ b/fe/src/main/java/org/apache/impala/catalog/DataSourceTable.java
@@ -114,6 +114,12 @@ public class DataSourceTable extends Table implements 
FeDataSourceTable {
   @Override // FeDataSourceTable
   public int getNumNodes() { return 1; }
 
+  @Override // FeDataSourceTable
+  public boolean isJdbcDataSourceTable() {
+    return (dataSource_ != null && dataSource_.name != null &&
+        dataSource_.name.equals(IMPALA_BUILTIN_JDBC_DATASOURCE));
+  }
+
   @Override
   public TCatalogObjectType getCatalogObjectType() { return 
TCatalogObjectType.TABLE; }
 
@@ -190,6 +196,18 @@ public class DataSourceTable extends Table implements 
FeDataSourceTable {
     }
   }
 
+  /**
+   * Check if the given property name is one of required JDBC/DBCP parameters.
+   */
+  public static boolean isRequiredJdbcParameter(String propertyName) {
+    for (JdbcStorageConfig config : JdbcStorageConfig.values()) {
+      if (config.getPropertyName().equalsIgnoreCase(propertyName)) {
+        return config.isRequired();
+      }
+    }
+    return false;
+  }
+
   /**
    * Create columns corresponding to fieldSchemas.
    * Throws a TableLoadingException if the metadata is incompatible with what 
we
diff --git a/fe/src/main/java/org/apache/impala/catalog/FeDataSourceTable.java 
b/fe/src/main/java/org/apache/impala/catalog/FeDataSourceTable.java
index a76f38db1..4f21946e0 100644
--- a/fe/src/main/java/org/apache/impala/catalog/FeDataSourceTable.java
+++ b/fe/src/main/java/org/apache/impala/catalog/FeDataSourceTable.java
@@ -36,4 +36,5 @@ public interface FeDataSourceTable extends FeTable {
   // in Frontend.getTableStats?
   TResultSet getTableStats();
 
+  boolean isJdbcDataSourceTable();
 }
diff --git 
a/fe/src/main/java/org/apache/impala/catalog/local/LocalDataSourceTable.java 
b/fe/src/main/java/org/apache/impala/catalog/local/LocalDataSourceTable.java
index dea93bcc5..2d083d795 100644
--- a/fe/src/main/java/org/apache/impala/catalog/local/LocalDataSourceTable.java
+++ b/fe/src/main/java/org/apache/impala/catalog/local/LocalDataSourceTable.java
@@ -146,6 +146,12 @@ public class LocalDataSourceTable extends LocalTable 
implements FeDataSourceTabl
   @Override // FeDataSourceTable
   public int getNumNodes() { return 1; }
 
+  @Override // FeDataSourceTable
+  public boolean isJdbcDataSourceTable() {
+    return (dataSource_ != null && dataSource_.name != null &&
+        
dataSource_.name.equals(DataSourceTable.IMPALA_BUILTIN_JDBC_DATASOURCE));
+  }
+
   /**
    * Returns statistics on this table as a tabular result set. Used for the
    * SHOW TABLE STATS statement. The schema of the returned TResultSet is set
diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
index f84bb342f..02a3aebdb 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
@@ -119,10 +119,15 @@ public class AnalyzeDDLTest extends FrontendTestBase {
       AnalysisError("alter table functional.alltypes_view " + kw +
           " partition(year=2050, month=10)",
           "ALTER TABLE not allowed on a view: functional.alltypes_view");
+      // Cannot ALTER TABLE to add or drop partition for data source tables.
       AnalysisError("alter table functional.alltypes_datasource " + kw +
           " partition(year=2050, month=10)",
-          "ALTER TABLE not allowed on a table produced by a data source: " +
-          "functional.alltypes_datasource");
+          "ALTER TABLE " + kw.toUpperCase() + " PARTITION not allowed on a 
table " +
+          "PRODUCED BY DATA SOURCE: functional.alltypes_datasource");
+      AnalysisError("alter table functional.alltypes_jdbc_datasource " + kw +
+          " partition(year=2050, month=10)",
+          "ALTER TABLE " + kw.toUpperCase() + " PARTITION not allowed on a 
table " +
+          "STORED BY JDBC: functional.alltypes_jdbc_datasource");
 
       // NULL partition keys
       AnalyzesOk("alter table functional.alltypes " + kw +
@@ -450,6 +455,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     // Valid unicode column name.
     AnalyzesOk("alter table functional.alltypes add column `???` int");
 
+    // ALTER TABLE to add column for data source tables.
+    AnalyzesOk("alter table functional.alltypes_datasource add column c1 
string");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource add column c1 
string");
+
     // Column name must be unique for add.
     AnalysisError("alter table functional.alltypes add column int_col int",
         "Column already exists: int_col");
@@ -478,10 +487,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalysisError("alter table allcomplextypes.int_array_col add column c1 
string",
         createAnalysisCtx("functional"),
         "ALTER TABLE not allowed on a nested collection: 
allcomplextypes.int_array_col");
-    // Cannot ALTER TABLE produced by a data source.
-    AnalysisError("alter table functional.alltypes_datasource add column c1 
string",
-        "ALTER TABLE not allowed on a table produced by a data source: " +
-        "functional.alltypes_datasource");
+    // Cannot ALTER TABLE to add column with unsupported data type for data 
source
+    // table.
+    AnalysisError("alter table functional.alltypes_jdbc_datasource add column 
i binary",
+        "Tables stored by JDBC do not support the column type: BINARY");
 
     // Cannot ALTER TABLE ADD COLUMNS on an HBase table.
     AnalysisError("alter table functional_hbase.alltypes add column i int",
@@ -523,6 +532,12 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalyzesOk("alter table functional.alltypes add columns" +
         "(`시스???पताED` int)");
 
+    // ALTER TABLE to add columns for data source tables.
+    AnalyzesOk("alter table functional.alltypes_datasource add columns " +
+        "(c1 string comment 'hi')");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource add columns " +
+        "(c1 string comment 'hi')");
+
     // Column name must be unique for add.
     AnalysisError("alter table functional.alltypes add columns (int_col int)",
         "Column already exists: int_col");
@@ -557,11 +572,11 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "add columns (c1 string comment 'hi')",
         createAnalysisCtx("functional"),
         "ALTER TABLE not allowed on a nested collection: 
allcomplextypes.int_array_col");
-    // Cannot ALTER TABLE produced by a data source.
-    AnalysisError("alter table functional.alltypes_datasource " +
-        "add columns (c1 string comment 'hi')",
-        "ALTER TABLE not allowed on a table produced by a data source: " +
-        "functional.alltypes_datasource");
+    // Cannot ALTER TABLE to add columns with unsupported data type for data 
source
+    // table.
+    AnalysisError("alter table functional.alltypes_jdbc_datasource add columns 
" +
+        "(c1 binary comment 'hi')",
+        "Tables stored by JDBC do not support the column type: BINARY");
 
     // Cannot ALTER TABLE ADD COLUMNS on an HBase table.
     AnalysisError("alter table functional_hbase.alltypes add columns (i int)",
@@ -632,11 +647,15 @@ public class AnalyzeDDLTest extends FrontendTestBase {
             "replace columns (c1 string comment 'hi')",
         createAnalysisCtx("functional"),
         "ALTER TABLE not allowed on a nested collection: 
allcomplextypes.int_array_col");
-    // Cannot ALTER TABLE produced by a data source.
+    // Cannot ALTER TABLE to replace columns for data source tables.
     AnalysisError("alter table functional.alltypes_datasource " +
             "replace columns (c1 string comment 'hi')",
-        "ALTER TABLE not allowed on a table produced by a data source: " +
+        "ALTER TABLE REPLACE COLUMNS not allowed on a table PRODUCED BY DATA 
SOURCE: " +
             "functional.alltypes_datasource");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource " +
+            "replace columns (c1 string comment 'hi')",
+        "ALTER TABLE REPLACE COLUMNS not allowed on a table STORED BY JDBC: " +
+            "functional.alltypes_jdbc_datasource");
 
     // Cannot ALTER TABLE REPLACE COLUMNS on a HBase table.
     AnalysisError("alter table functional_hbase.alltypes replace columns (i 
int)",
@@ -651,6 +670,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
   public void TestAlterTableDropColumn() throws AnalysisException {
     AnalyzesOk("alter table functional.alltypes drop column int_col");
 
+    // ALTER TABLE to drop column for data source tables.
+    AnalyzesOk("alter table functional.alltypes_datasource drop column 
int_col");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource drop column 
int_col");
+
     AnalysisError("alter table functional.alltypes drop column no_col",
         "Column 'no_col' does not exist in table: functional.alltypes");
 
@@ -675,10 +698,6 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalysisError("alter table allcomplextypes.int_array_col drop column 
int_col",
         createAnalysisCtx("functional"),
         "ALTER TABLE not allowed on a nested collection: 
allcomplextypes.int_array_col");
-    // Cannot ALTER TABLE produced by a data source.
-    AnalysisError("alter table functional.alltypes_datasource drop column 
int_col",
-        "ALTER TABLE not allowed on a table produced by a data source: " +
-        "functional.alltypes_datasource");
 
     // Cannot ALTER TABLE DROP COLUMN on an HBase table.
     AnalysisError("alter table functional_hbase.alltypes drop column int_col",
@@ -699,6 +718,15 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalyzesOk("alter table functional.alltypes change int_col int_col int 
comment 'c'");
     AnalyzesOk("alter table functional.alltypes change column int_col `汉字` 
int");
 
+    // ALTER TABLE to change column for data source tables.
+    AnalyzesOk("alter table functional.alltypes_datasource " +
+        "change column int_col int_col2 int");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource " +
+        "change column int_col int_col2 int");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource " +
+        "change column int_col bin_col binary",
+        "Tables stored by JDBC do not support the column type: BINARY");
+
     AnalysisError("alter table functional.alltypes change column no_col c1 
int",
         "Column 'no_col' does not exist in table: functional.alltypes");
 
@@ -709,7 +737,6 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "alter table functional.alltypes change column int_col Tinyint_col 
int",
         "Column already exists: tinyint_col");
 
-
     // Table/Db does not exist
     AnalysisError("alter table db_does_not_exist.alltypes change c1 c2 int",
         "Could not resolve table reference: 'db_does_not_exist.alltypes'");
@@ -725,11 +752,6 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "change column int_col int_col2 int",
         createAnalysisCtx("functional"),
         "ALTER TABLE not allowed on a nested collection: 
allcomplextypes.int_array_col");
-    // Cannot ALTER TABLE produced by a data source.
-    AnalysisError("alter table functional.alltypes_datasource " +
-        "change column int_col int_col2 int",
-        "ALTER TABLE not allowed on a table produced by a data source: " +
-        "functional.alltypes_datasource");
 
     // Cannot ALTER TABLE CHANGE COLUMN on an HBase table.
     AnalysisError("alter table functional_hbase.alltypes CHANGE COLUMN int_col 
i int",
@@ -762,6 +784,11 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "ALTER TABLE SET ROW FORMAT is only supported on TEXT or SEQUENCE file 
formats");
     AnalyzesOk("alter table functional.alltypesmixedformat 
partition(year=2009,month=1) " +
         "set row format delimited fields terminated by ' '");
+    // Cannot ALTER TABLE to set row format for data source tables.
+    AnalysisError("alter table functional.alltypes_jdbc_datasource set row 
format " +
+        "delimited fields terminated by ' '",
+        "ALTER TABLE SET ROW FORMAT not allowed on a table STORED BY JDBC: " +
+        "functional.alltypes_jdbc_datasource");
   }
 
   @Test
@@ -796,6 +823,39 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalyzesOk("alter table functional.alltypes PARTITION (year<=2010, 
month=11) " +
                "set serdeproperties ('a'='2')");
 
+    // ALTER TABLE to set or unset tblproperties for data source tables.
+    AnalyzesOk("alter table functional.alltypes_datasource set tblproperties 
('a'='2')");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource set 
tblproperties " +
+        "('a'='2')");
+    AnalyzesOk("alter table functional.alltypes_datasource unset tblproperties 
" +
+        "if exists ('a')");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource unset 
tblproperties " +
+        "if exists ('a')");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource set " +
+        "serdeproperties ('a'='2')",
+        "ALTER TABLE SET SERDEPROPERTIES is not supported for DataSource 
table");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource PARTITION " 
+
+        "(year=2010) set tblproperties ('a'='2')",
+        "Table is not partitioned: functional.alltypes_jdbc_datasource");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource set 
tblproperties " +
+        "('__IMPALA_DATA_SOURCE_NAME'='test')",
+        "Changing the '__IMPALA_DATA_SOURCE_NAME' table property is not 
supported for " +
+        "DataSource table.");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource unset " +
+        "serdeproperties ('a')",
+        "ALTER TABLE UNSET SERDEPROPERTIES is not supported for DataSource 
table");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource PARTITION " 
+
+        "(year=2010) unset tblproperties ('a')",
+        "Partition is not supported for DataSource table.");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource unset " +
+        "tblproperties ('__IMPALA_DATA_SOURCE_NAME')",
+        "Unsetting the '__IMPALA_DATA_SOURCE_NAME' table property is not 
supported " +
+        "for DataSource table.");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource unset " +
+        "tblproperties ('driver.url')",
+        "Unsetting the 'driver.url' table property is not supported for JDBC " 
+
+        "DataSource table.");
+
     AnalyzesOk("alter table functional.alltypes set 
tblproperties('sort.columns'='id')");
     AnalyzesOk("alter table functional.alltypes set tblproperties(" +
                "'sort.columns'='INT_COL,id')");
@@ -966,6 +1026,16 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalyzesOk("alter table functional.alltypes set location " +
         "'file:///test-warehouse/a/b'");
 
+    // Cannot ALTER TABLE to set location for data source tables.
+    AnalysisError("alter table functional.alltypes_datasource set location " +
+        "'file:///test-warehouse/a/b'",
+        "ALTER TABLE SET LOCATION not allowed on a table PRODUCED BY DATA 
SOURCE: " +
+        "functional.alltypes_datasource");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource set 
location " +
+        "'file:///test-warehouse/a/b'",
+        "ALTER TABLE SET LOCATION not allowed on a table STORED BY JDBC: " +
+        "functional.alltypes_jdbc_datasource");
+
     // Invalid location
     AnalysisError("alter table functional.alltypes set location 
'test/warehouse'",
         "URI path must be absolute: test/warehouse");
@@ -983,10 +1053,14 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalysisError("alter table allcomplextypes.int_array_col set fileformat 
sequencefile",
         createAnalysisCtx("functional"),
         "ALTER TABLE not allowed on a nested collection: 
allcomplextypes.int_array_col");
-    // Cannot ALTER TABLE produced by a data source.
+    // Cannot ALTER TABLE to set fileformat for data source tables.
     AnalysisError("alter table functional.alltypes_datasource set fileformat 
parquet",
-        "ALTER TABLE not allowed on a table produced by a data source: " +
+        "ALTER TABLE SET FILEFORMAT not allowed on a table PRODUCED BY DATA 
SOURCE: " +
         "functional.alltypes_datasource");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource set 
fileformat " +
+        "parquet",
+        "ALTER TABLE SET FILEFORMAT not allowed on a table STORED BY JDBC: " +
+        "functional.alltypes_jdbc_datasource");
 
     // Cannot ALTER TABLE SET on an HBase table.
     AnalysisError("alter table functional_hbase.alltypes set 
tblproperties('a'='b')",
@@ -1057,6 +1131,11 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalysisError("alter table functional.alltypestiny partition(year=9999, 
month=1) " +
         "set cached in 'testPool'",
         "No matching partition(s) found.");
+    // Cannot ALTER TABLE to set cached for data source tables.
+    AnalysisError("alter table functional.alltypes_jdbc_datasource set cached 
in " +
+        "'testPool'",
+        "ALTER TABLE SET CACHED not allowed on a table STORED BY JDBC: " +
+        "functional.alltypes_jdbc_datasource");
   }
 
   @Test
@@ -1343,8 +1422,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     // It should be okay to rename an HBase table.
     AnalyzesOk("alter table functional_hbase.alltypes rename to new_alltypes");
 
-    // It should be okay to rename a table produced by a data source.
+    // It should be okay to rename data source tables.
     AnalyzesOk("alter table functional.alltypes_datasource rename to 
new_datasrc_tbl");
+    AnalyzesOk("alter table functional.alltypes_jdbc_datasource rename to " +
+        "new_jdbc_datasrc_tbl");
   }
 
   @Test
@@ -1378,6 +1459,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "SORT BY column 'foo' in table.");
     AnalysisError("alter table functional_hbase.alltypes sort by (id, foo)",
         "ALTER TABLE SORT BY not supported on HBase tables.");
+    // Cannot ALTER TABLE to sort by for data source tables.
+    AnalysisError("alter table functional.alltypes_jdbc_datasource sort by 
(id)",
+        "ALTER TABLE SORT BY not allowed on a table STORED BY JDBC: " +
+        "functional.alltypes_jdbc_datasource");
   }
 
   @Test
@@ -1396,6 +1481,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "not find SORT BY column 'foo' in table.");
     AnalysisError("alter table functional_hbase.alltypes sort by zorder (id, 
foo)",
         "ALTER TABLE SORT BY not supported on HBase tables.");
+    // Cannot ALTER TABLE to sort by zorder for data source tables.
+    AnalysisError("alter table functional.alltypes_jdbc_datasource sort by 
zorder (id)",
+        "ALTER TABLE SORT BY not allowed on a table STORED BY JDBC: " +
+        "functional.alltypes_jdbc_datasource");
   }
 
   @Test
@@ -1648,6 +1737,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "Unsupported column options for non-Kudu table: 'int_col INT 
COMPRESSION LZ4'");
     AnalysisError("alter table functional.alltypes alter int_col drop default",
         "Unsupported column option for non-Kudu table: DROP DEFAULT");
+    AnalysisError("alter table functional.alltypes_datasource alter int_col 
drop " +
+        "default", "Unsupported column option for non-Kudu table: DROP 
DEFAULT");
+    AnalysisError("alter table functional.alltypes_jdbc_datasource alter 
int_col drop " +
+        "default", "Unsupported column option for non-Kudu table: DROP 
DEFAULT");
   }
 
   ComputeStatsStmt checkComputeStatsStmt(String stmt) throws AnalysisException 
{
diff --git 
a/testdata/workloads/functional-query/queries/QueryTest/jdbc-data-source.test 
b/testdata/workloads/functional-query/queries/QueryTest/jdbc-data-source.test
index 84148d614..72e375b80 100644
--- 
a/testdata/workloads/functional-query/queries/QueryTest/jdbc-data-source.test
+++ 
b/testdata/workloads/functional-query/queries/QueryTest/jdbc-data-source.test
@@ -433,3 +433,123 @@ DROP TABLE alltypes_jdbc_datasource_2;
 ---- RESULTS
 'Table has been dropped.'
 ====
+---- QUERY
+# Create JDBC table with unknown database type.
+DROP TABLE IF EXISTS jdbc_test;
+CREATE TABLE jdbc_test (
+ id INT,
+ bool_col BOOLEAN,
+ int_col INT)
+STORED BY JDBC
+TBLPROPERTIES (
+"database.type"="UNKNOWN",
+"jdbc.url"="jdbc:postgresql://$INTERNAL_LISTEN_HOST:5432/functional",
+"jdbc.driver"="org.postgresql.Driver",
+"driver.url"="$FILESYSTEM_PREFIX/test-warehouse/data-sources/jdbc-drivers/postgresql-jdbc.jar",
+"dbcp.username"="hiveuser",
+"dbcp.password"="password",
+"table"="alltypes");
+---- RESULTS
+'Table has been created.'
+====
+---- QUERY
+select count(*) from jdbc_test;
+---- CATCH
+row_regex:.*InternalException:.*Unknown database type.
+====
+---- QUERY
+# Alter JDBC table to change database type as POSTGRES.
+ALTER TABLE jdbc_test
+SET TBLPROPERTIES ("database.type"="POSTGRES");
+---- RESULTS
+'Updated table.'
+====
+---- QUERY
+select count(*) from jdbc_test;
+---- RESULTS
+7300
+---- TYPES
+BIGINT
+====
+---- QUERY
+# Alter JDBC table to set wrong username and password.
+ALTER TABLE jdbc_test
+SET TBLPROPERTIES ("dbcp.username"="UNKNOWN", "dbcp.password"="NONE");
+---- RESULTS
+'Updated table.'
+====
+---- QUERY
+select * from jdbc_test order by id limit 5;
+---- CATCH
+row_regex:.*Caught exception.*(FATAL: password authentication failed for user 
"UNKNOWN")
+====
+---- QUERY
+# Alter JDBC table to set correct username and password.
+ALTER TABLE jdbc_test
+SET TBLPROPERTIES ("dbcp.username"="hiveuser", "dbcp.password"="password");
+---- RESULTS
+'Updated table.'
+====
+---- QUERY
+select * from jdbc_test order by id limit 5;
+---- RESULTS
+0,true,0
+1,false,1
+2,true,2
+3,false,3
+4,true,4
+---- TYPES
+INT, BOOLEAN, INT
+====
+---- QUERY
+# Alter JDBC table to unset the required JDBC configuration "table".
+ALTER TABLE jdbc_test UNSET TBLPROPERTIES ("table");
+---- CATCH
+row_regex:.*AnalysisException: Unsetting the 'table' table property is not 
supported for JDBC DataSource table
+====
+---- QUERY
+# Alter table to drop a column.
+ALTER TABLE jdbc_test DROP COLUMN int_col;
+---- RESULTS
+'Column has been dropped.'
+====
+---- QUERY
+# Alter table to add a new column.
+ALTER TABLE jdbc_test ADD COLUMN IF NOT EXISTS date_col DATE;
+---- RESULTS
+'New column(s) have been added to the table.'
+====
+---- QUERY
+select * from jdbc_test order by id limit 5;
+---- RESULTS
+0,true,2009-01-01
+1,false,2009-01-01
+2,true,2009-01-01
+3,false,2009-01-01
+4,true,2009-01-01
+---- TYPES
+INT, BOOLEAN, DATE
+====
+---- QUERY
+# Alter table to change a column.
+ALTER TABLE jdbc_test CHANGE COLUMN date_col timestamp_col TIMESTAMP;
+---- RESULTS
+'Column has been altered.'
+====
+---- QUERY
+select * from jdbc_test order by id limit 5;
+---- RESULTS
+0,true,2009-01-01 00:00:00
+1,false,2009-01-01 00:01:00
+2,true,2009-01-01 00:02:00.100000000
+3,false,2009-01-01 00:03:00.300000000
+4,true,2009-01-01 00:04:00.600000000
+---- TYPES
+INT, BOOLEAN, TIMESTAMP
+====
+---- QUERY
+# Drop table.
+DROP TABLE jdbc_test;
+---- RESULTS
+'Table has been dropped.'
+====

Reply via email to