@Override protected R visitQuerySpecification(QuerySpecification node, C context) { process(node.getSelect(), context); if (node.getFrom().isPresent()) { process(node.getFrom().get(), context); } if (node.getWhere().isPresent()) { process(node.getWhere().get(), context); } if (node.getGroupBy().isPresent()) { process(node.getGroupBy().get(), context); } if (node.getHaving().isPresent()) { process(node.getHaving().get(), context); } if (node.getOrderBy().isPresent()) { process(node.getOrderBy().get(), context); } return null; }
private PlanBuilder limit(PlanBuilder subPlan, QuerySpecification node) { return limit(subPlan, node.getOrderBy(), node.getLimit()); }
public static Query simpleQuery(Select select, Relation from, Optional<Expression> where, Optional<GroupBy> groupBy, Optional<Expression> having, Optional<OrderBy> orderBy, Optional<String> limit) { return query(new QuerySpecification( select, Optional.of(from), where, groupBy, having, orderBy, limit)); }
private List<Expression> analyzeOrderBy(QuerySpecification node, Scope orderByScope, List<Expression> outputExpressions) { checkState(node.getOrderBy().isPresent(), "orderBy is absent"); List<SortItem> sortItems = getSortItemsFromOrderBy(node.getOrderBy()); if (node.getSelect().isDistinct()) { verifySelectDistinct(node, outputExpressions); } return analyzeOrderBy(node, sortItems, orderByScope); }
private ResponseQuery parseQuerySpecification(QuerySpecification queryBody, Optional<String> limitOutside, List<SortItem> orderByOutside, Map<String, NodeLocation> with) { Function<Node, Integer> mapper = item -> { if (item instanceof GroupingElement) { return findSelectIndex(((GroupingElement) item).enumerateGroupingSets(), queryBody.getSelect().getSelectItems()).orElse(null); } else if (item instanceof LongLiteral) { return Ints.checkedCast(((LongLiteral) item).getValue()); List<GroupBy> groupBy = queryBody.getGroupBy().map(value -> value.getGroupingElements().stream() .map(item -> new GroupBy(mapper.apply(item), item.enumerateGroupingSets().toString())) .collect(Collectors.toList())).orElse(ImmutableList.of()); .collect(Collectors.toList()); } else { orderBy = queryBody.getOrderBy().map(v -> v.getSortItems().stream().map(item -> new Ordering(item.getOrdering(), mapper.apply(item.getSortKey()), item.getSortKey().toString())) .collect(Collectors.toList())).orElse(ImmutableList.of()); String limitStr = limitOutside.orElse(queryBody.getLimit().orElse(null)); Long limit = null; if (limitStr != null) { return new ResponseQuery(with, queryBody.getLocation().orElse(null), groupBy, orderBy, limit);
private boolean hasAggregates(QuerySpecification node) { ImmutableList.Builder<Node> toExtractBuilder = ImmutableList.builder(); toExtractBuilder.addAll(node.getSelect().getSelectItems().stream() .filter(SingleColumn.class::isInstance) .collect(toImmutableList())); toExtractBuilder.addAll(getSortItemsFromOrderBy(node.getOrderBy())); node.getHaving().ifPresent(toExtractBuilder::add); List<FunctionCall> aggregates = extractAggregateFunctions(toExtractBuilder.build(), metadata.getFunctionRegistry()); return !aggregates.isEmpty(); }
node.getWhere().ifPresent(where -> analyzeWhere(node, sourceScope, where)); if (node.getOrderBy().isPresent()) { orderByScope = Optional.of(computeAndAssignOrderByScope(node.getOrderBy().get(), sourceScope, outputScope)); orderByExpressions = analyzeOrderBy(node, orderByScope.get(), outputExpressions); node.getHaving().ifPresent(sourceExpressions::add); analyzeWindowFunctions(node, outputExpressions, orderByExpressions); if (analysis.isAggregation(node) && node.getOrderBy().isPresent()) { computeAndAssignOrderByScopeWithAggregation(node.getOrderBy().get(), sourceScope, outputScope, orderByAggregations, groupByExpressions, orderByGroupingOperations);
if(!(queryBody instanceof QuerySpecification)) throw new SQLException("Statement does not contain expected query specifiction"); QuerySpecification querySpec = (QuerySpecification)queryBody; if(!querySpec.getFrom().isPresent()) throw new SQLException("Add atleast one INDEX to the query to create the view from"); List<QuerySource> relations = new RelationParser().process(querySpec.getFrom().get(), null); String[] indices = new String[relations.size()]; for(int i=0; i<relations.size(); i++) indices[i] = relations.get(i).getSource(); new SelectParser().process(querySpec.getSelect(), state); if(querySpec.getWhere().isPresent()){ QueryBuilder query = new WhereParser().process(querySpec.getWhere().get(), state).getQuery(); response = client.admin().indices().prepareAliases().addAlias(indices, alias, query).execute().actionGet(); }else{
for (SelectItem item : node.getSelect().getSelectItems()) { if (item instanceof AllColumns) { throw new SemanticException(MISSING_TABLE, item, "Table '%s' not found", starPrefix.get()); if (!node.getFrom().isPresent()) { throw new SemanticException(WILDCARD_WITHOUT_FROM, item, "SELECT * not allowed in queries without FROM clause"); if (node.getSelect().isDistinct() && !type.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s)", type); if (node.getSelect().isDistinct() && !type.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s): %s", type, column.getExpression());
private PlanBuilder distinct(PlanBuilder subPlan, QuerySpecification node) { if (node.getSelect().isDistinct()) { return subPlan.withNewRoot( new AggregationNode( idAllocator.getNextId(), subPlan.getRoot(), ImmutableMap.of(), singleGroupingSet(subPlan.getRoot().getOutputSymbols()), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty())); } return subPlan; }
private void analyzeGroupingOperations(QuerySpecification node, List<Expression> outputExpressions, List<Expression> orderByExpressions) { List<GroupingOperation> groupingOperations = extractExpressions(Iterables.concat(outputExpressions, orderByExpressions), GroupingOperation.class); boolean isGroupingOperationPresent = !groupingOperations.isEmpty(); if (isGroupingOperationPresent && !node.getGroupBy().isPresent()) { throw new SemanticException( INVALID_PROCEDURE_ARGUMENTS, node, "A GROUPING() operation can only be used with a corresponding GROUPING SET/CUBE/ROLLUP/GROUP BY clause"); } analysis.setGroupingOperations(node, groupingOperations); }
private void analyzeHaving(QuerySpecification node, Scope scope) { if (node.getHaving().isPresent()) { Expression predicate = node.getHaving().get(); ExpressionAnalysis expressionAnalysis = analyzeExpression(predicate, scope); expressionAnalysis.getWindowFunctions().stream() .findFirst() .ifPresent(function -> { throw new SemanticException(NESTED_WINDOW, function.getNode(), "HAVING clause cannot contain window functions"); }); analysis.recordSubqueries(node, expressionAnalysis); Type predicateType = expressionAnalysis.getType(predicate); if (!predicateType.equals(BOOLEAN) && !predicateType.equals(UNKNOWN)) { throw new SemanticException(TYPE_MISMATCH, predicate, "HAVING clause must evaluate to a boolean: actual type %s", predicateType); } analysis.setHaving(node, predicate); } }
private void analyzeWindowFunctions(QuerySpecification node, List<Expression> outputExpressions, List<Expression> orderByExpressions) { analysis.setWindowFunctions(node, analyzeWindowFunctions(node, outputExpressions)); if (node.getOrderBy().isPresent()) { analysis.setOrderByWindowFunctions(node.getOrderBy().get(), analyzeWindowFunctions(node, orderByExpressions)); } }
@Override protected RelationType visitQuerySpecification(QuerySpecification node, AnalysisContext parentContext) { // TODO: extract candidate names from SELECT, WHERE, HAVING, GROUP BY and ORDER BY expressions // to pass down to analyzeFrom AnalysisContext context = new AnalysisContext(parentContext); RelationType tupleDescriptor = analyzeFrom(node, context); node.getWhere().ifPresent(where -> analyzeWhere(node, tupleDescriptor, context, where)); List<FieldOrExpression> outputExpressions = analyzeSelect(node, tupleDescriptor, context); List<List<FieldOrExpression>> groupByExpressions = analyzeGroupBy(node, tupleDescriptor, context, outputExpressions); List<FieldOrExpression> orderByExpressions = analyzeOrderBy(node, tupleDescriptor, context, outputExpressions); analyzeHaving(node, tupleDescriptor, context); analyzeAggregations(node, tupleDescriptor, groupByExpressions, outputExpressions, orderByExpressions, context, analysis.getColumnReferences()); analyzeWindowFunctions(node, outputExpressions, orderByExpressions); RelationType descriptor = computeOutputDescriptor(node, tupleDescriptor); analysis.setOutputDescriptor(node, descriptor); return descriptor; }
private List<FunctionCall> extractAggregates(QuerySpecification node) { AggregateExtractor extractor = new AggregateExtractor(metadata); for (SelectItem item : node.getSelect().getSelectItems()) { if (item instanceof SingleColumn) { extractor.process(((SingleColumn) item).getExpression(), null); } } for (SortItem item : node.getOrderBy()) { extractor.process(item.getSortKey(), null); } if (node.getHaving().isPresent()) { extractor.process(node.getHaving().get(), null); } List<FunctionCall> aggregates = extractor.getAggregates(); analysis.setAggregates(node, aggregates); return aggregates; }
private void verifySelectDistinct(QuerySpecification node, List<Expression> outputExpressions) { for (SortItem item : node.getOrderBy().get().getSortItems()) { Expression expression = item.getSortKey(); if (expression instanceof LongLiteral) { continue; } Expression rewrittenOrderByExpression = ExpressionTreeRewriter.rewriteWith(new OrderByExpressionRewriter(extractNamedOutputExpressions(node.getSelect())), expression); int index = outputExpressions.indexOf(rewrittenOrderByExpression); if (index == -1) { throw new SemanticException(ORDER_BY_MUST_BE_IN_SELECT, node.getSelect(), "For SELECT DISTINCT, ORDER BY expressions must appear in select list"); } if (!isDeterministic(expression)) { throw new SemanticException(NONDETERMINISTIC_ORDER_BY_EXPRESSION_WITH_SELECT_DISTINCT, expression, "Non deterministic ORDER BY expression is not supported with SELECT DISTINCT"); } } }
for (SelectItem item : node.getSelect().getSelectItems()) { if (item instanceof AllColumns) {
private List<Expression> analyzeGroupBy(QuerySpecification node, Scope scope, List<Expression> outputExpressions) if (node.getGroupBy().isPresent()) { ImmutableList.Builder<Set<FieldId>> cubes = ImmutableList.builder(); ImmutableList.Builder<List<FieldId>> rollups = ImmutableList.builder(); ImmutableList.Builder<Expression> groupingExpressions = ImmutableList.builder(); checkGroupingSetsCount(node.getGroupBy().get()); for (GroupingElement groupingElement : node.getGroupBy().get().getGroupingElements()) { if (groupingElement instanceof SimpleGroupBy) { for (Expression column : groupingElement.getExpressions()) {