blob: de173b8c75f4528df75c8024f6877dcd49bed3ef [file] [log] [blame]
package org.apache.hawq.pxf.plugins.jdbc;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hawq.pxf.api.*;
import org.apache.hawq.pxf.api.utilities.ColumnDescriptor;
import org.apache.hawq.pxf.api.utilities.InputData;
import org.apache.hawq.pxf.api.io.DataType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Validate SQL string generated by the {@link JdbcPartitionFragmenter#buildFragmenterSql} method
* and the {@link WhereSQLBuilder#buildWhereSQL} method.
*/
public class SqlBuilderTest {
private static final Log LOG = LogFactory.getLog(SqlBuilderTest.class);
static final String DB_PRODUCT = "mysql";
static final String ORIGINAL_SQL = "select * from sales";
InputData inputData;
@Before
public void setup() throws Exception {
LOG.info("SqlBuilderTest.setup()");
}
@After
public void cleanup() throws Exception {
LOG.info("SqlBuilderTest.cleanup()");
}
@Test
public void testIdFilter() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(true);
// id = 1
when(inputData.getFilterString()).thenReturn("a0c20s1d1o5");
WhereSQLBuilder builder = new WhereSQLBuilder(inputData);
StringBuilder sb = new StringBuilder();
builder.buildWhereSQL(DB_PRODUCT, sb);
assertEquals(" WHERE id = 1", sb.toString());
}
@Test
public void testDateAndAmtFilter() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(true);
// cdate > '2008-02-01' and cdate < '2008-12-01' and amt > 1200
when(inputData.getFilterString()).thenReturn("a1c25s10d2008-02-01o2a1c25s10d2008-12-01o1l0a2c20s4d1200o2l0");
WhereSQLBuilder builder = new WhereSQLBuilder(inputData);
StringBuilder sb = new StringBuilder();
builder.buildWhereSQL(DB_PRODUCT, sb);
assertEquals(" WHERE cdate > DATE('2008-02-01') AND cdate < DATE('2008-12-01') AND amt > 1200"
, sb.toString());
}
@Test
public void testUnsupportedOperationFilter() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(true);
// IN 'bad'
when(inputData.getFilterString()).thenReturn("a3c25s3dbado10");
WhereSQLBuilder builder = new WhereSQLBuilder(inputData);
StringBuilder sb = new StringBuilder();
builder.buildWhereSQL(DB_PRODUCT, sb);
assertEquals("", sb.toString());
}
@Test
public void testUnsupportedLogicalFilter() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(true);
// cdate > '2008-02-01' or amt < 1200
when(inputData.getFilterString()).thenReturn("a1c25s10d2008-02-01o2a2c20s4d1200o2l1");
WhereSQLBuilder builder = new WhereSQLBuilder(inputData);
StringBuilder sb = new StringBuilder();
builder.buildWhereSQL(DB_PRODUCT, sb);
assertEquals("", sb.toString());
}
@Test
public void testDatePartition() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(false);
when(inputData.getUserProperty("PARTITION_BY")).thenReturn("cdate:date");
when(inputData.getUserProperty("RANGE")).thenReturn("2008-01-01:2009-01-01");
when(inputData.getUserProperty("INTERVAL")).thenReturn("2:month");
JdbcPartitionFragmenter fragment = new JdbcPartitionFragmenter(inputData);
List<Fragment> fragments = fragment.getFragments();
assertEquals(6, fragments.size());
// Partition: cdate >= 2008-01-01 and cdate < 2008-03-01
when(inputData.getFragmentMetadata()).thenReturn(fragments.get(0).getMetadata());
StringBuilder sb = new StringBuilder(ORIGINAL_SQL);
JdbcPartitionFragmenter.buildFragmenterSql(inputData, DB_PRODUCT, sb);
assertEquals(ORIGINAL_SQL + " WHERE cdate >= DATE('2008-01-01') AND cdate < DATE('2008-03-01')", sb.toString());
}
@Test
public void testFilterAndPartition() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(true);
when(inputData.getFilterString()).thenReturn("a0c20s1d5o2"); //id>5
when(inputData.getUserProperty("PARTITION_BY")).thenReturn("grade:enum");
when(inputData.getUserProperty("RANGE")).thenReturn("excellent:good:general:bad");
StringBuilder sb = new StringBuilder(ORIGINAL_SQL);
WhereSQLBuilder builder = new WhereSQLBuilder(inputData);
builder.buildWhereSQL(DB_PRODUCT, sb);
assertEquals(ORIGINAL_SQL + " WHERE id > 5", sb.toString());
JdbcPartitionFragmenter fragment = new JdbcPartitionFragmenter(inputData);
List<Fragment> fragments = fragment.getFragments();
// Partition: id > 5 and grade = 'excellent'
when(inputData.getFragmentMetadata()).thenReturn(fragments.get(0).getMetadata());
JdbcPartitionFragmenter.buildFragmenterSql(inputData, DB_PRODUCT, sb);
assertEquals(ORIGINAL_SQL + " WHERE id > 5 AND grade = 'excellent'", sb.toString());
}
@Test
public void testNoPartition() throws Exception {
prepareConstruction();
when(inputData.hasFilter()).thenReturn(false);
JdbcPartitionFragmenter fragment = new JdbcPartitionFragmenter(inputData);
List<Fragment> fragments = fragment.getFragments();
assertEquals(1, fragments.size());
when(inputData.getFragmentMetadata()).thenReturn(fragments.get(0).getMetadata());
StringBuilder sb = new StringBuilder(ORIGINAL_SQL);
JdbcPartitionFragmenter.buildFragmenterSql(inputData, DB_PRODUCT, sb);
assertEquals(ORIGINAL_SQL, sb.toString());
}
private void prepareConstruction() throws Exception {
inputData = mock(InputData.class);
when(inputData.getDataSource()).thenReturn("sales");
ArrayList<ColumnDescriptor> columns = new ArrayList<>();
columns.add(new ColumnDescriptor("id", DataType.INTEGER.getOID(), 0, "int4", null));
columns.add(new ColumnDescriptor("cdate", DataType.DATE.getOID(), 1, "date", null));
columns.add(new ColumnDescriptor("amt", DataType.FLOAT8.getOID(), 2, "float8", null));
columns.add(new ColumnDescriptor("grade", DataType.TEXT.getOID(), 3, "text", null));
when(inputData.getTupleDescription()).thenReturn(columns);
when(inputData.getColumn(0)).thenReturn(columns.get(0));
when(inputData.getColumn(1)).thenReturn(columns.get(1));
when(inputData.getColumn(2)).thenReturn(columns.get(2));
when(inputData.getColumn(3)).thenReturn(columns.get(3));
}
}