/* * 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.sql.util; import static org.junit.Assert.*; import org.junit.Test; import org.teiid.api.exception.query.QueryMetadataException; import org.teiid.api.exception.query.QueryParserException; import org.teiid.api.exception.query.QueryResolverException; import org.teiid.core.TeiidComponentException; import org.teiid.query.metadata.BasicQueryMetadataWrapper; import org.teiid.query.metadata.QueryMetadataInterface; import org.teiid.query.parser.QueryParser; import org.teiid.query.resolver.QueryResolver; import org.teiid.query.resolver.util.ResolverUtil; import org.teiid.query.sql.lang.Command; import org.teiid.query.unittest.RealMetadataFactory; @SuppressWarnings("nls") public class TestElementSymbolOptimizer { public Command helpResolve(String sql, QueryMetadataInterface metadata) throws QueryParserException, QueryResolverException, TeiidComponentException { Command command = QueryParser.getQueryParser().parseCommand(sql); QueryResolver.resolveCommand(command, metadata); return command; } public void helpTestOptimize(String sql, QueryMetadataInterface metadata, String expected) throws QueryMetadataException, TeiidComponentException, QueryParserException, QueryResolverException { Command command = helpResolve(sql, new BasicQueryMetadataWrapper(metadata){ @Override public boolean findShortName() { return true; } }); String actual = command.toString(); assertEquals("Expected different optimized string", expected, actual); //$NON-NLS-1$ } /** Can be optimized */ @Test public void testOptimize1() throws Exception { helpTestOptimize("SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT e1, e2 FROM pm1.g1"); //$NON-NLS-1$ } /** Can't be optimized */ @Test public void testOptimize2() throws Exception { helpTestOptimize("SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1, pm1.g2", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1, pm1.g2"); //$NON-NLS-1$ } @Test public void testOptimize3() throws Exception { helpTestOptimize("UPDATE pm1.g1 SET pm1.g1.e1 = 'e' WHERE pm1.g1.e2 = 3", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "UPDATE pm1.g1 SET e1 = 'e' WHERE e2 = 3"); //$NON-NLS-1$ } @Test public void testOptimize4() throws Exception { helpTestOptimize("INSERT INTO pm1.g1 (pm1.g1.e1, pm1.g1.e2) VALUES ('e', 3)", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "INSERT INTO pm1.g1 (e1, e2) VALUES ('e', 3)"); //$NON-NLS-1$ } @Test public void testOptimize5() throws Exception { helpTestOptimize("DELETE FROM pm1.g1 WHERE pm1.g1.e2 = 3", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "DELETE FROM pm1.g1 WHERE e2 = 3"); //$NON-NLS-1$ } @Test public void testOptimize6() throws Exception { helpTestOptimize("SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1 WHERE e2 > (SELECT AVG(pm1.g2.e2) FROM pm1.g2 WHERE pm1.g1.e1 = pm1.g2.e1)", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT e1, e2 FROM pm1.g1 WHERE e2 > (SELECT AVG(e2) FROM pm1.g2 WHERE pm1.g1.e1 = e1)"); //$NON-NLS-1$ } /** alias */ @Test public void testOptimize7() throws Exception { helpTestOptimize("SELECT 'text' AS zz, pm1.g1.e2 FROM pm1.g1", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT 'text' AS zz, e2 FROM pm1.g1"); //$NON-NLS-1$ } @Test public void testOptimize8() throws Exception { helpTestOptimize("SELECT 1, 'xyz'", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT 1, 'xyz'"); //$NON-NLS-1$ } public void helpTestFullyQualify(String sql, QueryMetadataInterface metadata, String expected) throws QueryParserException, QueryResolverException, TeiidComponentException { Command command = helpResolve(sql, metadata); ResolverUtil.fullyQualifyElements(command); String actual = command.toString(); assertEquals("Expected different fully qualified string", expected, actual); //$NON-NLS-1$ } @Test public void testFullyQualify1() throws Exception { helpTestFullyQualify("SELECT e1, e2 FROM pm1.g1", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1"); //$NON-NLS-1$ } @Test public void testXMLQuery() throws Exception { helpTestOptimize("SELECT root.node1.node2.node3 FROM xmltest.doc1", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT root.node1.node2.node3 FROM xmltest.doc1"); //$NON-NLS-1$ } @Test public void testVirtualStoredProcedure() throws Exception { helpTestOptimize("EXEC pm1.vsp7(5)", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "EXEC pm1.vsp7(5)"); //$NON-NLS-1$ } @Test public void testStoredQuerySubquery() throws Exception { helpTestOptimize("select x.e1 from (EXEC pm1.sq1()) as x", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT e1 FROM (EXEC pm1.sq1()) AS x"); //$NON-NLS-1$ } @Test public void testStoredQuerySubquery2() throws Exception { helpTestOptimize("select x.e1 from (EXEC pm1.sq1()) as x WHERE x.e2 = 3", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT e1 FROM (EXEC pm1.sq1()) AS x WHERE e2 = 3"); //$NON-NLS-1$ } @Test public void testOptimizeOrderBy() throws Exception { helpTestOptimize("SELECT pm1.g1.e1 FROM pm1.g1 order by pm1.g1.e1", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT e1 FROM pm1.g1 ORDER BY e1"); //$NON-NLS-1$ } /** * It is by design that order by optimization only works in one direction. It is not desirable to * fully qualify order by elements */ @Test public void testOptimizeOrderBy1() throws Exception { helpTestFullyQualify("SELECT e1 FROM pm1.g1 order by e1", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT pm1.g1.e1 FROM pm1.g1 ORDER BY e1"); //$NON-NLS-1$ } @Test public void testOptimizeOrderByWithoutGroup() throws Exception { helpTestOptimize("SELECT pm1.g1.e1, count(*) as x FROM pm1.g1 order by x", //$NON-NLS-1$ RealMetadataFactory.example1Cached(), "SELECT e1, COUNT(*) AS x FROM pm1.g1 ORDER BY x"); //$NON-NLS-1$ } @Test public void testOutputNames() throws Exception { String sql = "select PM1.g1.e1, e2 FROM Pm1.G1"; Command command = QueryParser.getQueryParser().parseCommand(sql); QueryMetadataInterface metadata = new BasicQueryMetadataWrapper(RealMetadataFactory.example1Cached()){ public boolean useOutputName() { return false; }; }; QueryResolver.resolveCommand(command, metadata); assertEquals("SELECT pm1.g1.e1, pm1.g1.e2 FROM pm1.g1", command.toString()); } }