package org.teiid.translator.prestodb; import static org.junit.Assert.*; import java.io.FileNotFoundException; import java.io.FileReader; import java.sql.Timestamp; import java.util.Arrays; import java.util.TimeZone; import org.junit.BeforeClass; import org.junit.Test; import org.teiid.adminapi.impl.ModelMetaData; import org.teiid.cdk.api.TranslationUtility; import org.teiid.core.CoreConstants; import org.teiid.core.util.TimestampWithTimezone; import org.teiid.core.util.UnitTestUtil; import org.teiid.language.Command; import org.teiid.language.Function; import org.teiid.language.LanguageFactory; import org.teiid.language.Literal; import org.teiid.metadata.MetadataException; import org.teiid.metadata.MetadataFactory; import org.teiid.query.metadata.MetadataValidator; import org.teiid.query.metadata.SystemMetadata; import org.teiid.query.metadata.TransformationMetadata; import org.teiid.query.parser.QueryParser; import org.teiid.query.unittest.RealMetadataFactory; import org.teiid.query.unittest.TimestampUtil; import org.teiid.query.validator.ValidatorReport; import org.teiid.translator.SourceSystemFunctions; import org.teiid.translator.TranslatorException; import org.teiid.translator.jdbc.SQLConversionVisitor; @SuppressWarnings("nls") public class TestSQLConversionVisitor { private static final LanguageFactory LANG_FACTORY = new LanguageFactory(); private static PrestoDBExecutionFactory TRANSLATOR; private static TranslationUtility translationUtility = new TranslationUtility(queryMetadataInterface()); @BeforeClass public static void init() throws TranslatorException { TRANSLATOR = new PrestoDBExecutionFactory(); TRANSLATOR.start(); translationUtility.addUDF(CoreConstants.SYSTEM_MODEL, TRANSLATOR.getPushDownFunctions()); } private static TransformationMetadata queryMetadataInterface() { try { ModelMetaData mmd = new ModelMetaData(); mmd.setName("prestodbModel"); MetadataFactory mf = new MetadataFactory("prestodb", 1, SystemMetadata.getInstance().getRuntimeTypeMap(), mmd); mf.setParser(new QueryParser()); mf.parse(new FileReader(UnitTestUtil.getTestDataFile("sample.ddl"))); TransformationMetadata tm = RealMetadataFactory.createTransformationMetadata(mf.asMetadataStore(), "x"); ValidatorReport report = new MetadataValidator().validate(tm.getVdbMetaData(), tm.getMetadataStore()); if (report.hasItems()) { throw new RuntimeException(report.getFailureMessage()); } return tm; } catch (MetadataException | FileNotFoundException e) { throw new RuntimeException(e); } } private void helpTest(String sql, String expected) throws TranslatorException { Command command = translationUtility.parseCommand(sql); SQLConversionVisitor vistor = TRANSLATOR.getSQLConversionVisitor(); vistor.append(command); // System.out.println(vistor.toString()); assertEquals(expected, vistor.toString()); } private void helpTestMod(Literal c, String format, String expectedStr) throws Exception { Function func = LANG_FACTORY.createFunction(format, Arrays.asList(c), String.class); PrestoDBExecutionFactory ef= new PrestoDBExecutionFactory(); ef.start(); SQLConversionVisitor sqlVisitor = ef.getSQLConversionVisitor(); sqlVisitor.append(func); assertEquals(expectedStr, sqlVisitor.toString()); } @Test public void testDayOfMonth() throws Exception { Literal arg1 = LANG_FACTORY.createLiteral(TimestampUtil.createTimestamp(117, 0, 13, 10, 5, 0, 10000000), Timestamp.class); helpTestMod(arg1, SourceSystemFunctions.DAYOFMONTH, "day_of_month(timestamp '2017-01-13 10:05:00.01')"); //$NON-NLS-1$ } @Test public void testDayOfWeek() throws Exception { Literal arg1 = LANG_FACTORY.createLiteral(TimestampUtil.createTimestamp(117, 0, 13, 10, 5, 0, 10000000), Timestamp.class); helpTestMod(arg1, SourceSystemFunctions.DAYOFWEEK, "day_of_week(timestamp '2017-01-13 10:05:00.01')"); //$NON-NLS-1$ } @Test public void testDayOfYear() throws Exception { Literal arg1 = LANG_FACTORY.createLiteral(TimestampUtil.createTimestamp(117, 0, 13, 10, 5, 0, 10000000), Timestamp.class); helpTestMod(arg1, SourceSystemFunctions.DAYOFYEAR, "day_of_year(timestamp '2017-01-13 10:05:00.01')"); //$NON-NLS-1$ } @Test public void testDateTimeLiterals() throws Exception { TimestampWithTimezone.resetCalendar(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$ try { String sql = "SELECT intkey FROM prestodbModel.smalla WHERE datevalue = cast('2017-01-13' as date)"; //$NON-NLS-1$ String expected = "SELECT smalla.intKey FROM smalla WHERE smalla.dateValue = date '2017-01-13'"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT intkey FROM prestodbModel.smalla WHERE smalla.timeValue = cast('15:50:02' as time)"; //$NON-NLS-1$ expected = "SELECT smalla.intKey FROM smalla WHERE smalla.timeValue = time '15:50:02'"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT intkey FROM prestodbModel.smalla WHERE smalla.timestampValue = cast('2017-01-13 15:50:02.0' as timestamp)"; //$NON-NLS-1$ expected = "SELECT smalla.intKey FROM smalla WHERE smalla.timestampValue = timestamp '2017-01-13 15:50:02.0'"; //$NON-NLS-1$ helpTest(sql, expected); } finally { TimestampWithTimezone.resetCalendar(null); } } @Test public void testFormatDateTime() throws TranslatorException { String sql = "SELECT FORMATDATE(datevalue, 'MM-dd-yy') FROM prestodbModel.smalla"; //$NON-NLS-1$ String expected = "SELECT format_datetime(cast(smalla.dateValue AS timestamp), 'MM-dd-yy') FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT FORMATTIME(timeValue, 'HH:MI:SS') FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT format_datetime(cast(smalla.timeValue AS timestamp), 'HH:MI:SS') FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT FORMATTIMESTAMP(timestampValue, 'YYYY-MM-DD HH:MI:SS') FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT format_datetime(smalla.timestampValue, 'YYYY-MM-DD HH:MI:SS') FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); } @Test public void testConvertCast() throws TranslatorException { String sql = "SELECT convert(stringnum, integer) FROM prestodbModel.smalla"; //$NON-NLS-1$ String expected = "SELECT cast(smalla.stringnum AS integer) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT booleanValue, (booleanValue + 1) AS BooleanValuePlus2 FROM prestodbModel.SmallA"; //$NON-NLS-1$ expected = "SELECT smalla.booleanValue, (cast(smalla.booleanValue AS integer) + 1) AS BooleanValuePlus2 FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT convert(dateValue, timestamp) FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT cast(smalla.dateValue AS timestamp) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); sql = "SELECT convert(timeValue, timestamp) FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT cast(smalla.timeValue AS timestamp) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); } @Test public void testLogarithmFunctions() throws TranslatorException { // natural logarithm String sql = "SELECT log(doublenum) FROM prestodbModel.smalla"; //$NON-NLS-1$ String expected = "SELECT ln(smalla.doublenum) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); // base 10 logarithm sql = "SELECT log10(doublenum) FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT log10(smalla.doublenum) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); // base 2 logarithm sql = "SELECT prestodb.log2(doublenum) FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT log2(smalla.doublenum) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); // base b logarithm sql = "SELECT prestodb.log(doublenum, 2) FROM prestodbModel.smalla"; //$NON-NLS-1$ expected = "SELECT log(smalla.doublenum, 2) FROM smalla"; //$NON-NLS-1$ helpTest(sql, expected); } @Test public void testCorelatedSubquery() throws TranslatorException { String sql = "SELECT intkey, bytenum, (SELECT bytenum FROM prestodbModel.smalla AS b WHERE (bytenum = a.longnum) AND (intkey = '10')) AS longnum FROM prestodbModel.smalla AS a"; //$NON-NLS-1$ String expected = "SELECT a.intKey, a.bytenum, (SELECT b.bytenum FROM smalla AS b WHERE cast(b.bytenum AS bigint) = a.longnum AND b.intKey = '10' LIMIT 2) AS longnum FROM smalla AS a"; //$NON-NLS-1$ helpTest(sql, expected); } }