/*
 * 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.Spaces;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
import org.apache.calcite.rel.type.RelDataTypeImpl;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rel.type.RelDataTypeSystemImpl;
import org.apache.calcite.sql.SqlCollation;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.fun.SqlLibraryOperators;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.BasicSqlType;
import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.test.RexImplicationCheckerFixtures;
import org.apache.calcite.util.DateString;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.NlsString;
import org.apache.calcite.util.TimeString;
import org.apache.calcite.util.TimeWithTimeZoneString;
import org.apache.calcite.util.TimestampString;
import org.apache.calcite.util.TimestampWithTimeZoneString;
import org.apache.calcite.util.Util;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasToString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.params.provider.Arguments.of;

/**
 * Test for {@link RexBuilder}.
 */
class RexBuilderTest {

  private static final int PRECISION = 256;

  /**
   * MySqlTypeFactoryImpl provides a specific implementation of
   * {@link SqlTypeFactoryImpl} which sets precision to 256 for VARCHAR.
   */
  private static class MySqlTypeFactoryImpl extends SqlTypeFactoryImpl {

    MySqlTypeFactoryImpl(RelDataTypeSystem typeSystem) {
      super(typeSystem);
    }

    @Override public RelDataType createTypeWithNullability(
        final RelDataType type,
        final boolean nullable) {
      if (type.getSqlTypeName() == SqlTypeName.VARCHAR) {
        return new BasicSqlType(this.typeSystem, type.getSqlTypeName(),
            PRECISION);
      }
      return super.createTypeWithNullability(type, nullable);
    }
  }


  /**
   * Test RexBuilder.ensureType()
   */
  @Test void testEnsureTypeWithAny() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RexBuilder builder = new RexBuilder(typeFactory);

    RexNode node =
        new RexLiteral(Boolean.TRUE,
            typeFactory.createSqlType(SqlTypeName.BOOLEAN), SqlTypeName.BOOLEAN);
    RexNode ensuredNode =
        builder.ensureType(typeFactory.createSqlType(SqlTypeName.ANY), node,
            true);

