QueryPlannerImpl implements QueryPlanner { @Override public QueryPlan plan(String sql) throws SQLException { QueryParser queryParser = applicationContext.getBean(QueryParser.class); queryParser.parse(sql); QueryType queryType = queryParser.getQueryType(); switch (queryType) { case EXPLAIN: case SELECT: { SelectQueryAware selectQueryAware = queryParser.getSelectQueryAware(); processSelectQuery(selectQueryAware); break; } case SHOW_TABLES: { tasksQueue.add(applicationContext.getBean(ShowTablesTask.class)); break; } case UNKNOWN: throw new SQLSyntaxErrorException("Unknown query type"); } return new QueryPlanImpl(tasksQueue, queryType); }  @Override QueryPlan plan(String sql);  }
@Test public void testGroupBy() throws Exception { ColumnExpression groupByExpression = new ColumnExpression(NAME, INSTANCES); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getGroupByExpressions().add(groupByExpression); } }); List<Task> tasks = new ArrayList<>(plan()); assertThat(tasks, hasSize(3)); Task secondTask = tasks.get(1); assertThat(secondTask, is(instanceOf(GroupTask.class))); GroupTask groupTask = (GroupTask) secondTask; assertThat(groupTask.getExpressions(), contains(groupByExpression)); }
@Test public void testOrderBy() throws Exception { OrderExpression orderByExpression = new OrderExpression(new ColumnExpression(NAME, INSTANCES), OrderDirection.DESC); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getOrderByExpressions().add(orderByExpression); } }); List<Task> tasks = new ArrayList<>(plan()); assertThat(tasks, hasSize(3)); Task secondTask = tasks.get(1); assertThat(secondTask, is(instanceOf(OrderTask.class))); OrderTask orderTask = (OrderTask) secondTask; assertThat(orderTask.getExpressions(), contains(orderByExpression)); }
@Test public void testLimit() throws Exception { queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { setLimitCount(10); setLimitOffset(20); } }); List<Task> tasks = new ArrayList<>(plan()); assertThat(tasks, is(not(empty()))); Task lastTask = tasks.get(tasks.size() - 1); assertThat(lastTask, is(instanceOf(LimitTask.class))); LimitTask limitTask = (LimitTask) lastTask; assertThat(limitTask.getCount(), equalTo(10)); assertThat(limitTask.getOffset(), equalTo(20)); }
@Test public void testTableScanStrategySimpleFetch() throws Exception { DataSource leftDataSource = new DataSource(PROJECTS); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getSelectionMap().put(PROJECT_NAME, new ColumnExpression(PROJECT_NAME, PROJECTS)); setDataSource(leftDataSource); getTableAliases().put(PROJECTS, PROJECTS); } }); List<Task> tasks = new ArrayList<>(plan()); DataSourceTask dataSourceTask = doCommonTaskAssertions(tasks); DataSource optimizedLeftDataSource = doOptimizedLeftDataSourceAssertions(dataSourceTask); assertThat(optimizedLeftDataSource, equalTo(leftDataSource)); }
@Test public void testIndexScanStrategyInnerJoin() throws Exception { DataSource leftDataSource = new DataSource(INSTANCES_ALIAS); DataSource rightDataSource = new DataSource(PROJECTS_ALIAS); rightDataSource.setJoinType(INNER); BooleanExpression joinCondition = new SimpleBooleanExpression(new ColumnExpression(PROJECT_ID, INSTANCES_ALIAS), EQUAL, new ColumnExpression(ID, PROJECTS_ALIAS)); rightDataSource.setCondition(joinCondition); leftDataSource.setRightDataSource(rightDataSource); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getSelectionMap().put(NAME, new ColumnExpression(NAME, INSTANCES_ALIAS)); getSelectionMap().put(PROJECT_ID, new ColumnExpression(ID, PROJECTS_ALIAS)); setDataSource(leftDataSource); BooleanExpression whereCondition = new SimpleBooleanExpression(new ColumnExpression(NAME, INSTANCES_ALIAS), EQUAL, VALUE); setWhereExpression(whereCondition); getTableAliases().put(INSTANCES_ALIAS, INSTANCES); getTableAliases().put(PROJECTS_ALIAS, PROJECTS); } }); List<Task> tasks = new ArrayList<>(plan()); DataSourceTask dataSourceTask = doCommonTaskAssertions(tasks); DataSource optimizedLeftDataSource = doOptimizedLeftDataSourceAssertions(dataSourceTask); assertThat(optimizedLeftDataSource.getTableAlias().isPresent(), is(true)); assertThat(optimizedLeftDataSource.getTableAlias().get(), equalTo(INSTANCES_ALIAS)); assertThat(optimizedLeftDataSource.getType(), equalTo(INDEX_SCAN)); assertThat(optimizedLeftDataSource.getCondition().isPresent(), is(true)); assertThat(optimizedLeftDataSource.getColumns(), is(empty())); assertThat(optimizedLeftDataSource.getRightDataSource().isPresent(), is(true)); DataSource optimizedRightDataSource = optimizedLeftDataSource.getRightDataSource().get(); assertThat(optimizedRightDataSource.getTableAlias().isPresent(), is(true)); assertThat(optimizedRightDataSource.getTableAlias().get(), equalTo(PROJECTS_ALIAS)); assertThat(optimizedRightDataSource.getType(), equalTo(INDEX_SCAN)); assertThat(optimizedRightDataSource.getCondition().isPresent(), is(true)); assertThat(optimizedRightDataSource.getColumns(), is(empty())); BooleanExpression optimizedLeftCondition = optimizedLeftDataSource.getCondition().get(); assertThat(optimizedLeftCondition, is(instanceOf(IndexBooleanExpression.class))); assertThat(optimizedLeftCondition.getColumnRelations(), is(empty())); assertThat(optimizedLeftCondition.getRestOfExpression().isPresent(), is(false)); assertThat(optimizedLeftCondition.getFixedValueConditions(INSTANCES_ALIAS), equalTo(Collections.singletonMap(NAME, Collections.singleton(VALUE)))); BooleanExpression optimizedRightCondition = optimizedRightDataSource.getCondition().get(); assertThat(optimizedRightCondition, is(instanceOf(IndexBooleanExpression.class))); assertThat(optimizedRightCondition.getColumnRelations(), hasSize(1)); assertThat(optimizedRightCondition.getRestOfExpression().isPresent(), is(false)); ColumnRelation columnRelation = optimizedRightCondition.getColumnRelations().get(0); assertThat(columnRelation.getLeftTableAlias(), equalTo(INSTANCES_ALIAS)); assertThat(columnRelation.getLeftColumn(), equalTo(PROJECT_ID)); assertThat(columnRelation.getRightTableAlias(), equalTo(PROJECTS_ALIAS)); assertThat(columnRelation.getRightColumn(), equalTo(ID)); }
@Ignore @Test public void testIndexScanStrategyOrCondition() throws Exception { DataSource leftDataSource = new DataSource(INSTANCES_ALIAS); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getSelectionMap().put(ANY_COLUMN, new ColumnExpression()); setDataSource(leftDataSource); BooleanExpression whereCondition = new BinaryBooleanExpression( new SimpleBooleanExpression(new ColumnExpression(NAME, INSTANCES_ALIAS), EQUAL, VALUE), OR, new SimpleBooleanExpression(new ColumnExpression(ID, INSTANCES_ALIAS), EQUAL, VALUE) ); setWhereExpression(whereCondition); getTableAliases().put(INSTANCES_ALIAS, INSTANCES); } }); List<Task> tasks = new ArrayList<>(plan()); DataSourceTask dataSourceTask = doCommonTaskAssertions(tasks); DataSource optimizedLeftDataSource = doOptimizedLeftDataSourceAssertions(dataSourceTask); assertThat(optimizedLeftDataSource.getTableAlias().isPresent(), is(true)); }
@Test public void testOptimizeMultipleOrConditions() throws Exception { DataSource leftDataSource = new DataSource(PROJECTS_ALIAS); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getSelectionMap().put(PROJECT_NAME, new ColumnExpression(PROJECT_NAME, PROJECTS_ALIAS)); setDataSource(leftDataSource); getTableAliases().put(PROJECTS_ALIAS, PROJECTS); BooleanExpression whereCondition = new BinaryBooleanExpression( new SimpleBooleanExpression(new ColumnExpression(PROJECT_NAME, PROJECTS_ALIAS), EQUAL, VALUE), OR, new SimpleBooleanExpression(new ColumnExpression(PROJECT_NAME, PROJECTS_ALIAS), EQUAL, ANOTHER_VALUE) ); setWhereExpression(whereCondition); } }); List<Task> tasks = new ArrayList<>(plan()); DataSourceTask dataSourceTask = doCommonTaskAssertions(tasks, Arrays.asList(DataSourceTask.class, FilterTask.class, SelectTask.class)); doOptimizedLeftDataSourceAssertions(dataSourceTask); FilterTask filterTask = (FilterTask) tasks.get(1); assertThat(filterTask.getCondition().isPresent(), is(true)); BooleanExpression optimizedLeftCondition = filterTask.getCondition().get(); assertThat(optimizedLeftCondition.getTableAliases(), contains(PROJECTS_ALIAS)); Map<String, Set<Object>> fixedValueCondition = optimizedLeftCondition.getFixedValueConditions(PROJECTS_ALIAS); assertThat(fixedValueCondition.keySet(), contains(PROJECT_NAME)); assertThat(fixedValueCondition.get(PROJECT_NAME), containsInAnyOrder(VALUE, ANOTHER_VALUE)); }
@Test public void testOptimizeIndexedInCondition() throws Exception { DataSource leftDataSource = new DataSource(INSTANCES); Set<Object> values = new HashSet<>(Arrays.asList(VALUE, ANOTHER_VALUE)); BooleanExpression whereCondition = new InExpression( new ColumnExpression(NAME, INSTANCES), values ); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getSelectionMap().put(ANY_COLUMN, new ColumnExpression()); setDataSource(leftDataSource); getTableAliases().put(INSTANCES, INSTANCES); setWhereExpression(whereCondition); } }); List<Task> tasks = new ArrayList<>(plan()); DataSourceTask dataSourceTask = doCommonTaskAssertions(tasks); DataSource dataSource = doOptimizedLeftDataSourceAssertions(dataSourceTask); Optional<BooleanExpression> conditionCandidate = dataSource.getCondition(); assertThat(conditionCandidate.isPresent(), is(true)); BooleanExpression condition = conditionCandidate.get(); assertThat(condition, is(instanceOf(IndexBooleanExpression.class))); assertThat(condition.getFixedValueConditions(INSTANCES), equalTo(Collections.singletonMap(NAME, values))); }
@Test public void testOptimizeMultipleRegexConditions() throws Exception { DataSource leftDataSource = new DataSource(INSTANCES); BooleanExpression whereCondition = new BinaryBooleanExpression( new SimpleBooleanExpression(new ColumnExpression(NAME, INSTANCES), REGEXP, VALUE), OR, new SimpleBooleanExpression(new ColumnExpression(NAME, INSTANCES), REGEXP, ANOTHER_VALUE) ); queryParser.setSelectQueryAware(new MockSelectQueryAware(){ { getSelectionMap().put(NAME, new ColumnExpression(NAME, INSTANCES)); setDataSource(leftDataSource); getTableAliases().put(INSTANCES, INSTANCES); setWhereExpression(whereCondition); } }); List<Task> tasks = new ArrayList<>(plan()); DataSourceTask dataSourceTask = doCommonTaskAssertions(tasks, Arrays.asList(DataSourceTask.class, FilterTask.class, SelectTask.class)); doOptimizedLeftDataSourceAssertions(dataSourceTask); FilterTask filterTask = (FilterTask) tasks.get(1); assertThat(filterTask.getCondition().isPresent(), is(true)); BooleanExpression optimizedCondition = filterTask.getCondition().get(); assertThat(optimizedCondition.getTableAliases(), contains(INSTANCES)); assertThat(optimizedCondition.getFixedValueConditions(INSTANCES).keySet(), is(empty())); assertThat(optimizedCondition.getColumnRelations(), is(empty())); assertThat(optimizedCondition.getRestOfExpression(), is(equalTo(Optional.of(whereCondition)))); }