Package org.teiid.query.processor.eval

Source Code of org.teiid.query.processor.eval.TestExpressionEvaluator

/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/

package org.teiid.query.processor.eval;

import static org.junit.Assert.*;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.junit.Test;
import org.teiid.api.exception.query.ExpressionEvaluationException;
import org.teiid.common.buffer.BlockedException;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.query.eval.Evaluator;
import org.teiid.query.function.FunctionDescriptor;
import org.teiid.query.processor.FakeDataManager;
import org.teiid.query.processor.ProcessorDataManager;
import org.teiid.query.resolver.TestFunctionResolving;
import org.teiid.query.sql.lang.CollectionValueIterator;
import org.teiid.query.sql.lang.IsNullCriteria;
import org.teiid.query.sql.lang.Query;
import org.teiid.query.sql.lang.SubqueryContainer;
import org.teiid.query.sql.symbol.CaseExpression;
import org.teiid.query.sql.symbol.Constant;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.Function;
import org.teiid.query.sql.symbol.ScalarSubquery;
import org.teiid.query.sql.symbol.SearchedCaseExpression;
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.symbol.TestCaseExpression;
import org.teiid.query.sql.symbol.TestSearchedCaseExpression;
import org.teiid.query.sql.util.ValueIterator;
import org.teiid.query.unittest.FakeMetadataFactory;
import org.teiid.query.util.CommandContext;

@SuppressWarnings("nls")
public class TestExpressionEvaluator {

    public void helpTestEval(Expression expr, SingleElementSymbol[] elementList, Object[] valueList, ProcessorDataManager dataMgr, CommandContext context, Object expectedValue) {
        try {
            Object actualValue = helpEval(expr, elementList, valueList, dataMgr, context);
            assertEquals("Did not get expected result", expectedValue, actualValue); //$NON-NLS-1$
        } catch(TeiidException e) {
            fail("Received unexpected exception: " + e.getFullMessage()); //$NON-NLS-1$
        }
    }

    public Object helpEval(Expression expr, SingleElementSymbol[] elementList, Object[] valueList, ProcessorDataManager dataMgr, CommandContext context) throws ExpressionEvaluationException, BlockedException, TeiidComponentException {
        Map elements = new HashMap();
        if (elementList != null) {
            for(int i=0; i<elementList.length; i++) {
                elements.put(elementList[i], new Integer(i));
            }
        }
       
        List tuple = new ArrayList();
        if (valueList != null) {
            for(int i=0; i<valueList.length; i++) {
                tuple.add(valueList[i]);
            }
        }
        return new Evaluator(elements, dataMgr, context).evaluate(expr, tuple);
    }
   
    @Test public void testCaseExpression1() {
        CaseExpression expr = TestCaseExpression.example(3);
        expr.setExpression(new Constant("a")); //$NON-NLS-1$
        helpTestEval(expr, null, null, null, null, new Integer(0));
        expr.setExpression(new Constant("b")); //$NON-NLS-1$
        helpTestEval(expr, null, null, null, null, new Integer(1));
        expr.setExpression(new Constant("c")); //$NON-NLS-1$
        helpTestEval(expr, null, null, null, null, new Integer(2));
        expr.setExpression(new Constant("d")); //$NON-NLS-1$
        helpTestEval(expr, null, null, null, null, new Integer(9999));
    }
   
    @Test public void testSearchedCaseExpression1() {
        SearchedCaseExpression expr = TestSearchedCaseExpression.example(3);
        helpTestEval(expr,
                     new SingleElementSymbol[] {new ElementSymbol("x")}, //$NON-NLS-1$
                     new Object[] {new Integer(0)},
                     null,
                     null,
                     new Integer(0));
        helpTestEval(expr,
                     new SingleElementSymbol[] {new ElementSymbol("x")}, //$NON-NLS-1$
                     new Object[] {new Integer(1)},
                     null,
                     null,
                     new Integer(1));
        helpTestEval(expr,
                     new SingleElementSymbol[] {new ElementSymbol("x")}, //$NON-NLS-1$
                     new Object[] {new Integer(2)},
                     null,
                     null,
                     new Integer(2));
        helpTestEval(expr,
                     new SingleElementSymbol[] {new ElementSymbol("x")}, //$NON-NLS-1$
                     new Object[] {new Integer(3)},
                     null,
                     null,
                     new Integer(9999));
    }
   
