15 package com.cloudera.impala.analysis;
17 import java.util.ArrayList;
18 import java.util.List;
22 import org.apache.hadoop.fs.permission.FsAction;
31 import com.cloudera.impala.thrift.TAccessEvent;
32 import com.cloudera.impala.thrift.TCatalogObjectType;
33 import com.cloudera.impala.thrift.TCreateTableParams;
34 import com.cloudera.impala.thrift.THdfsFileFormat;
35 import com.cloudera.impala.thrift.TTableName;
37 import com.google.common.base.Preconditions;
38 import com.google.common.base.Strings;
39 import com.google.common.collect.Lists;
40 import com.google.common.collect.Sets;
81 List<ColumnDef> partitionColumnDefs,
boolean isExternal, String comment,
83 HdfsCachingOp cachingOp,
boolean ifNotExists, Map<String, String> tblProperties,
84 Map<String, String> serdeProperties) {
85 Preconditions.checkNotNull(columnDefs);
86 Preconditions.checkNotNull(partitionColumnDefs);
87 Preconditions.checkNotNull(fileFormat);
88 Preconditions.checkNotNull(rowFormat);
89 Preconditions.checkNotNull(tableName);
91 this.columnDefs_ = Lists.newArrayList(columnDefs);
92 this.comment_ = comment;
94 this.ifNotExists_ = ifNotExists;
95 this.fileFormat_ = fileFormat;
96 this.location_ = location;
97 this.cachingOp_ = cachingOp;
98 this.partitionColDefs_ = Lists.newArrayList(partitionColumnDefs);
99 this.rowFormat_ = rowFormat;
100 this.tableName_ = tableName;
101 this.tblProperties_ = tblProperties;
102 this.serdeProperties_ = serdeProperties;
111 columnDefs_ = Lists.newArrayList(other.columnDefs_);
128 public String
getTbl() {
return tableName_.getTbl(); }
147 Preconditions.checkNotNull(
owner_);
156 Preconditions.checkNotNull(
dbName_);
162 return ToSqlUtils.getCreateTableSql(
this);
166 TCreateTableParams params =
new TCreateTableParams();
167 params.setTable_name(
new TTableName(
getDb(),
getTbl()));
169 params.addToColumns(col.toThrift());
172 params.addToPartition_columns(col.toThrift());
177 params.setLocation(
location_ == null ? null : location_.toString());
178 if (
cachingOp_ != null) params.setCache_op(cachingOp_.toThrift());
179 params.setRow_format(rowFormat_.toThrift());
189 Preconditions.checkState(
tableName_ != null && !tableName_.isEmpty());
190 tableName_.analyze();
192 owner_ = analyzer.getUser().getName();
197 String.format(
"%s.%s", dbName_,
getTbl()));
200 analyzer.addAccessEvent(
new TAccessEvent(dbName_ +
"." +
tableName_.
getTbl(),
201 TCatalogObjectType.TABLE, Privilege.CREATE.toString()));
210 location_.analyze(analyzer,
Privilege.ALL, FsAction.READ_WRITE);
225 columnDefs_.addAll(newColumnDefs);
230 if (
cachingOp_ != null) cachingOp_.analyze(analyzer);
238 Set<String> colNames = Sets.newHashSet();
241 if (!colNames.add(colDef.getColName().toLowerCase())) {
247 if (!colDef.getType().supportsTablePartitioning()) {
249 String.format(
"Type '%s' is not supported as partition-column type " +
250 "in column: %s", colDef.getType().toSql(), colDef.getColName()));
252 if (!colNames.add(colDef.getColName().toLowerCase())) {
265 Preconditions.checkState(
fileFormat_ == THdfsFileFormat.AVRO);
268 List<Map<String, String>> schemaSearchLocations = Lists.newArrayList();
269 String fullTblName =
dbName_ +
"." + tableName_.getTbl();
272 String avroSchema = null;
274 avroSchema = HdfsTable.getAvroSchema(schemaSearchLocations,
275 dbName_ +
"." + tableName_.getTbl());
280 if (Strings.isNullOrEmpty(avroSchema)) {
285 List<Column> avroColumns = null;
287 avroColumns = AvroSchemaParser.parse(avroSchema);
288 }
catch (Exception e) {
290 "Error parsing Avro schema for table '%s': %s", fullTblName,
293 Preconditions.checkNotNull(avroColumns);
298 String warnStr = null;
299 if (avroColumns.size() != columnDefs_.size() && !
columnDefs_.isEmpty()) {
300 warnStr = String.format(
301 "Ignoring column definitions in favor of Avro schema.\n" +
302 "The Avro schema has %s column(s) but %s column definition(s) were given.",
306 for (
int i = 0; i < columnDefs_.size(); ++i) {
308 Column avroCol = avroColumns.get(i);
309 String warnDetail = null;
310 if (!colDesc.
getColName().equalsIgnoreCase(avroCol.getName())) {
313 if (colDesc.
getType().isStringType() &&
314 avroCol.getType().isStringType()) {
316 }
else if (!colDesc.
getType().equals(avroCol.getType())) {
319 if (warnDetail != null) {
320 warnStr = String.format(
321 "Ignoring column definitions in favor of Avro schema due to a " +
322 "mismatched column %s at position %s.\n" +
323 "Column definition: %s\n" +
324 "Avro schema column: %s", warnDetail, i + 1,
325 colDesc.getColName() +
" " + colDesc.
getType().toSql(),
326 avroCol.getName() +
" " + avroCol.getType().
toSql());
333 analyzer.addWarning(warnStr);
335 List<ColumnDef> avroSchemaColDefs =
336 Lists.newArrayListWithCapacity(avroColumns.size());
337 for (
Column avroCol: avroColumns) {
339 new ColumnDef(avroCol.getName(), null, avroCol.getComment());
340 colDef.setType(avroCol.getType());
341 avroSchemaColDefs.add(colDef);
343 return avroSchemaColDefs;
350 if (value == null)
return;
353 "terminators must be specified as a single character or as a decimal " +
354 "value in the range [-128:127]: " + value);
362 if (propertyMap == null)
return;
363 for (Map.Entry<String, String> kv : propertyMap.entrySet()) {
364 propertyMap.put(kv.getKey(),
List< ColumnDef > getPartitionColumnDefs()
void analyzeRowFormatValue(String value)
CreateTableStmt(TableName tableName, List< ColumnDef > columnDefs, List< ColumnDef > partitionColumnDefs, boolean isExternal, String comment, RowFormat rowFormat, THdfsFileFormat fileFormat, HdfsUri location, HdfsCachingOp cachingOp, boolean ifNotExists, Map< String, String > tblProperties, Map< String, String > serdeProperties)
static void unescapeProperties(Map< String, String > propertyMap)
CreateTableStmt(CreateTableStmt other)
final HdfsCachingOp cachingOp_
List< ColumnDef > getColumnDefs()
final boolean ifNotExists_
final Map< String, String > serdeProperties_
final THdfsFileFormat fileFormat_
final boolean isExternal_
void setLocation(HdfsUri location)
TCreateTableParams toThrift()
static Byte parseDelim(String delimVal)
Map< String, String > getTblProperties()
List< ColumnDef > analyzeAvroSchema(Analyzer analyzer)
static final String TBL_ALREADY_EXISTS_ERROR_MSG
THdfsFileFormat getFileFormat()
final TableName tableName_
final RowFormat rowFormat_
final ArrayList< ColumnDef > partitionColDefs_
final Map< String, String > tblProperties_
void analyze(Analyzer analyzer)
void analyzeColumnDefs(Analyzer analyzer)
Map< String, String > getSerdeProperties()
final ArrayList< ColumnDef > columnDefs_