Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.calcite.rex;
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.SqlCollation;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserUtil;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.CompositeList;
import org.apache.calcite.util.ConversionUtil;
import org.apache.calcite.util.DateString;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.NlsString;
import org.apache.calcite.util.SaffronProperties;
import org.apache.calcite.util.TimeString;
import org.apache.calcite.util.TimestampString;
import org.apache.calcite.util.Util;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.AbstractList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
/**
* Constant value in a row-expression.
*
*
There are several methods for creating literals in {@link RexBuilder}:
* {@link RexBuilder#makeLiteral(boolean)} and so forth.
*
*
How is the value stored? In that respect, the class is somewhat of a black
* box. There is a {@link #getValue} method which returns the value as an
* object, but the type of that value is implementation detail, and it is best
* that your code does not depend upon that knowledge. It is better to use
* task-oriented methods such as {@link #getValue2} and
* {@link #toJavaString}.
*
*
The allowable types and combinations are:
*
*
*
Allowable types for RexLiteral instances
*
*
TypeName
*
Meaning
*
Value type
*
*
*
{@link SqlTypeName#NULL}
*
The null value. It has its own special type.
*
null
*
*
*
{@link SqlTypeName#BOOLEAN}
*
Boolean, namely TRUE, FALSE or
* UNKNOWN.
*
{@link Boolean}, or null represents the UNKNOWN value
*
*
*
{@link SqlTypeName#DECIMAL}
*
Exact number, for example 0, -.5,
* 12345.
*
{@link BigDecimal}
*
*
*
{@link SqlTypeName#DOUBLE}
*
Approximate number, for example 6.023E-23.
*
{@link BigDecimal}
*
*
*
{@link SqlTypeName#DATE}
*
Date, for example DATE '1969-04'29'
*
{@link Calendar};
* also {@link Calendar} (UTC time zone)
* and {@link Integer} (days since POSIX epoch)
*
*
*
{@link SqlTypeName#TIME}
*
Time, for example TIME '18:37:42.567'
*
{@link Calendar};
* also {@link Calendar} (UTC time zone)
* and {@link Integer} (milliseconds since midnight)
*
*
*
{@link SqlTypeName#TIMESTAMP}
*
Timestamp, for example TIMESTAMP '1969-04-29
* 18:37:42.567'
*
{@link TimestampString};
* also {@link Calendar} (UTC time zone)
* and {@link Long} (milliseconds since POSIX epoch)
Interval, for example INTERVAL '2-3' YEAR TO MONTH
*
{@link BigDecimal};
* also {@link Integer} (months)
*
*
*
{@link SqlTypeName#CHAR}
*
Character constant, for example 'Hello, world!',
* '', _N'Bonjour', _ISO-8859-1'It''s superman!'
* COLLATE SHIFT_JIS$ja_JP$2. These are always CHAR, never VARCHAR.
*
{@link NlsString};
* also {@link String}
*
*
*
{@link SqlTypeName#BINARY}
*
Binary constant, for example X'7F34'. (The number of hexits
* must be even; see above.) These constants are always BINARY, never
* VARBINARY.
*
{@link ByteBuffer};
* also {@code byte[]}
*
*
*
{@link SqlTypeName#SYMBOL}
*
A symbol is a special type used to make parsing easier; it is not part of
* the SQL standard, and is not exposed to end-users. It is used to hold a flag,
* such as the LEADING flag in a call to the function
* TRIM([LEADING|TRAILING|BOTH] chars FROM string).
*
An enum class
*
*
*/
public class RexLiteral extends RexNode {
//~ Instance fields --------------------------------------------------------
/**
* The value of this literal. Must be consistent with its type, as per
* {@link #valueMatchesType}. For example, you can't store an
* {@link Integer} value here just because you feel like it -- all numbers are
* represented by a {@link BigDecimal}. But since this field is private, it
* doesn't really matter how the values are stored.
*/
private final Comparable value;
/**
* The real type of this literal, as reported by {@link #getType}.
*/
private final RelDataType type;
// TODO jvs 26-May-2006: Use SqlTypeFamily instead; it exists
// for exactly this purpose (to avoid the confusion which results
// from overloading SqlTypeName).
/**
* An indication of the broad type of this literal -- even if its type isn't
* a SQL type. Sometimes this will be different than the SQL type; for
* example, all exact numbers, including integers have typeName
* {@link SqlTypeName#DECIMAL}. See {@link #valueMatchesType} for the
* definitive story.
*/
private final SqlTypeName typeName;
private static final ImmutableList TIME_UNITS =
ImmutableList.copyOf(TimeUnit.values());
//~ Constructors -----------------------------------------------------------
/**
* Creates a RexLiteral.
*/
RexLiteral(
Comparable value,
RelDataType type,
SqlTypeName typeName) {
this.value = value;
this.type = Objects.requireNonNull(type);
this.typeName = Objects.requireNonNull(typeName);
Preconditions.checkArgument(valueMatchesType(value, typeName, true));
Preconditions.checkArgument((value == null) == type.isNullable());
Preconditions.checkArgument(typeName != SqlTypeName.ANY);
this.digest = toJavaString(value, typeName);
}
//~ Methods ----------------------------------------------------------------
/**
* @return whether value is appropriate for its type (we have rules about
* these things)
*/
public static boolean valueMatchesType(
Comparable value,
SqlTypeName typeName,
boolean strict) {
if (value == null) {
return true;
}
switch (typeName) {
case BOOLEAN:
// Unlike SqlLiteral, we do not allow boolean null.
return value instanceof Boolean;
case NULL:
return false; // value should have been null
case INTEGER: // not allowed -- use Decimal
case TINYINT:
case SMALLINT:
if (strict) {
throw Util.unexpected(typeName);
}
// fall through
case DECIMAL:
case DOUBLE:
case FLOAT:
case REAL:
case BIGINT:
return value instanceof BigDecimal;
case DATE:
return value instanceof DateString;
case TIME:
return value instanceof TimeString;
case TIME_WITH_LOCAL_TIME_ZONE:
return value instanceof TimeString;
case TIMESTAMP:
return value instanceof TimestampString;
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
return value instanceof TimestampString;
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
case INTERVAL_DAY:
case INTERVAL_DAY_HOUR:
case INTERVAL_DAY_MINUTE:
case INTERVAL_DAY_SECOND:
case INTERVAL_HOUR:
case INTERVAL_HOUR_MINUTE:
case INTERVAL_HOUR_SECOND:
case INTERVAL_MINUTE:
case INTERVAL_MINUTE_SECOND:
case INTERVAL_SECOND:
// The value of a DAY-TIME interval (whatever the start and end units,
// even say HOUR TO MINUTE) is in milliseconds (perhaps fractional
// milliseconds). The value of a YEAR-MONTH interval is in months.
return value instanceof BigDecimal;
case VARBINARY: // not allowed -- use Binary
if (strict) {
throw Util.unexpected(typeName);
}
// fall through
case BINARY:
return value instanceof ByteString;
case VARCHAR: // not allowed -- use Char
if (strict) {
throw Util.unexpected(typeName);
}
// fall through
case CHAR:
// A SqlLiteral's charset and collation are optional; not so a
// RexLiteral.
return (value instanceof NlsString)
&& (((NlsString) value).getCharset() != null)
&& (((NlsString) value).getCollation() != null);
case SYMBOL:
return value instanceof Enum;
case ROW:
case MULTISET:
return value instanceof List;
case ANY:
// Literal of type ANY is not legal. "CAST(2 AS ANY)" remains
// an integer literal surrounded by a cast function.
return false;
default:
throw Util.unexpected(typeName);
}
}
private static String toJavaString(
Comparable value,
SqlTypeName typeName) {
if (value == null) {
return "null";
}
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
printAsJava(value, pw, typeName, false);
pw.flush();
return sw.toString();
}
/** Returns whether a value is valid as a constant value, using the same
* criteria as {@link #valueMatchesType}. */
public static boolean validConstant(Object o, Litmus litmus) {
if (o == null
|| o instanceof BigDecimal
|| o instanceof NlsString
|| o instanceof ByteString) {
return litmus.succeed();
} else if (o instanceof List) {
List list = (List) o;
for (Object o1 : list) {
if (!validConstant(o1, litmus)) {
return litmus.fail("not a constant: {}", o1);
}
}
return litmus.succeed();
} else if (o instanceof Map) {
@SuppressWarnings("unchecked") final Map