blob: c7c51c9e7116f1764c7a68ca0df83b1e26ddc962 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.impala.analysis;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.apache.impala.common.AnalysisException;
import org.apache.impala.service.FeSupport;
import com.google.common.base.Preconditions;
/**
* Representation of a single column:value element in the PARTITION (...) clause of an
* insert or alter table statement.
*/
public class PartitionKeyValue {
// Name of partitioning column.
private final String colName_;
// Value of partitioning column. Set to null for dynamic inserts.
private final Expr value_;
// Evaluation of value for static partition keys, null otherwise. Set in analyze().
private LiteralExpr literalValue_;
public PartitionKeyValue(String colName, Expr value) {
this.colName_ = colName.toLowerCase();
this.value_ = value;
}
public void analyze(Analyzer analyzer) throws AnalysisException {
if (value_ == null) return;
if (isStatic() && !value_.isConstant()) {
throw new AnalysisException(
String.format("Non-constant expressions are not supported " +
"as static partition-key values in '%s'.", toString()));
}
value_.analyze(analyzer);
literalValue_ = LiteralExpr.createBounded(value_, analyzer.getQueryCtx(),
StringLiteral.MAX_STRING_LEN);
}
public String getColName() { return colName_; }
public Expr getValue() { return value_; }
public LiteralExpr getLiteralValue() { return literalValue_; }
public boolean isDynamic() { return value_ == null; }
public boolean isStatic() { return !isDynamic(); }
@Override
public String toString() {
return isStatic() ? colName_ + "=" + value_.toSql() : colName_;
}
/**
* Returns a binary predicate as a SQL string which matches the column and value of this
* PartitionKeyValue. If the value is null, correctly substitutes 'IS' as the operator.
*/
public String toPredicateSql() {
String ident = ToSqlUtils.getIdentSql(colName_);
if (Expr.IS_NULL_LITERAL.apply(literalValue_) ||
literalValue_.getStringValue().isEmpty()) {
return ident + " IS NULL";
}
return isStatic() ? ident + "=" + value_.toSql() : ident;
}
/**
* Utility method that returns the string value for the given partition key. For
* NULL values (a NullLiteral type) or empty literal values this will return the
* given null partition key value.
*/
public static String getPartitionKeyValueString(LiteralExpr literalValue,
String nullPartitionKeyValue) {
Preconditions.checkNotNull(literalValue);
if (Expr.IS_NULL_LITERAL.apply(literalValue) ||
literalValue.getStringValue().isEmpty()) {
return nullPartitionKeyValue;
}
return literalValue.getStringValue();
}
/**
* Utility method that applies getPartitionKeyValueString to each literal to return
* a list of partitioning key values as strings.
*/
public static List<String> getPartitionKeyValueStringList(
List<LiteralExpr> literals, String nullPartitionKeyValue) {
List<String> partValues = new ArrayList<>();
for (LiteralExpr partValue : literals) {
partValues.add(getPartitionKeyValueString(partValue, nullPartitionKeyValue));
}
return partValues;
}
public static Comparator<PartitionKeyValue> getColNameComparator() {
return new Comparator<PartitionKeyValue>() {
@Override
public int compare(PartitionKeyValue t, PartitionKeyValue o) {
return t.colName_.compareTo(o.colName_);
}
};
}
}