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.' +====