/* * 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.optimizer.relational.rules; import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Ignore; import org.junit.Test; import org.teiid.api.exception.query.QueryMetadataException; import org.teiid.core.TeiidComponentException; import org.teiid.core.TeiidProcessingException; import org.teiid.metadata.Column; import org.teiid.query.metadata.QueryMetadataInterface; import org.teiid.query.metadata.TransformationMetadata; import org.teiid.query.optimizer.TestOptimizer; import org.teiid.query.optimizer.TestOptimizer.ComparisonMode; import org.teiid.query.optimizer.relational.RelationalPlanner; import org.teiid.query.optimizer.relational.plantree.NodeConstants; import org.teiid.query.optimizer.relational.plantree.NodeFactory; import org.teiid.query.optimizer.relational.plantree.PlanNode; import org.teiid.query.parser.QueryParser; import org.teiid.query.processor.TestVirtualDepJoin; import org.teiid.query.processor.relational.RelationalPlan; import org.teiid.query.resolver.QueryResolver; import org.teiid.query.rewriter.QueryRewriter; import org.teiid.query.sql.lang.Criteria; import org.teiid.query.sql.lang.JoinType; import org.teiid.query.unittest.RealMetadataFactory; import org.teiid.query.util.CommandContext; @SuppressWarnings("nls") public class TestCalculateCostUtil { // ===================================================================== // HELPERS // ===================================================================== private static Criteria helpGetCriteria(String critString, QueryMetadataInterface metadata) throws QueryMetadataException, TeiidComponentException, TeiidProcessingException{ Criteria result = QueryParser.getQueryParser().parseCriteria(critString); QueryResolver.resolveCriteria(result, metadata); result = QueryRewriter.rewriteCriteria(result, new CommandContext(), metadata); return result; } private static PlanNode helpGetJoinNode(float childCost1, float childCost2, JoinType joinType){ PlanNode joinNode = NodeFactory.getNewNode(NodeConstants.Types.JOIN); PlanNode child1 = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); PlanNode child2 = NodeFactory.getNewNode(NodeConstants.Types.ACCESS); joinNode.addLastChild(child1); joinNode.addLastChild(child2); child1.setProperty(NodeConstants.Info.EST_CARDINALITY, new Float(childCost1)); child2.setProperty(NodeConstants.Info.EST_CARDINALITY, new Float(childCost2)); joinNode.setProperty(NodeConstants.Info.JOIN_TYPE, joinType); return joinNode; } void helpTestEstimateCost(String critString, float childCost, float expectedResult, QueryMetadataInterface metadata) throws Exception { Criteria crit = helpGetCriteria(critString, metadata); PlanNode select = RelationalPlanner.createSelectNode(crit, false); float resultCost = NewCalculateCostUtil.recursiveEstimateCostOfCriteria(childCost, select, crit, metadata); assertEquals((int)expectedResult, (int)resultCost); } // ===================================================================== // TESTS // ===================================================================== @Test public void testEstimateCostOfCriteria() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 = '3' or pm2.g3.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } @Test public void testEstimateCostOfCompareCriteria() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 = '3'"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } @Test public void testEstimateCostOfCompareCriteria1() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 < '3'"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * usesKey = false * NOT = false */ @Test public void testEstimateCostOfMatchCriteria1() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 LIKE '#%'"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 100, metadata); } /** * usesKey = false * NOT = true */ @Test public void testEstimateCostOfMatchCriteria2() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 NOT LIKE '#_'"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 241, metadata); } /** * usesKey = true * NOT = false */ @Test public void testEstimateCostOfMatchCriteria3() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 LIKE '#_'"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 50, metadata); } /** * usesKey = true * NOT = true */ @Test public void testEstimateCostOfMatchCriteria4() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 NOT LIKE '#_'"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 249, metadata); } /** * usesKey = false * NOT = false */ @Test public void testEstimateCostOfIsNullCriteria1() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 IS NULL"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 35, metadata); } /** * usesKey = false * NOT = true */ @Test public void testEstimateCostOfIsNullCriteria2() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 IS NOT NULL"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 264, metadata); } /** * usesKey = true * NOT = false */ @Test public void testEstimateCostOfIsNullCriteria3() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 IS NULL"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 1, metadata); } /** * usesKey = true * NOT = true */ @Test public void testEstimateCostOfIsNullCriteria4() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 IS NOT NULL"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 300, metadata); } /** * usesKey = false * known child cost = false * NOT = false */ @Test public void testEstimateCostOfSetCriteria1() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * usesKey = false * known child cost = false * NOT = true */ @Test public void testEstimateCostOfSetCriteria2() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 NOT IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * usesKey = false * known child cost = true * NOT = false */ @Test public void testEstimateCostOfSetCriteria3() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 33, metadata); } /** * usesKey = false * known child cost = true * NOT = true */ @Test public void testEstimateCostOfSetCriteria4() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 NOT IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, 300, 266, metadata); } /** * usesKey = true * known child cost = false * NOT = false */ @Test public void testEstimateCostOfSetCriteria5() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 2, metadata); } /** * usesKey = true * known child cost = false * NOT = true */ @Test public void testEstimateCostOfSetCriteria6() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 NOT IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * usesKey = true * known child cost = true * NOT = false */ @Test public void testEstimateCostOfSetCriteria7() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, 200, 2, metadata); } /** * usesKey = true * known child cost = true * NOT = true */ @Test public void testEstimateCostOfSetCriteria8() throws Exception{ QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm1.g1.e1 NOT IN ('2', '3')"; //$NON-NLS-1$ helpTestEstimateCost(critString, 200, 198, metadata); } @Test public void testEstimateJoinNodeCost() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); PlanNode joinNode = helpGetJoinNode(NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, JoinType.JOIN_CROSS); float cost = NewCalculateCostUtil.computeCostForTree(joinNode, metadata); assertTrue(cost == NewCalculateCostUtil.UNKNOWN_VALUE); } @Ignore("this logic needs to be refined to work better") @Test public void testEstimateJoinNodeCostOneUnknown() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); PlanNode joinNode = helpGetJoinNode(NewCalculateCostUtil.UNKNOWN_VALUE, 500, JoinType.JOIN_INNER); joinNode.setProperty(NodeConstants.Info.JOIN_CRITERIA, Arrays.asList(helpGetCriteria("pm1.g1.e1 = pm1.g2.e1", metadata))); float cost = NewCalculateCostUtil.computeCostForTree(joinNode, metadata); assertEquals(10000, cost, 0); } @Test public void testEstimateNdvPostJoin() throws Exception { String query = "SELECT account FROM US.Accounts, Europe.CustAccts, CustomerMaster.Customers where account + accid + CustomerMaster.Customers.id = 1000000"; //$NON-NLS-1$ helpTestQuery(1, query, new String[] {"SELECT g_0.accid FROM Europe.CustAccts AS g_0", "SELECT g_0.id FROM CustomerMaster.Customers AS g_0", "SELECT g_0.account FROM US.Accounts AS g_0"}); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key */ @Test public void testEstimateCostOfCriteriaCompoundKey() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 = '3' and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key, so an OR criteria cannot be * predicted to reduce the cost of the join */ @Test public void testEstimateCostOfCriteriaCompoundKey2() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 = '3' or pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the NOT */ @Test public void testEstimateCostOfCriteriaCompoundKey3() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 = '3' and not pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the 0R */ @Test public void testEstimateCostOfCriteriaCompoundKey4() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "(pm4.g1.e1 = '3' or pm4.g1.e4 = 2.0) and not pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the OR */ @Test public void testEstimateCostOfCriteriaCompoundKey5() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "(pm4.g1.e1 = '3' or pm4.g1.e4 = 2.0) and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the OR */ @Test public void testEstimateCostOfCriteriaCompoundKey6() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "(pm4.g1.e1 = '3' and pm4.g1.e2 = 2) or pm4.g1.e4 = 2.0"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria covers that * key so the cost should be low */ @Test public void testEstimateCostOfCriteriaCompoundKey8() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 LIKE '3%' and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the NOT */ @Test public void testEstimateCostOfCriteriaCompoundKey9() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 NOT LIKE '3%' and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria covers that * key so the cost should be low */ @Test public void testEstimateCostOfCriteriaCompoundKey10() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "'3' LIKE pm4.g1.e1 and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria covers that * key so the cost should be low */ @Test public void testEstimateCostOfCriteriaCompoundKey11() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 IS NULL and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the NOT */ @Test public void testEstimateCostOfCriteriaCompoundKey12() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 IS NOT NULL and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria covers that * key so the cost should be low */ @Test public void testEstimateCostOfCriteriaCompoundKey13() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 IN ('3', '4') and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } /** * cases 2159 and 2160, defect 14998 * * e1 and e2 make up a single compound key - this criteria does not * lower the cost due to the NOT */ @Test public void testEstimateCostOfCriteriaCompoundKey14() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 NOT IN ('3', '4') and pm4.g1.e2 = 2"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } @Test public void testEstimateCostOfCriteriaCompoundKey15() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "(pm4.g1.e1 = '3' or pm4.g1.e1 = '2') and (pm4.g1.e2 = 2 or pm4.g1.e2 = 1)"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, 1, metadata); } /** * usesKey true */ @Test public void testEstimateCostOfCriteriaMultiGroup() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 = pm1.g1.e1"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * usesKey false */ @Test public void testEstimateCostOfCriteriaMultiGroup1() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 = pm4.g1.e1"; //$NON-NLS-1$ helpTestEstimateCost(critString, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, metadata); } /** * usesKey true */ @Test public void testEstimateCostOfCriteriaMultiGroup2() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm4.g1.e1 = pm1.g1.e1"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 8, metadata); } /** * usesKey false */ @Test public void testEstimateCostOfCriteriaMultiGroup3() throws Exception { QueryMetadataInterface metadata = RealMetadataFactory.example4(); String critString = "pm2.g3.e1 = pm4.g1.e1"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 10, metadata); } /** * Date Criteria - Case using valid max and min date strings. In the case of date, * the valid strings are timestamp format - since that is what our costing sets them as. */ @Test public void testEstimateCostOfCriteriaDate1() throws Exception { TransformationMetadata metadata = RealMetadataFactory.example1(); Column e2 = metadata.getElementID("pm3.g1.e2"); //$NON-NLS-1$ e2.setMinimumValue("2007-04-03 12:12:12.10"); //$NON-NLS-1$ e2.setMaximumValue("2007-06-03 12:12:12.10"); //$NON-NLS-1$ String critString = "pm3.g1.e2 <= {d'2008-04-03'}"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 100, metadata); } /** * Date Criteria - Case using invalid max and min date strings. In the case of date, * one example of invalid strings is date format - since our costing sets them to timestamp. */ @Test public void testEstimateCostOfCriteriaDate2() throws Exception { TransformationMetadata metadata = RealMetadataFactory.example1(); Column e2 = metadata.getElementID("pm3.g1.e2"); //$NON-NLS-1$ e2.setMinimumValue("2007-04-03"); //$NON-NLS-1$ e2.setMaximumValue("2007-06-03"); //$NON-NLS-1$ String critString = "pm3.g1.e2 <= {d'2008-04-03'}"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 33, metadata); } /** * Time Criteria - case using valid max and min time strings. */ @Test public void testEstimateCostOfCriteriaTime1() throws Exception { TransformationMetadata metadata = RealMetadataFactory.example1(); Column e3 = metadata.getElementID("pm3.g1.e3"); //$NON-NLS-1$ e3.setMinimumValue("12:12:12"); //$NON-NLS-1$ e3.setMaximumValue("12:13:14"); //$NON-NLS-1$ String critString = "pm3.g1.e3 <= {t'11:11:11'}"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 1, metadata); } /** * Time Criteria - case using invalid max and min time strings */ @Test public void testEstimateCostOfCriteriaTime2() throws Exception { TransformationMetadata metadata = RealMetadataFactory.example1(); Column e3 = metadata.getElementID("pm3.g1.e3"); //$NON-NLS-1$ e3.setMinimumValue("2007-04-03 12:12:12.10"); //$NON-NLS-1$ e3.setMaximumValue("2007-06-03 12:12:12.10"); //$NON-NLS-1$ String critString = "pm3.g1.e3 <= {t'11:11:11'}"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 33, metadata); } /** * Timestamp Criteria - case using valid max and min timestamp strings */ @Test public void testEstimateCostOfCriteriaTimestamp1() throws Exception { TransformationMetadata metadata = RealMetadataFactory.example1(); Column e4 = metadata.getElementID("pm3.g1.e4"); //$NON-NLS-1$ e4.setMinimumValue("2007-04-03 12:12:12.10"); //$NON-NLS-1$ e4.setMaximumValue("2007-04-03 12:12:12.10"); //$NON-NLS-1$ String critString = "pm3.g1.e4 <= {ts'2007-04-03 12:12:12.10'}"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 1, metadata); } /** * Timestamp Criteria - case using invalid max and min timestamp strings */ @Test public void testEstimateCostOfCriteriaTimestamp2() throws Exception { TransformationMetadata metadata = RealMetadataFactory.example1(); Column e4 = metadata.getElementID("pm3.g1.e4"); //$NON-NLS-1$ e4.setMinimumValue("2007-04-03"); //$NON-NLS-1$ e4.setMaximumValue("2007-06-03"); //$NON-NLS-1$ String critString = "pm3.g1.e4 <= {ts'2007-04-03 12:12:12.10'}"; //$NON-NLS-1$ helpTestEstimateCost(critString, 100, 33, metadata); } @Test public void testNDVEstimate() throws Exception { String crit = "US.accounts.account = 10"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 800, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testNDVEstimate1() throws Exception { String crit = "US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 894, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate() throws Exception { String crit = "US.accounts.account = 10 and US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 757, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate1() throws Exception { String crit = "US.accounts.account = 10 or US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1000, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testNNVEstimate() throws Exception { String crit = "US.accounts.account is null"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testNNVEstimate1() throws Exception { String crit = "US.accounts.account is null"; //$NON-NLS-1$ helpTestEstimateCost(crit, NewCalculateCostUtil.UNKNOWN_VALUE, 1, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate2() throws Exception { String crit = "US.accounts.account is null and US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate3() throws Exception { String crit = "US.accounts.account is null or US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 895, TestVirtualDepJoin.exampleVirtualDepJoin()); } //ensures that the ordering of criteria does not effect the costing calculation @Test public void testCompoundCriteriaEstimate4() throws Exception { String crit = "US.accounts.account = 10 and US.accounts.account = US.accounts.customer and US.accounts.customer < 100"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 87, TestVirtualDepJoin.exampleVirtualDepJoin()); String crit1 = "US.accounts.account = US.accounts.customer and US.accounts.customer < 100 and US.accounts.account = 10"; //$NON-NLS-1$ helpTestEstimateCost(crit1, 1000, 85, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate5() throws Exception { String crit = "US.accounts.account is null and US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, NewCalculateCostUtil.UNKNOWN_VALUE, 1, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate6() throws Exception { String crit = "US.accounts.account is null or US.accounts.account = US.accounts.customer"; //$NON-NLS-1$ helpTestEstimateCost(crit, NewCalculateCostUtil.UNKNOWN_VALUE, NewCalculateCostUtil.UNKNOWN_VALUE, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testCompoundCriteriaEstimate7() throws Exception { String critString = "US.accounts.account = 10"; //$NON-NLS-1$ helpTestEstimateCost(critString, 1000, 800, TestVirtualDepJoin.exampleVirtualDepJoin()); critString = "US.accounts.customer < 100"; //$NON-NLS-1$ helpTestEstimateCost(critString, 800, 80, TestVirtualDepJoin.exampleVirtualDepJoin()); String crit = "US.accounts.account = 10 and US.accounts.customer < 100"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 90, TestVirtualDepJoin.exampleVirtualDepJoin()); } //min and max are not set, so the default estimate is returned @Test public void testRangeEstimate() throws Exception { String crit = "US.accounts.account < 100"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 333, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate1() throws Exception { String crit = "US.accounts.customer < 100"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 100, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate2() throws Exception { String crit = "US.accounts.customer > 100"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 900, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate3() throws Exception { String crit = "US.accounts.customer >= 1600"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate4() throws Exception { String crit = "US.accounts.customer < -1"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate5() throws Exception { String crit = "US.accounts.customer >= -1"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1000, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate6() throws Exception { String crit = "US.accounts.pennies >= -2"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 1000, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testRangeEstimate7() throws Exception { String crit = "US.accounts.pennies >= -6"; //$NON-NLS-1$ helpTestEstimateCost(crit, 1000, 800, TestVirtualDepJoin.exampleVirtualDepJoin()); } @Test public void testLimitWithUnknownChildCardinality() throws Exception { String query = "select e1 from pm1.g1 limit 2"; //$NON-NLS-1$ RelationalPlan plan = (RelationalPlan)TestOptimizer.helpPlan(query, RealMetadataFactory.example1Cached(), new String[] {"SELECT e1 FROM pm1.g1"}); //$NON-NLS-1$ assertEquals(new Float(2), plan.getRootNode().getEstimateNodeCardinality()); } public void helpTestSetOp(String op, float cost) throws Exception { String query = "SELECT customer as customer_id, convert(account, long) as account_id, convert(txnid, long) as transaction_id, case txn when 'DEP' then 1 when 'TFR' then 2 when 'WD' then 3 else -1 end as txn_type, (pennies + convert('0.00', bigdecimal)) / 100 as amount, 'US' as source FROM US.Accounts where txn != 'X'" + //$NON-NLS-1$ op + "SELECT id, convert(accid / 10000, long), mod(accid, 10000), convert(type, integer), amount, 'EU' from Europe.CustAccts"; //$NON-NLS-1$ String[] expected = new String[] {"SELECT g_0.customer, g_0.account, g_0.txnid, g_0.txn, g_0.pennies FROM US.Accounts AS g_0 WHERE g_0.txn <> 'X'", "SELECT g_0.id, g_0.accid, g_0.type, g_0.amount FROM Europe.CustAccts AS g_0"}; helpTestQuery(cost, query, expected); } private void helpTestQuery(float cost, String query, String[] expected) throws TeiidComponentException, TeiidProcessingException { RelationalPlan plan = (RelationalPlan)TestOptimizer.helpPlan(query, TestVirtualDepJoin.exampleVirtualDepJoin(), expected, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$ assertEquals(cost, plan.getRootNode().getEstimateNodeCardinality()); } @Test public void testUnion() throws Exception { helpTestSetOp("UNION ", 1375000.0f); //$NON-NLS-1$ } @Test public void testUnionALL() throws Exception { helpTestSetOp("UNION ALL ", 1750000.0f); //$NON-NLS-1$ } @Test public void testExcept() throws Exception { helpTestSetOp("EXCEPT ", 250000.0f); //$NON-NLS-1$ } @Test public void testIntersect() throws Exception { helpTestSetOp("INTERSECT ", 375000.0f); //$NON-NLS-1$ } }