    @Test public void testConstant() {
        helpTestEval(new Constant("xyz", String.class), new SingleElementSymbol[0], new Object[0], null, null, "xyz"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    @Test public void testElement1() {
        ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
        ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
       
        SingleElementSymbol[] elements = new SingleElementSymbol[] {
            e1, e2
        };
       
        Object[] values = new Object[] {
            "xyz", "abc" //$NON-NLS-1$ //$NON-NLS-2$
        };
       
        helpTestEval(e1, elements, values, null, null, "xyz"); //$NON-NLS-1$
    }

    @Test public void testElement2() {
        ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
        ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
       
        SingleElementSymbol[] elements = new SingleElementSymbol[] {
            e1, e2
        };
       
        Object[] values = new Object[] {
            "xyz", "abc" //$NON-NLS-1$ //$NON-NLS-2$
        };

        helpTestEval(e2, elements, values, null, null, "abc"); //$NON-NLS-1$
    }
   
    /**
     * Element Symbols must have values set during evaluation
     */
    @Test public void testElement3() throws Exception {
        ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
       
        SingleElementSymbol[] elements = new SingleElementSymbol[] {};
       
        Object[] values = new Object[] {
            "xyz", "abc" //$NON-NLS-1$ //$NON-NLS-2$
        };

        try {
            helpEval(e2, elements, values, null, null);
            fail("Exception expected"); //$NON-NLS-1$
        } catch (TeiidComponentException e){
          //this should be a componentexception, since it is unexpected
            assertEquals(e.getMessage(), "Error Code:ERR.015.006.0033 Message:Unable to evaluate e2: No value was available"); //$NON-NLS-1$
        }
    }

    @Test public void testFunction1() {
        ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
        e1.setType(String.class);       
        ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
        e2.setType(String.class);
       
        Function func = new Function("concat", new Expression[] { e1, e2 }); //$NON-NLS-1$
        FunctionDescriptor desc = FakeMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("concat", new Class[] { String.class, String.class } ); //$NON-NLS-1$
        func.setFunctionDescriptor(desc);

        SingleElementSymbol[] elements = new SingleElementSymbol[] {
            e1, e2
        };
       
        Object[] values = new Object[] {
            "xyz", "abc" //$NON-NLS-1$ //$NON-NLS-2$
        };


        helpTestEval(func, elements, values, null, null, "xyzabc"); //$NON-NLS-1$
    }

    @Test public void testFunction2() {
        ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
        e1.setType(String.class);       
        ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
        e2.setType(String.class);
       
        Function func = new Function("concat", new Expression[] { e2, e1 }); //$NON-NLS-1$
        FunctionDescriptor desc = FakeMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("concat", new Class[] { String.class, String.class } ); //$NON-NLS-1$
        func.setFunctionDescriptor(desc);

        SingleElementSymbol[] elements = new SingleElementSymbol[] {
            e1, e2
        };
       
        Object[] values = new Object[] {
            "xyz", "abc" //$NON-NLS-1$ //$NON-NLS-2$
        };
       
        helpTestEval(func, elements, values, null, null, "abcxyz"); //$NON-NLS-1$
    }
   
    @Test public void testLookupFunction() {
        ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
        e1.setType(String.class);       
        ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
        e1.setType(Integer.class);       
       
        Function func = new Function("lookup", new Expression[] { new Constant("pm1.g1"), new Constant("e2"), new Constant("e1"), e1 }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
        FunctionDescriptor desc = FakeMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("lookup", new Class[] { String.class, String.class, String.class, String.class } ); //$NON-NLS-1$
        func.setFunctionDescriptor(desc);

        SingleElementSymbol[] elements = new SingleElementSymbol[] {
            e1, e2
        };
       
        Object[] values = new Object[] {
            "xyz", new Integer(5) //$NON-NLS-1$
        };
       
        FakeDataManager dataMgr = new FakeDataManager();
        Map valueMap = new HashMap();
        valueMap.put("xyz", new Integer(5)); //$NON-NLS-1$
        dataMgr.defineCodeTable("pm1.g1", "e1", "e2", valueMap); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
       
        helpTestEval(func, elements, values, dataMgr, null, new Integer(5));
    }

    @Test public void testScalarSubquery() throws Exception{
        ScalarSubquery expr = new ScalarSubquery(new Query());
        ArrayList values = new ArrayList(1);
        values.add("a"); //$NON-NLS-1$
        Object expected = "a"; //$NON-NLS-1$
        helpTestWithValueIterator(expr, values, expected);
    }

  private void helpTestWithValueIterator(ScalarSubquery expr,
      List<?> values, Object expected)
      throws BlockedException,
      TeiidComponentException, ExpressionEvaluationException {
    final CollectionValueIterator valueIter = new CollectionValueIterator(values);
        CommandContext cc = new CommandContext();
        assertEquals(expected, new Evaluator(Collections.emptyMap(), null, cc) {
          @Override
          protected ValueIterator evaluateSubquery(
              SubqueryContainer container, List tuple)
              throws TeiidProcessingException, BlockedException,
              TeiidComponentException {
            return valueIter;
          }
        }.evaluate(expr, null) );
  }

    @Test public void testScalarSubquery2() throws Exception{
        ScalarSubquery expr = new ScalarSubquery(new Query());
        ArrayList values = new ArrayList(1);
        values.add(null);
        helpTestWithValueIterator(expr, values, null);
    }

    @Test public void testScalarSubquery3() throws Exception{
        ScalarSubquery expr = new ScalarSubquery(new Query());
        helpTestWithValueIterator(expr, Collections.emptyList(), null);
    }

    @Test public void testScalarSubqueryFails() throws Exception{
        ScalarSubquery expr = new ScalarSubquery(new Query());
        ArrayList values = new ArrayList(2);
        values.add("a"); //$NON-NLS-1$
        values.add("b"); //$NON-NLS-1$
       
        try {
          helpTestWithValueIterator(expr, values, null);
            fail("Expected ExpressionEvaluationException but got none"); //$NON-NLS-1$
        } catch (ExpressionEvaluationException e) {
            assertEquals("Error Code:ERR.015.006.0058 Message:Unable to evaluate (<undefined>): Error Code:ERR.015.006.0058 Message:The command of this scalar subquery returned more than one value: <undefined>", e.getMessage()); //$NON-NLS-1$
        }
    }

    @Test public void testUser() throws Exception {
        Function func = new Function("user", new Expression[] {}); //$NON-NLS-1$
        FunctionDescriptor desc = FakeMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("user", new Class[] {} );         //$NON-NLS-1$
        func.setFunctionDescriptor(desc);

        FakeDataManager dataMgr = new FakeDataManager();
        CommandContext context = new CommandContext(new Long(1), null, null, null, 0);
        context.setUserName("logon")//$NON-NLS-1$
        assertEquals(context.getUserName(), new Evaluator(Collections.emptyMap(), dataMgr, context).evaluate(func, Collections.emptyList()) );      
    }
   
    /*
     * This is the only test that depends upon the the testsrc/metamatrix.properties
     * and testsrc/config.xml. If the implementation is changed, please update/remove
     * these files.
     * @throws Exception
     */
    @Test public void testEnv() throws Exception {
        Function func = new Function("env", new Expression[] {}); //$NON-NLS-1$
        FunctionDescriptor desc = FakeMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("env", new Class[] {String.class} );         //$NON-NLS-1$
        func.setFunctionDescriptor(desc);
       
        FakeDataManager dataMgr = new FakeDataManager();
       
        Properties props = new Properties();
        props.setProperty("http_host", "testHostName"); //$NON-NLS-1$ //$NON-NLS-2$
        props.setProperty("http_port", "8000"); //$NON-NLS-1$ //$NON-NLS-2$
        CommandContext context = new CommandContext(new Long(1), null, null, null, null, 0, props, false);
       
        func.setArgs(new Expression[] {new Constant("http_host")}); //$NON-NLS-1$
        assertEquals("testHostName", new Evaluator(Collections.emptyMap(), dataMgr, context).evaluate(func, Collections.emptyList())); //$NON-NLS-1$
              
        func.setArgs(new Expression[] {new Constant("http_port")}); //$NON-NLS-1$
        assertEquals("8000", new Evaluator(Collections.emptyMap(), dataMgr, context).evaluate(func, Collections.emptyList())); //$NON-NLS-1$
    }
   
    public void helpTestCommandPayload(Serializable payload, String property, String expectedValue) throws Exception {
        Function func = new Function("commandpayload", new Expression[] {}); //$NON-NLS-1$
       
        Class[] parameterSignature = null;
        if(property == null) {
            parameterSignature = new Class[] {};
        } else {
            parameterSignature = new Class[] { String.class };
        }       
        FunctionDescriptor desc = FakeMetadataFactory.SFM.getSystemFunctionLibrary().findFunction("commandpayload", parameterSignature );         //$NON-NLS-1$
        func.setFunctionDescriptor(desc);
       
        FakeDataManager dataMgr = new FakeDataManager();      
        CommandContext context = new CommandContext(new Long(-1), null, "user", payload, "vdb", 1, null, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        if(property != null) {
            func.setArgs(new Expression[] {new Constant(property)});
        }
        String actual = (String) new Evaluator(Collections.emptyMap(), dataMgr, context).evaluate(func, Collections.emptyList());
        assertEquals(expectedValue, actual);
    }
   
    @Test public void testCommandPayloadNoArgsWithPayload() throws Exception {
        helpTestCommandPayload("blah", null, "blah"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    @Test public void testCommandPayloadNoArgsWithoutPayload() throws Exception {
        helpTestCommandPayload(null, null, null);
    }

    @Test public void testCommandPayloadNoArgsWithNonStringPayload() throws Exception {
        helpTestCommandPayload(Boolean.TRUE, null, "true"); //$NON-NLS-1$
    }
   
    @Test public void testCommandPayloadArgWithPayload() throws Exception {
        Properties props = new Properties();
        props.setProperty("p1", "v1"); //$NON-NLS-1$ //$NON-NLS-2$
        props.setProperty("p2", "v2"); //$NON-NLS-1$ //$NON-NLS-2$
        helpTestCommandPayload(props, "p1", "v1"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    @Test public void testCommandPayloadArgWithPayloadMissingProp() throws Exception {
        Properties props = new Properties();
        props.setProperty("p1", "v1"); //$NON-NLS-1$ //$NON-NLS-2$
        props.setProperty("p2", "v2"); //$NON-NLS-1$ //$NON-NLS-2$
        helpTestCommandPayload(props, "BOGUS", null); //$NON-NLS-1$
    }

    @Test public void testCommandPayloadArgWithoutPayload() throws Exception {
        Properties props = new Properties();
        props.setProperty("p1", "v1"); //$NON-NLS-1$ //$NON-NLS-2$
        props.setProperty("p2", "v2"); //$NON-NLS-1$ //$NON-NLS-2$
        helpTestCommandPayload(null, "BOGUS", null); //$NON-NLS-1$
    }

    @Test(expected=ExpressionEvaluationException.class) public void testCommandPayloadArgWithBadPayload() throws Exception {
        helpTestCommandPayload(Boolean.TRUE, "BOGUS", null); //$NON-NLS-1$
    }
   
    @Test public void testBigDecimalFromDoubleDivision() throws Exception {
      Expression ex = TestFunctionResolving.getExpression("convert(1.0, bigdecimal)/3");
      assertEquals(new BigDecimal("0.3333333333333333"), Evaluator.evaluate(ex));
    }
   
    @Test public void testBigDecimalDivision() throws Exception {
      Expression ex = TestFunctionResolving.getExpression("1/convert('3.0', bigdecimal)");
      assertEquals(new BigDecimal("0.3333333333333333"), Evaluator.evaluate(ex));
    }
   
    @Test public void testIsNull() throws Exception {
      assertEquals(Boolean.TRUE, Evaluator.evaluate(new IsNullCriteria(new Constant(null, DataTypeManager.DefaultDataClasses.BOOLEAN))));
    }
   
    @Test public void testIsNull1() throws Exception {
      assertEquals(Boolean.FALSE, Evaluator.evaluate(new IsNullCriteria(new Constant(Boolean.TRUE, DataTypeManager.DefaultDataClasses.BOOLEAN))));
    }
   
    @Test public void testIsNull3() throws Exception {
      IsNullCriteria inc = new IsNullCriteria(new Constant(null, DataTypeManager.DefaultDataClasses.BOOLEAN));
      inc.setNegated(true);
      assertEquals(Boolean.FALSE, Evaluator.evaluate(inc));
    }
   
    @Test public void testIsNull4() throws Exception {
      IsNullCriteria inc = new IsNullCriteria(new Constant(Boolean.TRUE, DataTypeManager.DefaultDataClasses.BOOLEAN));
      inc.setNegated(true);
      assertEquals(Boolean.TRUE, Evaluator.evaluate(inc));
    }
   
}
TOP

Related Classes of org.teiid.query.processor.eval.TestExpressionEvaluator

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.