From ac7fb11da3fca8e2fe5f4dace4bf38512d4b0afa Mon Sep 17 00:00:00 2001 From: Lenni Kuff Date: Tue, 26 Mar 2013 22:50:34 -0700 Subject: [PATCH] Add analysis check for duplicate column names in create table statements --- .../impala/analysis/CreateTableStmt.java | 20 ++++++++++++++++--- .../impala/analysis/AnalyzerTest.java | 8 ++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/fe/src/main/java/com/cloudera/impala/analysis/CreateTableStmt.java b/fe/src/main/java/com/cloudera/impala/analysis/CreateTableStmt.java index 5107f37ee..7f5654378 100644 --- a/fe/src/main/java/com/cloudera/impala/analysis/CreateTableStmt.java +++ b/fe/src/main/java/com/cloudera/impala/analysis/CreateTableStmt.java @@ -15,6 +15,7 @@ package com.cloudera.impala.analysis; import java.util.List; +import java.util.Set; import java.util.ArrayList; import com.cloudera.impala.catalog.FileFormat; @@ -28,10 +29,10 @@ import com.cloudera.impala.thrift.TTableName; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; /** * Represents a CREATE TABLE statement. - * TODO: Add support for creating partitioned tables (IMPALA-102) */ public class CreateTableStmt extends ParseNodeBase { private final ArrayList columnDefs; @@ -193,18 +194,31 @@ public class CreateTableStmt extends ParseNodeBase { public void analyze(Analyzer analyzer) throws AnalysisException { Preconditions.checkState(tableName != null && !tableName.isEmpty()); dbName = tableName.isFullyQualified() ? tableName.getDb() : analyzer.getDefaultDb(); - + if (analyzer.getCatalog().getDb(dbName) == null) { throw new AnalysisException("Database does not exist: " + dbName); } if (analyzer.getCatalog().containsTable(dbName, getTbl()) && !ifNotExists) { throw new AnalysisException(String.format("Table already exists: %s.%s", - dbName, getTbl())); + dbName, getTbl())); } if (columnDefs.size() == 0) { throw new AnalysisException("A table requires at least 1 column"); } + + // Check that all the column names are unique. + Set colNames = Sets.newHashSet(); + for (ColumnDef colDef: columnDefs) { + if (!colNames.add(colDef.getColName().toLowerCase())) { + throw new AnalysisException("Duplicate column name: " + colDef.getColName()); + } + } + for (ColumnDef colDef: partitionColumnDefs) { + if (!colNames.add(colDef.getColName().toLowerCase())) { + throw new AnalysisException("Duplicate column name: " + colDef.getColName()); + } + } } } diff --git a/fe/src/test/java/com/cloudera/impala/analysis/AnalyzerTest.java b/fe/src/test/java/com/cloudera/impala/analysis/AnalyzerTest.java index 29ca1cfa8..bf469835a 100644 --- a/fe/src/test/java/com/cloudera/impala/analysis/AnalyzerTest.java +++ b/fe/src/test/java/com/cloudera/impala/analysis/AnalyzerTest.java @@ -1672,6 +1672,14 @@ public class AnalyzerTest { "terminated by '|'"); AnalysisError("create table db_does_not_exist.new_table (i int)", "Database does not exist: db_does_not_exist"); + AnalysisError("create table new_table (i int, I string)", + "Duplicate column name: I"); + AnalysisError("create table new_table (c1 double, col2 int, c1 double, c4 string)", + "Duplicate column name: c1"); + AnalysisError("create table new_table (i int, s string) PARTITIONED BY (i int)", + "Duplicate column name: i"); + AnalysisError("create table new_table (i int) PARTITIONED BY (C int, c2 int, c int)", + "Duplicate column name: c"); } @Test