    assertEquals(node, ensuredNode);
  }

  /**
   * Test RexBuilder.ensureType()
   */
  @Test void testEnsureTypeWithItself() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RexBuilder builder = new RexBuilder(typeFactory);

    RexNode node =
        new RexLiteral(Boolean.TRUE,
            typeFactory.createSqlType(SqlTypeName.BOOLEAN), SqlTypeName.BOOLEAN);
    RexNode ensuredNode =
        builder.ensureType(typeFactory.createSqlType(SqlTypeName.BOOLEAN), node,
            true);

    assertEquals(node, ensuredNode);
  }

  /**
   * Test RexBuilder.ensureType()
   */
  @Test void testEnsureTypeWithDifference() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RexBuilder builder = new RexBuilder(typeFactory);

    RexNode node =
        new RexLiteral(Boolean.TRUE,
            typeFactory.createSqlType(SqlTypeName.BOOLEAN), SqlTypeName.BOOLEAN);
    RexNode ensuredNode =
        builder.ensureType(typeFactory.createSqlType(SqlTypeName.INTEGER), node,
            true);

    assertNotEquals(node, ensuredNode);
    assertEquals(ensuredNode.getType(), typeFactory.createSqlType(SqlTypeName.INTEGER));
  }

  private static final long MOON = -14159025000L;

  private static final int MOON_DAY = -164;

  private static final int MOON_TIME = 10575000;

  /** Tests {@link RexBuilder#makeTimestampLiteral(TimestampString, int)}. */
  @Test void testTimestampLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RelDataType timestampType =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
    final RelDataType timestampType3 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 3);
    final RelDataType timestampType9 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 9);
    final RelDataType timestampType18 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP, 18);
    final RexBuilder builder = new RexBuilder(typeFactory);

    // Old way: provide a Calendar
    final Calendar calendar = Util.calendar();
    calendar.set(1969, Calendar.JULY, 21, 2, 56, 15); // one small step
    calendar.set(Calendar.MILLISECOND, 0);
    checkTimestamp(builder.makeLiteral(calendar, timestampType));

    // Old way #2: Provide a Long
    checkTimestamp(builder.makeLiteral(MOON, timestampType));

    // The new way
    final TimestampString ts = new TimestampString(1969, 7, 21, 2, 56, 15);
    checkTimestamp(builder.makeLiteral(ts, timestampType));

    // Now with milliseconds
    final TimestampString ts2 = ts.withMillis(56);
    assertThat(ts2, hasToString("1969-07-21 02:56:15.056"));
    final RexLiteral literal2 = builder.makeLiteral(ts2, timestampType3);
    assertThat(literal2.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15.056"));

    // Now with nanoseconds
    final TimestampString ts3 = ts.withNanos(56);
    final RexLiteral literal3 = builder.makeLiteral(ts3, timestampType9);
    assertThat(literal3.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15"));
    final TimestampString ts3b = ts.withNanos(2345678);
    final RexLiteral literal3b = builder.makeLiteral(ts3b, timestampType9);
    assertThat(literal3b.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15.002"));

    // Now with a very long fraction
    final TimestampString ts4 = ts.withFraction("102030405060708090102");
    final RexLiteral literal4 = builder.makeLiteral(ts4, timestampType18);
    assertThat(literal4.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15.102"));
  }

  /** Test cases for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-6389">[CALCITE-6389]
   * RexBuilder.removeCastFromLiteral does not preserve semantics for some types of literal</a>. */
  @Test void testRemoveCast() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RexBuilder builder = new RexBuilder(typeFactory);

    // Can remove cast of an integer to an integer
    BigDecimal value = new BigDecimal(10);
    RelDataType toType = builder.typeFactory.createSqlType(SqlTypeName.INTEGER);
    assertTrue(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.INTEGER));

    // Can remove cast from integer to decimal
    toType = builder.typeFactory.createSqlType(SqlTypeName.DECIMAL);
    assertTrue(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.INTEGER));

    // 250 is too large for a TINYINT
    value = new BigDecimal(250);
    toType = builder.typeFactory.createSqlType(SqlTypeName.TINYINT);
    assertFalse(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.INTEGER));

    // 50 isn't too large for a TINYINT
    value = new BigDecimal(50);
    toType = builder.typeFactory.createSqlType(SqlTypeName.TINYINT);
    assertTrue(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.INTEGER));

    // 120.25 cannot be represented with precision 2 and scale 2 without loss
    value = new BigDecimal("120.25");
    toType = builder.typeFactory.createSqlType(SqlTypeName.DECIMAL, 2, 2);
    assertFalse(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.DECIMAL));

    // 120.25 cannot be represented with precision 5 and scale 1 without rounding
    value = new BigDecimal("120.25");
    toType = builder.typeFactory.createSqlType(SqlTypeName.DECIMAL, 5, 1);
    assertFalse(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.DECIMAL));

    // longmax + 1 cannot be represented as a long
    value = new BigDecimal(Long.MAX_VALUE).add(BigDecimal.ONE);
    toType = builder.typeFactory.createSqlType(SqlTypeName.BIGINT);
    assertFalse(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.DECIMAL));

    // Cast to decimal of an INTERVAL '5' seconds cannot be removed
    value = new BigDecimal("5");
    toType = builder.typeFactory.createSqlType(SqlTypeName.DECIMAL, 5, 1);
    assertFalse(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.INTERVAL_SECOND));

    // Cast to decimal of an INTERVAL '5' minutes cannot be removed
    value = new BigDecimal("5");
    toType = builder.typeFactory.createSqlType(SqlTypeName.DECIMAL, 5, 1);
    assertFalse(builder.canRemoveCastFromLiteral(toType, value, SqlTypeName.INTERVAL_MINUTE));
  }

  @Test void testTimestampString() {
    final TimestampString ts = new TimestampString(1969, 7, 21, 2, 56, 15);
    assertThat(ts, hasToString("1969-07-21 02:56:15"));
    assertThat(ts.round(1), is(ts));

    // Now with milliseconds
    final TimestampString ts2 = ts.withMillis(56);
    assertThat(ts2, hasToString("1969-07-21 02:56:15.056"));

    // toString
    assertThat(ts2.round(1), hasToString("1969-07-21 02:56:15"));
    assertThat(ts2.round(2), hasToString("1969-07-21 02:56:15.05"));
    assertThat(ts2.round(3), hasToString("1969-07-21 02:56:15.056"));
    assertThat(ts2.round(4), hasToString("1969-07-21 02:56:15.056"));

    assertThat(ts2.toString(6), is("1969-07-21 02:56:15.056000"));
    assertThat(ts2.toString(1), is("1969-07-21 02:56:15.0"));
    assertThat(ts2.toString(0), is("1969-07-21 02:56:15"));

    assertThat(ts2.round(0), hasToString("1969-07-21 02:56:15"));
    assertThat(ts2.round(0).toString(0), is("1969-07-21 02:56:15"));
    assertThat(ts2.round(0).toString(1), is("1969-07-21 02:56:15.0"));
    assertThat(ts2.round(0).toString(2), is("1969-07-21 02:56:15.00"));

    // Now with milliseconds ending in zero (3 equivalent strings).
    final TimestampString ts3 = ts.withMillis(10);
    assertThat(ts3, hasToString("1969-07-21 02:56:15.01"));

    final TimestampString ts3b = new TimestampString("1969-07-21 02:56:15.01");
    assertThat(ts3b, hasToString("1969-07-21 02:56:15.01"));
    assertThat(ts3b, is(ts3));

    final TimestampString ts3c = new TimestampString("1969-07-21 02:56:15.010");
    assertThat(ts3c, hasToString("1969-07-21 02:56:15.01"));
    assertThat(ts3c, is(ts3));

    // Now with nanoseconds
    final TimestampString ts4 = ts.withNanos(56);
    assertThat(ts4, hasToString("1969-07-21 02:56:15.000000056"));

    // Check rounding; uses RoundingMode.DOWN
    final TimestampString ts5 = ts.withNanos(2345670);
    assertThat(ts5, hasToString("1969-07-21 02:56:15.00234567"));
    assertThat(ts5.round(0), hasToString("1969-07-21 02:56:15"));
    assertThat(ts5.round(1), hasToString("1969-07-21 02:56:15"));
    assertThat(ts5.round(2), hasToString("1969-07-21 02:56:15"));
    assertThat(ts5.round(3), hasToString("1969-07-21 02:56:15.002"));
    assertThat(ts5.round(4), hasToString("1969-07-21 02:56:15.0023"));
    assertThat(ts5.round(5), hasToString("1969-07-21 02:56:15.00234"));
    assertThat(ts5.round(6), hasToString("1969-07-21 02:56:15.002345"));
    assertThat(ts5.round(600), hasToString("1969-07-21 02:56:15.00234567"));

    // Now with a very long fraction
    final TimestampString ts6 = ts.withFraction("102030405060708090102");
    assertThat(ts6, hasToString("1969-07-21 02:56:15.102030405060708090102"));

    // From milliseconds
    final TimestampString ts7 =
        TimestampString.fromMillisSinceEpoch(1456513560123L);
    assertThat(ts7, hasToString("2016-02-26 19:06:00.123"));

    final TimestampString ts8 =
        TimestampString.fromMillisSinceEpoch(1456513560120L);
    assertThat(ts8, hasToString("2016-02-26 19:06:00.12"));

    final TimestampString ts9 = ts8.withFraction("9876543210");
    assertThat(ts9, hasToString("2016-02-26 19:06:00.987654321"));

    // TimestampString.toCalendar
    final Calendar c = ts9.toCalendar();
    assertThat(c.get(Calendar.ERA), is(1)); // CE
    assertThat(c.get(Calendar.YEAR), is(2016));
    assertThat(c.get(Calendar.MONTH), is(1)); // February
    assertThat(c.get(Calendar.DATE), is(26));
    assertThat(c.get(Calendar.HOUR_OF_DAY), is(19));
    assertThat(c.get(Calendar.MINUTE), is(6));
    assertThat(c.get(Calendar.SECOND), is(0));
    assertThat(c.get(Calendar.MILLISECOND), is(987)); // RoundingMode.DOWN
    assertThat(ts9.getMillisSinceEpoch(), is(c.getTimeInMillis()));

    // TimestampString.fromCalendarFields
    c.set(Calendar.YEAR, 1969);
    final TimestampString ts10 = TimestampString.fromCalendarFields(c);
    assertThat(ts10, hasToString("1969-02-26 19:06:00.987"));
    assertThat(ts10.getMillisSinceEpoch(), is(c.getTimeInMillis()));
  }

  @Test void testTimeString() {
    final TimeString t = new TimeString(2, 56, 15);
    assertThat(t, hasToString("02:56:15"));
    assertThat(t.round(1), is(t));

    // Now with milliseconds
    final TimeString t2 = t.withMillis(56);
    assertThat(t2, hasToString("02:56:15.056"));

    // toString
    assertThat(t2.round(1), hasToString("02:56:15"));
    assertThat(t2.round(2), hasToString("02:56:15.05"));
    assertThat(t2.round(3), hasToString("02:56:15.056"));
    assertThat(t2.round(4), hasToString("02:56:15.056"));

    assertThat(t2.toString(6), is("02:56:15.056000"));
    assertThat(t2.toString(1), is("02:56:15.0"));
    assertThat(t2.toString(0), is("02:56:15"));

    assertThat(t2.round(0), hasToString("02:56:15"));
    assertThat(t2.round(0).toString(0), is("02:56:15"));
    assertThat(t2.round(0).toString(1), is("02:56:15.0"));
    assertThat(t2.round(0).toString(2), is("02:56:15.00"));

    // Now with milliseconds ending in zero (3 equivalent strings).
    final TimeString t3 = t.withMillis(10);
    assertThat(t3, hasToString("02:56:15.01"));

    final TimeString t3b = new TimeString("02:56:15.01");
    assertThat(t3b, hasToString("02:56:15.01"));
    assertThat(t3b, is(t3));

    final TimeString t3c = new TimeString("02:56:15.010");
    assertThat(t3c, hasToString("02:56:15.01"));
    assertThat(t3c, is(t3));

    // Now with nanoseconds
    final TimeString t4 = t.withNanos(56);
    assertThat(t4, hasToString("02:56:15.000000056"));

    // Check rounding; uses RoundingMode.DOWN
    final TimeString t5 = t.withNanos(2345670);
    assertThat(t5, hasToString("02:56:15.00234567"));
    assertThat(t5.round(0), hasToString("02:56:15"));
    assertThat(t5.round(1), hasToString("02:56:15"));
    assertThat(t5.round(2), hasToString("02:56:15"));
    assertThat(t5.round(3), hasToString("02:56:15.002"));
    assertThat(t5.round(4), hasToString("02:56:15.0023"));
    assertThat(t5.round(5), hasToString("02:56:15.00234"));
    assertThat(t5.round(6), hasToString("02:56:15.002345"));
    assertThat(t5.round(600), hasToString("02:56:15.00234567"));

    // Now with a very long fraction
    final TimeString t6 = t.withFraction("102030405060708090102");
    assertThat(t6, hasToString("02:56:15.102030405060708090102"));
  }

  private void checkTimestamp(RexLiteral literal) {
    assertThat(literal, hasToString("1969-07-21 02:56:15"));
    assertThat(literal.getValue() instanceof Calendar, is(true));
    assertThat(literal.getValue2() instanceof Long, is(true));
    assertThat(literal.getValue3() instanceof Long, is(true));
    assertThat((Long) literal.getValue2(), is(MOON));
    assertThat(literal.getValueAs(Calendar.class), notNullValue());
    assertThat(literal.getValueAs(TimestampString.class), notNullValue());
  }

  /** Tests
   * {@link RexBuilder#makeTimestampWithLocalTimeZoneLiteral(TimestampString, int)}. */
  @Test void testTimestampWithLocalTimeZoneLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RelDataType timestampType =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE);
    final RelDataType timestampType3 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE, 3);
    final RelDataType timestampType9 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE, 9);
    final RelDataType timestampType18 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE, 18);
    final RexBuilder builder = new RexBuilder(typeFactory);

    // The new way
    final TimestampWithTimeZoneString ts =
        new TimestampWithTimeZoneString(1969, 7, 21, 2, 56, 15,
            TimeZone.getTimeZone("PST").getID());
    checkTimestampWithLocalTimeZone(
        builder.makeLiteral(ts.getLocalTimestampString(), timestampType));

    // Now with milliseconds
    final TimestampWithTimeZoneString ts2 = ts.withMillis(56);
    assertThat(ts2, hasToString("1969-07-21 02:56:15.056 PST"));
    final RexLiteral literal2 =
        builder.makeLiteral(ts2.getLocalTimestampString(), timestampType3);
    assertThat(literal2.getValue(), hasToString("1969-07-21 02:56:15.056"));

    // Now with nanoseconds
    final TimestampWithTimeZoneString ts3 = ts.withNanos(56);
    final RexLiteral literal3 =
        builder.makeLiteral(ts3.getLocalTimestampString(), timestampType9);
    assertThat(literal3.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15"));
    final TimestampWithTimeZoneString ts3b = ts.withNanos(2345678);
    final RexLiteral literal3b =
        builder.makeLiteral(ts3b.getLocalTimestampString(), timestampType9);
    assertThat(literal3b.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15.002"));

    // Now with a very long fraction
    final TimestampWithTimeZoneString ts4 = ts.withFraction("102030405060708090102");
    final RexLiteral literal4 =
        builder.makeLiteral(ts4.getLocalTimestampString(), timestampType18);
    assertThat(literal4.getValueAs(TimestampString.class),
        hasToString("1969-07-21 02:56:15.102"));

    // toString
    assertThat(ts2.round(1), hasToString("1969-07-21 02:56:15 PST"));
    assertThat(ts2.round(2), hasToString("1969-07-21 02:56:15.05 PST"));
    assertThat(ts2.round(3), hasToString("1969-07-21 02:56:15.056 PST"));
    assertThat(ts2.round(4), hasToString("1969-07-21 02:56:15.056 PST"));

    assertThat(ts2.toString(6), is("1969-07-21 02:56:15.056000 PST"));
    assertThat(ts2.toString(1), is("1969-07-21 02:56:15.0 PST"));
    assertThat(ts2.toString(0), is("1969-07-21 02:56:15 PST"));

    assertThat(ts2.round(0), hasToString("1969-07-21 02:56:15 PST"));
    assertThat(ts2.round(0).toString(0), is("1969-07-21 02:56:15 PST"));
    assertThat(ts2.round(0).toString(1), is("1969-07-21 02:56:15.0 PST"));
    assertThat(ts2.round(0).toString(2), is("1969-07-21 02:56:15.00 PST"));
  }

  private void checkTimestampWithLocalTimeZone(RexLiteral literal) {
    assertThat(literal,
        hasToString("1969-07-21 02:56:15:TIMESTAMP_WITH_LOCAL_TIME_ZONE(0)"));
    assertThat(literal.getValue() instanceof TimestampString, is(true));
    assertThat(literal.getValue2() instanceof Long, is(true));
    assertThat(literal.getValue3() instanceof Long, is(true));
  }

  /** Tests
   * {@link RexBuilder#makeTimestampTzLiteral(TimestampWithTimeZoneString, int)}. */
  @Test void testTimestampTzLiterals() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RelDataType timestampType =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_TZ);
    final RelDataType timestampType3 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_TZ, 3);
    final RelDataType timestampType9 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_TZ, 9);
    final RelDataType timestampType18 =
        typeFactory.createSqlType(SqlTypeName.TIMESTAMP_TZ, 18);
    final RexBuilder builder = new RexBuilder(typeFactory);

    // The new way
    final TimestampWithTimeZoneString ts =
        new TimestampWithTimeZoneString(1969, 7, 21, 2, 56, 15,
            TimeZone.getTimeZone("PST").getID());
    checkTimestampTz(builder.makeLiteral(ts, timestampType));

    // Now with milliseconds
    final TimestampWithTimeZoneString ts2 = ts.withMillis(56);
    assertThat(ts2, hasToString("1969-07-21 02:56:15.056 PST"));
    final RexLiteral literal2 =
        builder.makeLiteral(ts2, timestampType3);
    assertThat(literal2.getValue(), hasToString("1969-07-21 02:56:15.056 PST"));

    // Now with nanoseconds
    final TimestampWithTimeZoneString ts3 = ts.withNanos(56);
    final RexLiteral literal3 =
        builder.makeLiteral(ts3, timestampType9);
    assertThat(literal3.getValueAs(TimestampWithTimeZoneString.class),
        hasToString("1969-07-21 02:56:15 PST"));
    final TimestampWithTimeZoneString ts3b = ts.withNanos(2345678);
    final RexLiteral literal3b =
        builder.makeLiteral(ts3b, timestampType9);
    assertThat(literal3b.getValueAs(TimestampWithTimeZoneString.class),
        hasToString("1969-07-21 02:56:15.002 PST"));

    // Now with a very long fraction
    final TimestampWithTimeZoneString ts4 = ts.withFraction("102030405060708090102");
    final RexLiteral literal4 =
        builder.makeLiteral(ts4, timestampType18);
    assertThat(literal4.getValueAs(TimestampWithTimeZoneString.class),
        hasToString("1969-07-21 02:56:15.102 PST"));

    // toString
    assertThat(ts2.round(1), hasToString("1969-07-21 02:56:15 PST"));
    assertThat(ts2.round(2), hasToString("1969-07-21 02:56:15.05 PST"));
    assertThat(ts2.round(3), hasToString("1969-07-21 02:56:15.056 PST"));
    assertThat(ts2.round(4), hasToString("1969-07-21 02:56:15.056 PST"));

    assertThat(ts2.toString(6), is("1969-07-21 02:56:15.056000 PST"));
    assertThat(ts2.toString(1), is("1969-07-21 02:56:15.0 PST"));
    assertThat(ts2.toString(0), is("1969-07-21 02:56:15 PST"));

    assertThat(ts2.round(0), hasToString("1969-07-21 02:56:15 PST"));
    assertThat(ts2.round(0).toString(0), is("1969-07-21 02:56:15 PST"));
    assertThat(ts2.round(0).toString(1), is("1969-07-21 02:56:15.0 PST"));
    assertThat(ts2.round(0).toString(2), is("1969-07-21 02:56:15.00 PST"));
  }

  private void checkTimestampTz(RexLiteral literal) {
    assertThat(literal,
        hasToString("1969-07-21 02:56:15 PST:TIMESTAMP_TZ(0)"));
    assertThat(literal.getValue() instanceof TimestampWithTimeZoneString, is(true));
    assertThat(literal.getValue2() instanceof Long, is(true));
    assertThat(literal.getValue3() instanceof Long, is(true));
  }

  /** Tests {@link RexBuilder#makeTimeLiteral(TimeString, int)}. */
  @Test void testTimeLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType timeType = typeFactory.createSqlType(SqlTypeName.TIME);
    final RelDataType timeType3 =
        typeFactory.createSqlType(SqlTypeName.TIME, 3);
    final RelDataType timeType9 =
        typeFactory.createSqlType(SqlTypeName.TIME, 9);
    final RelDataType timeType18 =
        typeFactory.createSqlType(SqlTypeName.TIME, 18);
    final RexBuilder builder = new RexBuilder(typeFactory);

    // Old way: provide a Calendar
    final Calendar calendar = Util.calendar();
    calendar.set(1969, Calendar.JULY, 21, 2, 56, 15); // one small step
    calendar.set(Calendar.MILLISECOND, 0);
    checkTime(builder.makeLiteral(calendar, timeType));

    // Old way #2: Provide a Long
    checkTime(builder.makeLiteral(MOON_TIME, timeType));

    // The new way
    final TimeString t = new TimeString(2, 56, 15);
    assertThat(t.getMillisOfDay(), is(10575000));
    checkTime(builder.makeLiteral(t, timeType));

    // Now with milliseconds
    final TimeString t2 = t.withMillis(56);
    assertThat(t2.getMillisOfDay(), is(10575056));
    assertThat(t2, hasToString("02:56:15.056"));
    final RexLiteral literal2 = builder.makeLiteral(t2, timeType3);
    assertThat(literal2.getValueAs(TimeString.class),
        hasToString("02:56:15.056"));

    // Now with nanoseconds
    final TimeString t3 = t.withNanos(2345678);
    assertThat(t3.getMillisOfDay(), is(10575002));
    final RexLiteral literal3 = builder.makeLiteral(t3, timeType9);
    assertThat(literal3.getValueAs(TimeString.class),
        hasToString("02:56:15.002"));

    // Now with a very long fraction
    final TimeString t4 = t.withFraction("102030405060708090102");
    assertThat(t4.getMillisOfDay(), is(10575102));
    final RexLiteral literal4 = builder.makeLiteral(t4, timeType18);
    assertThat(literal4.getValueAs(TimeString.class),
        hasToString("02:56:15.102"));

    // toString
    assertThat(t2.round(1), hasToString("02:56:15"));
    assertThat(t2.round(2), hasToString("02:56:15.05"));
    assertThat(t2.round(3), hasToString("02:56:15.056"));
    assertThat(t2.round(4), hasToString("02:56:15.056"));

    assertThat(t2.toString(6), is("02:56:15.056000"));
    assertThat(t2.toString(1), is("02:56:15.0"));
    assertThat(t2.toString(0), is("02:56:15"));

    assertThat(t2.round(0), hasToString("02:56:15"));
    assertThat(t2.round(0).toString(0), is("02:56:15"));
    assertThat(t2.round(0).toString(1), is("02:56:15.0"));
    assertThat(t2.round(0).toString(2), is("02:56:15.00"));

    assertThat(TimeString.fromMillisOfDay(53560123),
        hasToString("14:52:40.123"));
  }

  private void checkTime(RexLiteral literal) {
    assertThat(literal, hasToString("02:56:15"));
    assertThat(literal.getValue() instanceof Calendar, is(true));
    assertThat(literal.getValue2() instanceof Integer, is(true));
    assertThat(literal.getValue3() instanceof Integer, is(true));
    assertThat((Integer) literal.getValue2(), is(MOON_TIME));
    assertThat(literal.getValueAs(Calendar.class), notNullValue());
    assertThat(literal.getValueAs(TimeString.class), notNullValue());
  }

  /** Tests {@link RexBuilder#makeDateLiteral(DateString)}. */
  @Test void testDateLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType dateType = typeFactory.createSqlType(SqlTypeName.DATE);
    final RexBuilder builder = new RexBuilder(typeFactory);

    // Old way: provide a Calendar
    final Calendar calendar = Util.calendar();
    calendar.set(1969, Calendar.JULY, 21); // one small step
    calendar.set(Calendar.MILLISECOND, 0);
    checkDate(builder.makeLiteral(calendar, dateType));

    // Old way #2: Provide in Integer
    checkDate(builder.makeLiteral(MOON_DAY, dateType));

    // The new way
    final DateString d = new DateString(1969, 7, 21);
    checkDate(builder.makeLiteral(d, dateType));
  }

  private void checkDate(RexLiteral literal) {
    assertThat(literal, hasToString("1969-07-21"));
    assertThat(literal.getValue() instanceof Calendar, is(true));
    assertThat(literal.getValue2() instanceof Integer, is(true));
    assertThat(literal.getValue3() instanceof Integer, is(true));
    assertThat((Integer) literal.getValue2(), is(MOON_DAY));
    assertThat(literal.getValueAs(Calendar.class), notNullValue());
    assertThat(literal.getValueAs(DateString.class), notNullValue());
  }

  /** Test case for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-2306">[CALCITE-2306]
   * AssertionError in {@link RexLiteral#getValue3} with null literal of type
   * DECIMAL</a>. */
  @Test void testDecimalLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RelDataType type = typeFactory.createSqlType(SqlTypeName.DECIMAL);
    final RexBuilder builder = new RexBuilder(typeFactory);
    final RexLiteral literal = builder.makeExactLiteral(null, type);
    assertThat(literal.getValue3(), nullValue());
  }

  /** Test case for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-3587">[CALCITE-3587]
   * RexBuilder may lose decimal fraction for creating literal with DECIMAL type</a>.
   */
  @Test void testDecimal() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RelDataType type = typeFactory.createSqlType(SqlTypeName.DECIMAL, 4, 2);
    final RexBuilder builder = new RexBuilder(typeFactory);
    try {
      builder.makeLiteral(12.3, type);
      fail();
    } catch (AssertionError e) {
      assertThat(e.getMessage(),
          is("java.lang.Double is not compatible with DECIMAL, try to use makeExactLiteral"));
    }
  }

  /** Tests {@link DateString} year range. */
  @Test void testDateStringYearError() {
    try {
      final DateString dateString = new DateString(11969, 7, 21);
      fail("expected exception, got " + dateString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Year out of range: [11969]"));
    }
    try {
      final DateString dateString = new DateString("12345-01-23");
      fail("expected exception, got " + dateString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(),
          containsString("Invalid date format: [12345-01-23]"));
    }
  }

  /** Tests {@link DateString} month range. */
  @Test void testDateStringMonthError() {
    try {
      final DateString dateString = new DateString(1969, 27, 21);
      fail("expected exception, got " + dateString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Month out of range: [27]"));
    }
    try {
      final DateString dateString = new DateString("1234-13-02");
      fail("expected exception, got " + dateString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Month out of range: [13]"));
    }
  }

  /** Tests {@link DateString} day range. */
  @Test void testDateStringDayError() {
    try {
      final DateString dateString = new DateString(1969, 7, 41);
      fail("expected exception, got " + dateString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Day out of range: [41]"));
    }
    try {
      final DateString dateString = new DateString("1234-01-32");
      fail("expected exception, got " + dateString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Day out of range: [32]"));
    }
    // We don't worry about the number of days in a month. 30 is in range.
    final DateString dateString = new DateString("1234-02-30");
    assertThat(dateString, notNullValue());
  }

  /** Tests {@link TimeString} hour range. */
  @Test void testTimeStringHourError() {
    try {
      final TimeString timeString = new TimeString(111, 34, 56);
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Hour out of range: [111]"));
    }
    try {
      final TimeString timeString = new TimeString("24:00:00");
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Hour out of range: [24]"));
    }
    try {
      final TimeString timeString = new TimeString("24:00");
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(),
          containsString("Invalid time format: [24:00]"));
    }
  }

  /** Tests {@link TimeString} minute range. */
  @Test void testTimeStringMinuteError() {
    try {
      final TimeString timeString = new TimeString(12, 334, 56);
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Minute out of range: [334]"));
    }
    try {
      final TimeString timeString = new TimeString("12:60:23");
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Minute out of range: [60]"));
    }
  }

  /** Tests {@link TimeString} second range. */
  @Test void testTimeStringSecondError() {
    try {
      final TimeString timeString = new TimeString(12, 34, 567);
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Second out of range: [567]"));
    }
    try {
      final TimeString timeString = new TimeString(12, 34, -4);
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Second out of range: [-4]"));
    }
    try {
      final TimeString timeString = new TimeString("12:34:60");
      fail("expected exception, got " + timeString);
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), containsString("Second out of range: [60]"));
    }
  }

  /**
   * Test string literal encoding.
   */
  @Test void testStringLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RelDataType varchar =
        typeFactory.createSqlType(SqlTypeName.VARCHAR);
    final RexBuilder builder = new RexBuilder(typeFactory);

    final NlsString latin1 = new NlsString("foobar", "LATIN1", SqlCollation.IMPLICIT);
    final NlsString utf8 = new NlsString("foobar", "UTF8", SqlCollation.IMPLICIT);

    RexLiteral literal = builder.makePreciseStringLiteral("foobar");
    assertEquals("'foobar'", literal.toString());
    literal =
        builder.makePreciseStringLiteral(
            new ByteString(new byte[] { 'f', 'o', 'o', 'b', 'a', 'r'}),
            "UTF8", SqlCollation.IMPLICIT);
    assertEquals("_UTF8'foobar'", literal.toString());
    assertEquals("_UTF8'foobar':CHAR(6) CHARACTER SET \"UTF-8\"",
        literal.computeDigest(RexDigestIncludeType.ALWAYS));
    literal =
        builder.makePreciseStringLiteral(
            new ByteString("\u82f1\u56fd".getBytes(StandardCharsets.UTF_8)),
            "UTF8", SqlCollation.IMPLICIT);
    assertEquals("_UTF8'\u82f1\u56fd'", literal.toString());
    // Test again to check decode cache.
    literal =
        builder.makePreciseStringLiteral(
            new ByteString("\u82f1".getBytes(StandardCharsets.UTF_8)),
            "UTF8", SqlCollation.IMPLICIT);
    assertEquals("_UTF8'\u82f1'", literal.toString());
    try {
      literal =
          builder.makePreciseStringLiteral(
              new ByteString("\u82f1\u56fd".getBytes(StandardCharsets.UTF_8)),
              "GB2312", SqlCollation.IMPLICIT);
      fail("expected exception, got " + literal);
    } catch (RuntimeException e) {
      assertThat(e.getMessage(), containsString("Failed to encode"));
    }
    literal = builder.makeLiteral(latin1, varchar);
    assertEquals("_LATIN1'foobar'", literal.toString());
    literal = builder.makeLiteral(utf8, varchar);
    assertEquals("_UTF8'foobar'", literal.toString());
  }

  /** Tests {@link RexBuilder#makeExactLiteral(java.math.BigDecimal)}. */
  @Test void testBigDecimalLiteral() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(new RelDataTypeSystemImpl() {
      @Override public int getMaxPrecision(SqlTypeName typeName) {
        return 38;
      }
    });
    final RexBuilder builder = new RexBuilder(typeFactory);
    checkBigDecimalLiteral(builder, "25");
    checkBigDecimalLiteral(builder, "9.9");
    checkBigDecimalLiteral(builder, "0");
    checkBigDecimalLiteral(builder, "-75.5");
    checkBigDecimalLiteral(builder, "10000000");
    checkBigDecimalLiteral(builder, "100000.111111111111111111");
    checkBigDecimalLiteral(builder, "-100000.111111111111111111");
    checkBigDecimalLiteral(builder, "73786976294838206464"); // 2^66
    checkBigDecimalLiteral(builder, "-73786976294838206464");
  }

  @Test void testMakeIn() {
    final RelDataTypeFactory typeFactory =
            new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder rexBuilder = new RexBuilder(typeFactory);
    final RelDataType floatType = typeFactory.createSqlType(SqlTypeName.REAL);
    RexNode left = rexBuilder.makeInputRef(floatType, 0);
    final RexNode literal1 = rexBuilder.makeLiteral(1.0f, floatType);
    final RexNode literal2 = rexBuilder.makeLiteral(2.0f, floatType);
    RexNode inCall = rexBuilder.makeIn(left, ImmutableList.of(literal1, literal2));
    assertThat(inCall.getKind(), is(SqlKind.SEARCH));
  }

  /** Test case for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-4555">[CALCITE-4555]
   * Invalid zero literal value is used for
   * TIMESTAMP WITH LOCAL TIME ZONE type in RexBuilder</a>. */
  @ParameterizedTest
  @MethodSource("testData4testMakeZeroLiteral")
  void testMakeZeroLiteral(RelDataType type, RexLiteral expected) {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder rexBuilder = new RexBuilder(typeFactory);
    assertThat(rexBuilder.makeZeroLiteral(type), is(equalTo(expected)));
  }

  private static Stream<Arguments> testData4testMakeZeroLiteral() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder rexBuilder = new RexBuilder(typeFactory);
    BiFunction<RelDataType, Function<RelDataType, Comparable>, Arguments> type2rexLiteral =
        (relDataType, relDataTypeComparableFunction) ->
            of(relDataType,
                rexBuilder.makeLiteral(
                    relDataTypeComparableFunction.apply(relDataType), relDataType));
    return Stream.of(
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.CHAR),
            relDataType -> new NlsString(Spaces.of(relDataType.getPrecision()), null, null)),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.VARCHAR),
            relDataType -> new NlsString("", null, null)),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.BINARY),
            relDataType -> new ByteString(new byte[relDataType.getPrecision()])),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.VARBINARY),
            relDataType -> ByteString.EMPTY),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TINYINT),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.SMALLINT),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.INTEGER),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.BIGINT),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.DECIMAL),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.FLOAT),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.REAL),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.DOUBLE),
            relDataType -> BigDecimal.ZERO),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.BOOLEAN),
            relDataType -> false),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TIME),
            relDataType -> DateTimeUtils.ZERO_CALENDAR),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.DATE),
            relDataType -> DateTimeUtils.ZERO_CALENDAR),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TIMESTAMP),
            relDataType -> DateTimeUtils.ZERO_CALENDAR),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE),
            relDataType -> new TimeString(0, 0, 0)),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE),
            relDataType -> new TimestampString(0, 1, 1, 0, 0, 0)),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TIME_TZ),
            relDataType -> new TimeWithTimeZoneString(0, 0, 0, "GMT+00:00")),
        type2rexLiteral.apply(typeFactory.createSqlType(SqlTypeName.TIMESTAMP_TZ),
            relDataType -> new TimestampWithTimeZoneString(0, 1, 1, 0, 0, 0, "GMT+00:00")));
  }

  /** Test case for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-4632">[CALCITE-4632]
   * Find the least restrictive datatype for SARG</a>. */
  @Test void testLeastRestrictiveTypeForSargMakeIn() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder rexBuilder = new RexBuilder(typeFactory);
    final RelDataType decimalType = typeFactory.createSqlType(SqlTypeName.DECIMAL);
    RexNode left = rexBuilder.makeInputRef(decimalType, 0);
    final RexNode literal1 = rexBuilder.makeExactLiteral(new BigDecimal("1.0"));
    final RexNode literal2 = rexBuilder.makeExactLiteral(new BigDecimal("20000.0"));

    RexNode inCall = rexBuilder.makeIn(left, ImmutableList.of(literal1, literal2));
    assertThat(inCall.getKind(), is(SqlKind.SEARCH));

    final RexNode sarg = ((RexCall) inCall).operands.get(1);
    RelDataType expected = typeFactory.createSqlType(SqlTypeName.DECIMAL, 6, 1);
    assertEquals(sarg.getType(), expected);
  }

  /** Test case for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-4632">[CALCITE-4632]
   * Find the least restrictive datatype for SARG</a>. */
  @Test void testLeastRestrictiveTypeForSargMakeBetween() {
    final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder rexBuilder = new RexBuilder(typeFactory);
    final RelDataType decimalType = typeFactory.createSqlType(SqlTypeName.DECIMAL);
    RexNode left = rexBuilder.makeInputRef(decimalType, 0);
    final RexNode literal1 = rexBuilder.makeExactLiteral(new BigDecimal("1.0"));
    final RexNode literal2 = rexBuilder.makeExactLiteral(new BigDecimal("20000.0"));

    RexNode betweenCall = rexBuilder.makeBetween(left, literal1, literal2);
    assertThat(betweenCall.getKind(), is(SqlKind.SEARCH));

    final RexNode sarg = ((RexCall) betweenCall).operands.get(1);
    RelDataType expected = typeFactory.createSqlType(SqlTypeName.DECIMAL, 6, 1);
    assertEquals(sarg.getType(), expected);
  }

  /** Tests {@link RexCopier#visitOver(RexOver)}. */
  @Test void testCopyOver() {
    final RelDataTypeFactory sourceTypeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 65536);

    final RelDataTypeFactory targetTypeFactory =
        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder builder = new RexBuilder(targetTypeFactory);

    final RexOver node =
        (RexOver) builder.makeOver(type, SqlStdOperatorTable.COUNT,
            ImmutableList.of(builder.makeInputRef(type, 0)),
            ImmutableList.of(builder.makeInputRef(type, 1)),
            ImmutableList.of(
                new RexFieldCollation(builder.makeInputRef(type, 2),
                    ImmutableSet.of())),
            RexWindowBounds.UNBOUNDED_PRECEDING,
            RexWindowBounds.CURRENT_ROW,
            true, true, false, false, false);
    final RexNode copy = builder.copy(node);
    assertTrue(copy instanceof RexOver);

    RexOver result = (RexOver) copy;
    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
    assertThat(result.getType().getPrecision(), is(PRECISION));
    assertThat(result.getWindow(), is(node.getWindow()));
    assertThat(result.getAggOperator(), is(node.getAggOperator()));
    assertThat(result.getAggOperator(), is(node.getAggOperator()));
    assertEquals(node.isDistinct(), result.isDistinct());
    assertEquals(node.ignoreNulls(), result.ignoreNulls());
    for (int i = 0; i < node.getOperands().size(); i++) {
      assertThat(result.getOperands().get(i).getType().getSqlTypeName(),
          is(node.getOperands().get(i).getType().getSqlTypeName()));
      assertThat(result.getOperands().get(i).getType().getPrecision(),
          is(PRECISION));
    }
  }

  /** Tests {@link RexCopier#visitCorrelVariable(RexCorrelVariable)}. */
  @Test void testCopyCorrelVariable() {
    final RelDataTypeFactory sourceTypeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 65536);

    final RelDataTypeFactory targetTypeFactory =
        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder builder = new RexBuilder(targetTypeFactory);

    final RexCorrelVariable node =
        (RexCorrelVariable) builder.makeCorrel(type, new CorrelationId(0));
    final RexNode copy = builder.copy(node);
    assertTrue(copy instanceof RexCorrelVariable);

    final RexCorrelVariable result = (RexCorrelVariable) copy;
    assertThat(result.id, is(node.id));
    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
    assertThat(result.getType().getPrecision(), is(PRECISION));
  }

  /** Tests {@link RexCopier#visitLocalRef(RexLocalRef)}. */
  @Test void testCopyLocalRef() {
    final RelDataTypeFactory sourceTypeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 65536);

    final RelDataTypeFactory targetTypeFactory =
        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder builder = new RexBuilder(targetTypeFactory);

    final RexLocalRef node = new RexLocalRef(0, type);
    final RexNode copy = builder.copy(node);
    assertTrue(copy instanceof RexLocalRef);

    final RexLocalRef result = (RexLocalRef) copy;
    assertThat(result.getIndex(), is(node.getIndex()));
    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
    assertThat(result.getType().getPrecision(), is(PRECISION));
  }

  /** Tests {@link RexCopier#visitDynamicParam(RexDynamicParam)}. */
  @Test void testCopyDynamicParam() {
    final RelDataTypeFactory sourceTypeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 65536);

    final RelDataTypeFactory targetTypeFactory =
        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder builder = new RexBuilder(targetTypeFactory);

    final RexDynamicParam node = builder.makeDynamicParam(type, 0);
    final RexNode copy = builder.copy(node);
    assertTrue(copy instanceof RexDynamicParam);

    final RexDynamicParam result = (RexDynamicParam) copy;
    assertThat(result.getIndex(), is(node.getIndex()));
    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
    assertThat(result.getType().getPrecision(), is(PRECISION));
  }

  /** Tests {@link RexCopier#visitRangeRef(RexRangeRef)}. */
  @Test void testCopyRangeRef() {
    final RelDataTypeFactory sourceTypeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 65536);

    final RelDataTypeFactory targetTypeFactory =
        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder builder = new RexBuilder(targetTypeFactory);

    final RexRangeRef node = builder.makeRangeReference(type, 1, true);
    final RexNode copy = builder.copy(node);
    assertTrue(copy instanceof RexRangeRef);

    final RexRangeRef result = (RexRangeRef) copy;
    assertThat(result.getOffset(), is(node.getOffset()));
    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
    assertThat(result.getType().getPrecision(), is(PRECISION));
  }

  private void checkBigDecimalLiteral(RexBuilder builder, String val) {
    final RexLiteral literal = builder.makeExactLiteral(new BigDecimal(val));
    assertThat("builder.makeExactLiteral(new BigDecimal(" + val
            + ")).getValueAs(BigDecimal.class).toString()",
        literal.getValueAs(BigDecimal.class), hasToString(val));
  }

  @Test void testValidateRexFieldAccess() {
    final RelDataTypeFactory typeFactory =
        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
    final RexBuilder builder = new RexBuilder(typeFactory);

    RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
    RelDataType longType = typeFactory.createSqlType(SqlTypeName.BIGINT);

    RelDataType structType =
        typeFactory.createStructType(Arrays.asList(intType, longType),
            Arrays.asList("x", "y"));
    RexInputRef inputRef = builder.makeInputRef(structType, 0);

    // construct RexFieldAccess fails because of negative index
    IllegalArgumentException e1 = assertThrows(IllegalArgumentException.class, () -> {
      RelDataTypeField field = new RelDataTypeFieldImpl("z", -1, intType);
      new RexFieldAccess(inputRef, field);
    });
    assertThat(e1.getMessage(),
        is("Field #-1: z INTEGER does not exist for expression $0"));

    // construct RexFieldAccess fails because of too large index
    IllegalArgumentException e2 = assertThrows(IllegalArgumentException.class, () -> {
      RelDataTypeField field = new RelDataTypeFieldImpl("z", 2, intType);
      new RexFieldAccess(inputRef, field);
    });
    assertThat(e2.getMessage(),
        is("Field #2: z INTEGER does not exist for expression $0"));

    // construct RexFieldAccess fails because of incorrect type
    IllegalArgumentException e3 = assertThrows(IllegalArgumentException.class, () -> {
      RelDataTypeField field = new RelDataTypeFieldImpl("z", 0, longType);
      new RexFieldAccess(inputRef, field);
    });
    assertThat(e3.getMessage(),
        is("Field #0: z BIGINT does not exist for expression $0"));

    // construct RexFieldAccess successfully
    RelDataTypeField field = new RelDataTypeFieldImpl("x", 0, intType);
    RexFieldAccess fieldAccess = new RexFieldAccess(inputRef, field);
    RexChecker checker = new RexChecker(structType, () -> null, Litmus.THROW);
    assertThat(fieldAccess.accept(checker), is(true));
  }

  /** Emulate a user defined type. */
  private static class UDT extends RelDataTypeImpl {
    UDT() {
      this.digest = "(udt)NOT NULL";
    }

    @Override protected void generateTypeString(StringBuilder sb, boolean withDetail) {
      sb.append("udt");
    }
  }

  @Test void testUDTLiteralDigest() {
    RexLiteral literal = new RexLiteral(new BigDecimal(0L), new UDT(), SqlTypeName.BIGINT);

    // when the space before "NOT NULL" is missing, the digest is not correct
    // and the suffix should not be removed.
    assertThat(literal.digest, is("0L:(udt)NOT NULL"));
  }


  /** Test case for
   * <a href="https://issues.apache.org/jira/browse/CALCITE-5489">[CALCITE-5489]
   * RexCall to TIMESTAMP_DIFF function fails to convert a TIMESTAMP literal to
   * a org.apache.calcite.avatica.util.TimeUnit</a>. */
  @Test void testTimestampDiffCall() {
    final RexImplicationCheckerFixtures.Fixture f =
        new RexImplicationCheckerFixtures.Fixture();
    final TimestampString ts =
        TimestampString.fromCalendarFields(Util.calendar());
    final RexNode literal = f.timestampLiteral(ts);
    final RexLiteral flag = f.rexBuilder.makeFlag(TimeUnit.QUARTER);
    assertThat(
        f.rexBuilder.makeCall(SqlLibraryOperators.DATEDIFF,
            flag, literal, literal),
        notNullValue());
    assertThat(
        f.rexBuilder.makeCall(SqlStdOperatorTable.TIMESTAMP_DIFF,
            flag, literal, literal),
        notNullValue());
    assertThat(
        f.rexBuilder.makeCall(SqlLibraryOperators.TIMESTAMP_DIFF3,
            literal, literal, flag),
        notNullValue());
    assertThat(
        f.rexBuilder.makeCall(SqlLibraryOperators.TIME_DIFF,
            literal, literal, flag),
        notNullValue());
  }
}
