Package org.eigenbase.test

Source Code of org.eigenbase.test.RexTransformerTest

/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde 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.eigenbase.test;

import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
import org.eigenbase.sql.fun.*;
import org.eigenbase.sql.type.*;

import net.hydromatic.optiq.jdbc.JavaTypeFactoryImpl;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
* Tests transformations on rex nodes.
*/
public class RexTransformerTest {
  //~ Instance fields --------------------------------------------------------

  RexBuilder rexBuilder = null;
  RexNode x;
  RexNode y;
  RexNode z;
  RexNode trueRex;
  RexNode falseRex;
  RelDataType boolRelDataType;
  RelDataTypeFactory typeFactory;

  //~ Methods ----------------------------------------------------------------

  @Before
  public void setUp() {
    typeFactory = new JavaTypeFactoryImpl();
    rexBuilder = new RexBuilder(typeFactory);
    boolRelDataType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);

    x = new RexInputRef(
        0,
        typeFactory.createTypeWithNullability(boolRelDataType, true));
    y = new RexInputRef(
        1,
        typeFactory.createTypeWithNullability(boolRelDataType, true));
    z = new RexInputRef(
        2,
        typeFactory.createTypeWithNullability(boolRelDataType, true));
    trueRex = rexBuilder.makeLiteral(true);
    falseRex = rexBuilder.makeLiteral(false);
  }

  void check(
      Boolean encapsulateType,
      RexNode node,
      String expected) {
    RexNode root;
    if (null == encapsulateType) {
      root = node;
    } else if (encapsulateType.equals(Boolean.TRUE)) {
      root =
          rexBuilder.makeCall(
              SqlStdOperatorTable.IS_TRUE,
              node);
    } else {
      // encapsulateType.equals(Boolean.FALSE)
      root =
          rexBuilder.makeCall(
              SqlStdOperatorTable.IS_FALSE,
              node);
    }

    RexTransformer transformer = new RexTransformer(root, rexBuilder);
    RexNode result = transformer.transformNullSemantics();
    String actual = result.toString();
    if (!actual.equals(expected)) {
      String msg =
          "\nExpected=<" + expected + ">\n  Actual=<" + actual + ">";
      fail(msg);
    }
  }

  @Test public void testPreTests() {
    // can make variable nullable?
    RexNode node =
        new RexInputRef(
            0,
            typeFactory.createTypeWithNullability(
                typeFactory.createSqlType(SqlTypeName.BOOLEAN),
                true));
    assertTrue(node.getType().isNullable());

    // can make variable not nullable?
    node =
        new RexInputRef(
            0,
            typeFactory.createTypeWithNullability(
                typeFactory.createSqlType(SqlTypeName.BOOLEAN),
                false));
    assertFalse(node.getType().isNullable());
  }

  @Test public void testNonBooleans() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.PLUS,
            x,
            y);
    String expected = node.toString();
    check(Boolean.TRUE, node, expected);
    check(Boolean.FALSE, node, expected);
    check(null, node, expected);
  }

  /**
   * the or operator should pass through unchanged since e.g. x OR y should
   * return true if x=null and y=true if it was transformed into something
   * like (x ISNOTNULL) AND (y ISNOTNULL) AND (x OR y) an incorrect result
   * could be produced
   */
  @Test public void testOrUnchanged() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.OR,
            x,
            y);
    String expected = node.toString();
    check(Boolean.TRUE, node, expected);
    check(Boolean.FALSE, node, expected);
    check(null, node, expected);
  }

  @Test public void testSimpleAnd() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.AND,
            x,
            y);
    check(
        Boolean.FALSE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), AND($0, $1))");
  }

  @Test public void testSimpleEquals() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.EQUALS,
            x,
            y);
    check(
        Boolean.TRUE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), =($0, $1))");
  }

  @Test public void testSimpleNotEquals() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.NOT_EQUALS,
            x,
            y);
    check(
        Boolean.FALSE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), <>($0, $1))");
  }

  @Test public void testSimpleGreaterThan() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.GREATER_THAN,
            x,
            y);
    check(
        Boolean.TRUE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), >($0, $1))");
  }

  @Test public void testSimpleGreaterEquals() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.GREATER_THAN_OR_EQUAL,
            x,
            y);
    check(
        Boolean.FALSE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), >=($0, $1))");
  }

  @Test public void testSimpleLessThan() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN,
            x,
            y);
    check(
        Boolean.TRUE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), <($0, $1))");
  }

  @Test public void testSimpleLessEqual() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
            x,
            y);
    check(
        Boolean.FALSE,
        node,
        "AND(AND(IS NOT NULL($0), IS NOT NULL($1)), <=($0, $1))");
  }

  @Test public void testOptimizeNonNullLiterals() {
    RexNode node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
            x,
            trueRex);
    check(Boolean.TRUE, node, "AND(IS NOT NULL($0), <=($0, true))");
    node =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
            trueRex,
            x);
    check(Boolean.FALSE, node, "AND(IS NOT NULL($0), <=(true, $0))");
  }

  @Test public void testSimpleIdentifier() {
    RexNode node = rexBuilder.makeInputRef(boolRelDataType, 0);
    check(Boolean.TRUE, node, "=(IS TRUE($0), true)");
  }

  @Test public void testMixed1() {
    // x=true AND y
    RexNode op1 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.EQUALS,
            x,
            trueRex);
    RexNode and =
        rexBuilder.makeCall(
            SqlStdOperatorTable.AND,
            op1,
            y);
    check(
        Boolean.FALSE,
        and,
        "AND(IS NOT NULL($1), AND(AND(IS NOT NULL($0), =($0, true)), $1))");
  }

  @Test public void testMixed2() {
    // x!=true AND y>z
    RexNode op1 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.NOT_EQUALS,
            x,
            trueRex);
    RexNode op2 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.GREATER_THAN,
            y,
            z);
    RexNode and =
        rexBuilder.makeCall(
            SqlStdOperatorTable.AND,
            op1,
            op2);
    check(
        Boolean.FALSE,
        and,
        "AND(AND(IS NOT NULL($0), <>($0, true)), AND(AND(IS NOT NULL($1), IS NOT NULL($2)), >($1, $2)))");
  }

  @Test public void testMixed3() {
    // x=y AND false>z
    RexNode op1 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.EQUALS,
            x,
            y);
    RexNode op2 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.GREATER_THAN,
            falseRex,
            z);
    RexNode and =
        rexBuilder.makeCall(
            SqlStdOperatorTable.AND,
            op1,
            op2);
    check(
        Boolean.TRUE,
        and,
        "AND(AND(AND(IS NOT NULL($0), IS NOT NULL($1)), =($0, $1)), AND(IS NOT NULL($2), >(false, $2)))");
  }
}

// End RexTransformerTest.java
TOP

Related Classes of org.eigenbase.test.RexTransformerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.