| // 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.Arrays; |
| import java.time.format.DateTimeFormatter; |
| import java.time.format.DateTimeParseException; |
| import java.time.LocalDate; |
| |
| import com.google.common.base.Preconditions; |
| import org.apache.impala.catalog.Type; |
| import org.apache.impala.common.AnalysisException; |
| import org.apache.impala.common.InternalException; |
| import org.apache.impala.service.FeSupport; |
| import org.apache.impala.thrift.TExprNode; |
| import org.apache.impala.thrift.TExprNodeType; |
| import org.apache.impala.thrift.TDateLiteral; |
| import org.apache.impala.thrift.TParseDateStringResult; |
| |
| /** |
| * Represents a literal date as a string formatted as yyyy-MM-dd. |
| * Impala supports the same DATE literal syntax as Hive. For example: DATE '2019-02-15'. |
| */ |
| public class DateLiteral extends LiteralExpr { |
| // Days since 1970-01-01. Class DateValue in the backend uses the same representation. |
| private final int daysSinceEpoch_; |
| // String representation of date |
| private final String strDate_; |
| |
| public DateLiteral(int daysSinceEpoch, String strDate) { |
| daysSinceEpoch_ = daysSinceEpoch; |
| strDate_ = strDate; |
| type_ = Type.DATE; |
| } |
| |
| public DateLiteral(String strDate) throws AnalysisException { |
| type_ = Type.DATE; |
| |
| // Parse date string. |
| // Accept different variations. E.g.: '2011-01-01', '2011-1-01', '2011-01-1', |
| // '2011-1-1'. |
| TParseDateStringResult result; |
| try { |
| result = FeSupport.parseDateString(strDate); |
| } catch (InternalException e) { |
| throw new AnalysisException("Error parsing date literal: " + e.getMessage(), e); |
| } |
| |
| if (!result.valid || !result.isSetDays_since_epoch()) { |
| throw new AnalysisException("Invalid date literal: '" + strDate + "'"); |
| } |
| |
| daysSinceEpoch_ = result.getDays_since_epoch(); |
| if (result.isSetCanonical_date_string()) { |
| strDate_ = result.getCanonical_date_string(); |
| } else { |
| strDate_ = strDate; |
| } |
| } |
| |
| /** |
| * Copy c'tor used in clone. |
| */ |
| protected DateLiteral(DateLiteral other) { |
| super(other); |
| daysSinceEpoch_ = other.daysSinceEpoch_; |
| strDate_ = other.strDate_; |
| } |
| |
| @Override |
| public boolean localEquals(Expr that) { |
| return super.localEquals(that) |
| && daysSinceEpoch_ == ((DateLiteral) that).daysSinceEpoch_; |
| } |
| |
| @Override |
| public int hashCode() { return daysSinceEpoch_; } |
| |
| @Override |
| public String toSqlImpl(ToSqlOptions options) { |
| // ANSI Date Literal format. |
| return "DATE '" + getStringValue() + "'"; |
| } |
| |
| @Override |
| public String getStringValue() { return strDate_; } |
| |
| public int getValue() { return daysSinceEpoch_; } |
| |
| @Override |
| protected void toThrift(TExprNode msg) { |
| msg.node_type = TExprNodeType.DATE_LITERAL; |
| msg.date_literal = new TDateLiteral(); |
| msg.date_literal.setDays_since_epoch(daysSinceEpoch_); |
| msg.date_literal.setDate_string(strDate_); |
| } |
| |
| @Override |
| protected Expr uncheckedCastTo(Type targetType) throws AnalysisException { |
| if (targetType.equals(type_)) { |
| return this; |
| } else { |
| return new CastExpr(targetType, this); |
| } |
| } |
| |
| @Override |
| public int compareTo(LiteralExpr o) { |
| int ret = super.compareTo(o); |
| if (ret != 0) return ret; |
| DateLiteral other = (DateLiteral) o; |
| return daysSinceEpoch_ - other.daysSinceEpoch_; |
| } |
| |
| @Override |
| public Expr clone() { return new DateLiteral(this); } |
| } |