Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
AlterTableAddReplaceColsStmt.java
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.cloudera.impala.analysis;
16 
17 import java.util.List;
18 import java.util.Set;
19 
20 import org.apache.hadoop.hive.metastore.api.FieldSchema;
21 
26 import com.cloudera.impala.thrift.TAlterTableAddReplaceColsParams;
27 import com.cloudera.impala.thrift.TAlterTableParams;
28 import com.cloudera.impala.thrift.TAlterTableType;
29 import com.google.common.base.Preconditions;
30 import com.google.common.collect.Lists;
31 import com.google.common.collect.Sets;
32 
37  private final List<ColumnDef> columnDefs_;
38  private final boolean replaceExistingCols_;
39 
40  public AlterTableAddReplaceColsStmt(TableName tableName, List<ColumnDef> columnDefs,
41  boolean replaceExistingCols) {
42  super(tableName);
43  Preconditions.checkState(columnDefs != null && columnDefs.size() > 0);
44  columnDefs_ = Lists.newArrayList(columnDefs);
45  replaceExistingCols_ = replaceExistingCols;
46  }
47 
48  public List<ColumnDef> getColumnDescs() { return columnDefs_; }
49 
50  // Replace columns instead of appending new columns.
51  public boolean getReplaceExistingCols() {
52  return replaceExistingCols_;
53  }
54 
55  @Override
56  public TAlterTableParams toThrift() {
57  TAlterTableParams params = super.toThrift();
58  params.setAlter_type(TAlterTableType.ADD_REPLACE_COLUMNS);
59  TAlterTableAddReplaceColsParams colParams = new TAlterTableAddReplaceColsParams();
60  for (ColumnDef col: getColumnDescs()) {
61  colParams.addToColumns(col.toThrift());
62  }
63  colParams.setReplace_existing_cols(replaceExistingCols_);
64  params.setAdd_replace_cols_params(colParams);
65  return params;
66  }
67 
68  @Override
69  public void analyze(Analyzer analyzer) throws AnalysisException {
70  super.analyze(analyzer);
71  Table t = getTargetTable();
72  // TODO: Support column-level DDL on HBase tables. Requires updating the column
73  // mappings along with the table columns.
74  if (t instanceof HBaseTable) {
75  throw new AnalysisException("ALTER TABLE ADD|REPLACE COLUMNS not currently " +
76  "supported on HBase tables.");
77  }
78 
79  // Build a set of the partition keys for the table.
80  Set<String> existingPartitionKeys = Sets.newHashSet();
81  for (FieldSchema fs: t.getMetaStoreTable().getPartitionKeys()) {
82  existingPartitionKeys.add(fs.getName().toLowerCase());
83  }
84 
85  // Make sure the new columns don't already exist in the table, that the names
86  // are all valid and unique, and that none of the columns conflict with
87  // partition columns.
88  Set<String> colNames = Sets.newHashSet();
89  for (ColumnDef c: columnDefs_) {
90  c.analyze();
91  String colName = c.getColName().toLowerCase();
92  if (existingPartitionKeys.contains(colName)) {
93  throw new AnalysisException(
94  "Column name conflicts with existing partition column: " + colName);
95  }
96 
97  Column col = t.getColumn(colName);
98  if (col != null && !replaceExistingCols_) {
99  throw new AnalysisException("Column already exists: " + colName);
100  } else if (!colNames.add(colName)) {
101  throw new AnalysisException("Duplicate column name: " + colName);
102  }
103  }
104  }
105 }
AlterTableAddReplaceColsStmt(TableName tableName, List< ColumnDef > columnDefs, boolean replaceExistingCols)