/** * 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. */ package org.apache.drill.exec.store.ischema; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.apache.drill.PlanTestBase; import org.junit.Test; public class TestInfoSchemaFilterPushDown extends PlanTestBase { @Test public void testFilterPushdown_Equal() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_SCHEMA='INFORMATION_SCHEMA'"; final String scan = "Scan(groupscan=[TABLES, filter=equal(Field=TABLE_SCHEMA,Literal=INFORMATION_SCHEMA)])"; testHelper(query, scan, false); } @Test public void testFilterPushdown_NonEqual() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_SCHEMA <> 'INFORMATION_SCHEMA'"; final String scan = "Scan(groupscan=[TABLES, filter=not_equal(Field=TABLE_SCHEMA,Literal=INFORMATION_SCHEMA)])"; testHelper(query, scan, false); } @Test public void testFilterPushdown_Like() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_SCHEMA LIKE '%SCH%'"; final String scan = "Scan(groupscan=[TABLES, filter=like(Field=TABLE_SCHEMA,Literal=%SCH%)])"; testHelper(query, scan, false); } @Test public void testFilterPushdown_LikeWithEscape() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.`TABLES` WHERE TABLE_SCHEMA LIKE '%\\\\SCH%' ESCAPE '\\'"; final String scan = "Scan(groupscan=[TABLES, filter=like(Field=TABLE_SCHEMA,Literal=%\\\\SCH%,Literal=\\)])"; testHelper(query, scan, false); } @Test public void testFilterPushdown_And() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE " + "TABLE_SCHEMA = 'sys' AND " + "TABLE_NAME <> 'version'"; final String scan = "Scan(groupscan=[COLUMNS, filter=booleanand(equal(Field=TABLE_SCHEMA,Literal=sys)," + "not_equal(Field=TABLE_NAME,Literal=version))])"; testHelper(query, scan, false); } @Test public void testFilterPushdown_Or() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE " + "TABLE_SCHEMA = 'sys' OR " + "TABLE_NAME <> 'version' OR " + "TABLE_SCHEMA like '%sdfgjk%'"; final String scan = "Scan(groupscan=[COLUMNS, filter=booleanor(equal(Field=TABLE_SCHEMA,Literal=sys)," + "not_equal(Field=TABLE_NAME,Literal=version),like(Field=TABLE_SCHEMA,Literal=%sdfgjk%))])"; testHelper(query, scan, false); } @Test public void testFilterPushDownWithProject_Equal() throws Exception { final String query = "SELECT COLUMN_NAME from INFORMATION_SCHEMA.`COLUMNS` WHERE TABLE_SCHEMA = 'INFORMATION_SCHEMA'"; final String scan = "Scan(groupscan=[COLUMNS, filter=equal(Field=TABLE_SCHEMA,Literal=INFORMATION_SCHEMA)])"; testHelper(query, scan, false); } @Test public void testFilterPushDownWithProject_NotEqual() throws Exception { final String query = "SELECT COLUMN_NAME from INFORMATION_SCHEMA.`COLUMNS` WHERE TABLE_NAME <> 'TABLES'"; final String scan = "Scan(groupscan=[COLUMNS, filter=not_equal(Field=TABLE_NAME,Literal=TABLES)])"; testHelper(query, scan, false); } @Test public void testFilterPushDownWithProject_Like() throws Exception { final String query = "SELECT COLUMN_NAME from INFORMATION_SCHEMA.`COLUMNS` WHERE TABLE_NAME LIKE '%BL%'"; final String scan = "Scan(groupscan=[COLUMNS, filter=like(Field=TABLE_NAME,Literal=%BL%)])"; testHelper(query, scan, false); } @Test public void testPartialFilterPushDownWithProject() throws Exception { final String query = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE " + "TABLE_SCHEMA = 'sys' AND " + "TABLE_NAME = 'version' AND " + "COLUMN_NAME like 'commit%s' AND " + "IS_NULLABLE = 'YES'"; // this is not expected to pushdown into scan final String scan = "Scan(groupscan=[COLUMNS, " + "filter=booleanand(equal(Field=TABLE_SCHEMA,Literal=sys),equal(Field=TABLE_NAME,Literal=version)," + "like(Field=COLUMN_NAME,Literal=commit%s))]"; testHelper(query, scan, true); } private void testHelper(final String query, String filterInScan, boolean filterPrelExpected) throws Exception { final String plan = getPlanInString("EXPLAIN PLAN FOR " + query, OPTIQ_FORMAT); if (!filterPrelExpected) { // If filter prel is not expected, make sure it is not in plan assertFalse(plan.contains("Filter(")); } else { assertTrue(plan.contains("Filter(")); } // Check for filter pushed into scan. assertTrue(plan.contains(filterInScan)); // run the query test(query); } }