@Override public <T> Set<T> eval( QueryEnvironment<T> env, ImmutableList<Argument> args, ListeningExecutorService executor) throws QueryException, InterruptedException { QueryExpression argument = args.get(args.size() - 1).getExpression(); String attr = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, args.get(0).getWord()); final String attrValue = args.get(1).getWord(); final Predicate<Object> predicate = new Predicate<Object>() { @Override public boolean apply(Object input) { return attrValue.equals(input.toString()); } }; Set<T> result = new LinkedHashSet<>(); for (T target : argument.eval(env, executor)) { ImmutableSet<Object> matchingObjects = env.filterAttributeContents(target, attr, predicate); if (!matchingObjects.isEmpty()) { result.add(target); } } return result; }
OrderedHashSet getSubqueries() { OrderedHashSet set = null; if (joinCondition != null) { set = joinCondition.collectAllSubqueries(set); } if (rangeTable instanceof TableDerived) { QueryExpression baseQueryExpression = ((TableDerived) rangeTable).getQueryExpression(); if (((TableDerived) rangeTable).view != null) { if (set == null) { set = new OrderedHashSet(); } set.addAll(((TableDerived) rangeTable).view.getSubqueries()); } else if (baseQueryExpression == null) { set = OrderedHashSet.add(set, rangeTable.getSubQuery()); } else { OrderedHashSet temp = baseQueryExpression.getSubqueries(); set = OrderedHashSet.addAll(set, temp); set = OrderedHashSet.add(set, rangeTable.getSubQuery()); } } return set; }
SubQuery(Database database, int level, QueryExpression queryExpression, int mode) { this.level = level; this.queryExpression = queryExpression; this.database = database; switch (mode) { case OpTypes.EXISTS: isExistsPredicate = true; break; case OpTypes.IN: uniqueRows = true; if (queryExpression != null) { queryExpression.setFullOrder(); } break; case OpTypes.UNIQUE: isUniquePredicate = true; if (queryExpression != null) { queryExpression.setFullOrder(); } } }
private QueryExpression create(Request request, ResourceDefinition resourceDefinition) throws InvalidQueryException { String queryString; if (request.getCardinality() == Request.Cardinality.INSTANCE) { String idPropertyName = resourceDefinition.getIdPropertyName(); queryString = String.format("%s:%s", idPropertyName, request.<String>getProperty(idPropertyName)); } else { queryString = request.getQueryString(); } QueryExpression queryExpression; if (queryString != null && !queryString.isEmpty()) { QueryParser queryParser = new QueryParser(Version.LUCENE_48, "name", new KeywordAnalyzer()); queryParser.setLowercaseExpandedTerms(false); queryParser.setAllowLeadingWildcard(true); Query query; try { query = queryParser.parse((String) escape(queryString)); } catch (ParseException e) { throw new InvalidQueryException(e.getMessage()); } LOG.info("LuceneQuery: " + query); queryExpression = create(query, resourceDefinition); } else { queryExpression = new AlwaysQueryExpression(); } // add query properties to request so that they are returned request.addAdditionalSelectProperties(queryExpression.getProperties()); return queryExpression; }
@Override public <T> Set<T> eval(QueryEnvironment<T> env, ImmutableList<Argument> args, Executor executor) throws QueryException, InterruptedException { QueryExpression from = args.get(0).getExpression(); QueryExpression to = args.get(1).getExpression(); Set<T> fromSet = from.eval(env, executor); Set<T> toSet = to.eval(env, executor); // Algorithm: // 1) compute "reachableFromX", the forward transitive closure of the "from" set; // 2) find the intersection of "reachableFromX" with the "to" set, and traverse the graph using // the reverse dependencies. This will effectively compute the intersection between the nodes // reachable from the "from" set and the reverse transitive closure of the "to" set. env.buildTransitiveClosure(fromSet, Integer.MAX_VALUE, executor); Set<T> reachableFromX = env.getTransitiveClosure(fromSet); Set<T> result = MoreSets.intersection(reachableFromX, toSet); Collection<T> worklist = result; while (!worklist.isEmpty()) { Collection<T> reverseDeps = env.getReverseDeps(worklist); worklist = Lists.newArrayList(); for (T target : reverseDeps) { if (reachableFromX.contains(target) && result.add(target)) { worklist.add(target); } } } return result; }
public void replaceColumnReferences(RangeVariable range, Expression[] list) { QueryExpression queryExpression = rangeTable.getQueryExpression(); Expression dataExpression = rangeTable.getDataExpression(); if (dataExpression != null) { dataExpression = dataExpression.replaceColumnReferences(range, list); } if (queryExpression != null) { queryExpression.replaceColumnReferences(range, list); } if (joinCondition != null) { joinCondition = joinCondition.replaceColumnReferences(range, list); } for (int i = 0; i < joinConditions.length; i++) { joinConditions[i].replaceColumnReferences(range, list); } for (int i = 0; i < whereConditions.length; i++) { whereConditions[i].replaceColumnReferences(range, list); } }
public OrderedHashSet getSubqueries() { OrderedHashSet set = null; if (joinCondition != null) { set = joinCondition.collectAllSubqueries(set); } if (rangeTable instanceof TableDerived) { QueryExpression queryExpression = ((TableDerived) rangeTable).getQueryExpression(); if (queryExpression == null) { Expression dataExpression = ((TableDerived) rangeTable).getDataExpression(); if (dataExpression != null) { if (set == null) { set = new OrderedHashSet(); } OrderedHashSet.addAll(set, dataExpression.getSubqueries()); } } else { OrderedHashSet temp = queryExpression.getSubqueries(); set = OrderedHashSet.addAll(set, temp); set = OrderedHashSet.add(set, rangeTable); } } return set; }
public void setExpressionValueAsParam(QueryExpression expr) { if (valueAsParamConfiged) { exprValueAsParam = valueAsParam; } else { exprValueAsParam = expr.getValueAsParam(); } }
/** Fills the table with a result set */ public void materialise(Session session) { PersistentStore store; // table constructors if (isDataExpression) { store = session.sessionData.getSubqueryRowStore(table); dataExpression.insertValuesIntoSubqueryTable(session, store); return; } Result result = queryExpression.getResult(session, isExistsPredicate ? 1 : 0); if (uniqueRows) { RowSetNavigatorData navigator = ((RowSetNavigatorData) result.getNavigator()); navigator.removeDuplicates(); } store = session.sessionData.getSubqueryRowStore(table); table.insertResult(store, result); result.getNavigator().close(); }
void resolveRangeTableTypes(Session session, RangeVariable[] ranges) { QueryExpression queryExpression = rangeTable.getQueryExpression(); if (queryExpression != null) { if (queryExpression instanceof QuerySpecification) { QuerySpecification qs = (QuerySpecification) queryExpression; if (qs.isGrouped || qs.isAggregated || qs.isOrderSensitive) { // } else { moveConditionsToInner(session, ranges); } } queryExpression.resolveTypesPartThree(session); } }
public OrderedHashSet collectAllExpressions( OrderedHashSet set, OrderedIntHashSet typeSet, OrderedIntHashSet stopAtTypeSet) { if (joinCondition != null) { set = joinCondition.collectAllExpressions(set, typeSet, stopAtTypeSet); } QueryExpression queryExpression = rangeTable.getQueryExpression(); Expression dataExpression = rangeTable.getDataExpression(); if (queryExpression != null) { set = queryExpression.collectAllExpressions(set, typeSet, stopAtTypeSet); } if (dataExpression != null) { set = dataExpression.collectAllExpressions(set, typeSet, stopAtTypeSet); } return set; }
public void resolveRangeTable(Session session, RangeGroup rangeGroup, RangeGroup[] rangeGroups) { QueryExpression queryExpression = rangeTable.getQueryExpression(); Expression dataExpression = rangeTable.getDataExpression(); if (queryExpression == null && dataExpression == null) { return; } rangeGroups = (RangeGroup[]) ArrayUtil.toAdjustedArray(rangeGroups, rangeGroup, rangeGroups.length, 1); if (dataExpression != null) { HsqlList unresolved = dataExpression.resolveColumnReferences(session, RangeGroup.emptyGroup, rangeGroups, null); unresolved = Expression.resolveColumnSet( session, RangeVariable.emptyArray, RangeGroup.emptyArray, unresolved); ExpressionColumn.checkColumnsResolved(unresolved); dataExpression.resolveTypes(session, null); setRangeTableVariables(); } if (queryExpression != null) { queryExpression.resolveReferences(session, rangeGroups); HsqlList unresolved = queryExpression.getUnresolvedExpressions(); unresolved = Expression.resolveColumnSet( session, RangeVariable.emptyArray, RangeGroup.emptyArray, unresolved); ExpressionColumn.checkColumnsResolved(unresolved); queryExpression.resolveTypesPartOne(session); queryExpression.resolveTypesPartTwo(session); rangeTable.prepareTable(); setRangeTableVariables(); } }
VoltXMLElement voltGetXMLExpression(QueryExpression queryExpr, Session session) throws HSQLParseException { // "select" statements/clauses are always represented by a QueryExpression of type // QuerySpecification. // The only other instances of QueryExpression are direct QueryExpression instances instantiated // in XreadSetOperation // to represent UNION, etc. int exprType = queryExpr.getUnionType(); if (exprType == QueryExpression.NOUNION) { // "select" statements/clauses are always represented by a QueryExpression of type // QuerySpecification. if (!(queryExpr instanceof QuerySpecification)) { throw new HSQLParseException(queryExpr.operatorName() + " is not supported."); } QuerySpecification select = (QuerySpecification) queryExpr; return voltGetXMLSpecification(select, session); } else if (exprType == QueryExpression.UNION || exprType == QueryExpression.UNION_ALL || exprType == QueryExpression.EXCEPT || exprType == QueryExpression.EXCEPT_ALL || exprType == QueryExpression.INTERSECT || exprType == QueryExpression.INTERSECT_ALL) { VoltXMLElement unionExpr = new VoltXMLElement("union"); unionExpr.attributes.put("uniontype", queryExpr.operatorName()); VoltXMLElement leftExpr = voltGetXMLExpression(queryExpr.getLeftQueryExpression(), session); VoltXMLElement rightExpr = voltGetXMLExpression(queryExpr.getRightQueryExpression(), session); /** * Try to merge parent and the child nodes for UNION and INTERSECT (ALL) set operation. In * case of EXCEPT(ALL) operation only the left child can be merged with the parent in order to * preserve associativity - (Select1 EXCEPT Select2) EXCEPT Select3 vs. Select1 EXCEPT * (Select2 EXCEPT Select3) */ if ("union".equalsIgnoreCase(leftExpr.name) && queryExpr.operatorName().equalsIgnoreCase(leftExpr.attributes.get("uniontype"))) { unionExpr.children.addAll(leftExpr.children); } else { unionExpr.children.add(leftExpr); } if (exprType != QueryExpression.EXCEPT && exprType != QueryExpression.EXCEPT_ALL && "union".equalsIgnoreCase(rightExpr.name) && queryExpr.operatorName().equalsIgnoreCase(rightExpr.attributes.get("uniontype"))) { unionExpr.children.addAll(rightExpr.children); } else { unionExpr.children.add(rightExpr); } return unionExpr; } else { throw new HSQLParseException( queryExpression.operatorName() + " tuple set operator is not supported."); } }
SubQuery[] getSubqueries(Session session) { OrderedHashSet subQueries = null; for (int i = 0; i < targetRangeVariables.length; i++) { if (targetRangeVariables[i] == null) { continue; } OrderedHashSet set = targetRangeVariables[i].getSubqueries(); subQueries = OrderedHashSet.addAll(subQueries, set); } for (int i = 0; i < updateExpressions.length; i++) { subQueries = updateExpressions[i].collectAllSubqueries(subQueries); } if (insertExpression != null) { subQueries = insertExpression.collectAllSubqueries(subQueries); } if (condition != null) { subQueries = condition.collectAllSubqueries(subQueries); } if (queryExpression != null) { OrderedHashSet set = queryExpression.getSubqueries(); subQueries = OrderedHashSet.addAll(subQueries, set); } if (subQueries == null || subQueries.size() == 0) { return SubQuery.emptySubqueryArray; } SubQuery[] subQueryArray = new SubQuery[subQueries.size()]; subQueries.toArray(subQueryArray); ArraySort.sort(subQueryArray, 0, subQueryArray.length, subQueryArray[0]); for (int i = 0; i < subQueryArray.length; i++) { subQueryArray[i].prepareTable(session); } return subQueryArray; }
void moveConditionsToInner(Session session, RangeVariable[] ranges) { Expression[] colExpr; int exclude; HsqlArrayList conditionsList; Expression condition = null; if (whereConditions.length > 1) { return; } if (joinConditions.length > 1) { return; } for (int i = 0; i < ranges.length; i++) { if (ranges[i].isLeftJoin || ranges[i].isRightJoin) { return; } } exclude = ArrayUtil.find(ranges, this); conditionsList = new HsqlArrayList(); addConditionsToList(conditionsList, joinConditions[0].indexCond); if (joinConditions[0].indexCond != null && joinConditions[0].indexCond[0] != joinConditions[0].indexEndCond[0]) { addConditionsToList(conditionsList, joinConditions[0].indexEndCond); } addConditionsToList(conditionsList, whereConditions[0].indexCond); addConditionsToList(conditionsList, whereConditions[0].indexEndCond); RangeVariableResolver.decomposeAndConditions( session, joinConditions[0].nonIndexCondition, conditionsList); RangeVariableResolver.decomposeAndConditions( session, whereConditions[0].nonIndexCondition, conditionsList); for (int i = conditionsList.size() - 1; i >= 0; i--) { Expression e = (Expression) conditionsList.get(i); if (e == null || e.isTrue() || e.hasReference(ranges, exclude)) { conditionsList.remove(i); continue; } } if (conditionsList.size() == 0) { if (rangeTable.isView()) { ((TableDerived) rangeTable).resetToView(); } return; } QueryExpression queryExpression = rangeTable.getQueryExpression(); colExpr = ((QuerySpecification) queryExpression).exprColumns; for (int i = 0; i < conditionsList.size(); i++) { Expression e = (Expression) conditionsList.get(i); OrderedHashSet set = e.collectRangeVariables(null); e = e.duplicate(); e = e.replaceColumnReferences(this, colExpr); if (e.collectAllSubqueries(null) != null) { return; } if (set != null) { for (int j = 0; j < set.size(); j++) { RangeVariable range = (RangeVariable) set.get(j); if (this != range && range.rangeType == RangeVariable.TABLE_RANGE) { queryExpression.setCorrelated(); } } } condition = ExpressionLogical.andExpressions(condition, e); } queryExpression.addExtraConditions(condition); }
QueryExpression createExpression(T query, ResourceDefinition resourceDefinition) { QueryExpression expression = create(query, resourceDefinition); return expression.isProjectionExpression() ? new ProjectionQueryExpression(expression, resourceDefinition) : expression; }
@Override public List<?> translateCommand(Command command, ExecutionContext context) { if (command instanceof Insert) { try { handleInsertSequences((Insert) command); } catch (TranslatorException e) { throw new RuntimeException(e); } } if (!(command instanceof QueryExpression)) { return null; } QueryExpression queryCommand = (QueryExpression) command; if (queryCommand.getLimit() == null) { return null; } Limit limit = queryCommand.getLimit(); queryCommand.setLimit(null); if (command instanceof Select) { Select select = (Select) command; TableReference tr = select.getFrom().get(0); if (tr instanceof NamedTable && isDual((NamedTable) tr)) { if (limit.getRowOffset() > 0 || limit.getRowLimit() == 0) { // no data select.setWhere( new Comparison( new Literal(1, TypeFacility.RUNTIME_TYPES.INTEGER), new Literal(0, TypeFacility.RUNTIME_TYPES.INTEGER), Operator.EQ)); return null; } return null; // dual does not allow a limit } } List<Object> parts = new ArrayList<Object>(); parts.add("SELECT "); // $NON-NLS-1$ /* * if all of the columns are aliased, assume that names matter - it actually only seems to matter for * the first query of a set op when there is a order by. Rather than adding logic to traverse up, * we just use the projected names */ boolean allAliased = true; for (DerivedColumn selectSymbol : queryCommand.getProjectedQuery().getDerivedColumns()) { if (selectSymbol.getAlias() == null) { allAliased = false; break; } } if (allAliased) { String[] columnNames = queryCommand.getColumnNames(); for (int i = 0; i < columnNames.length; i++) { if (i > 0) { parts.add(", "); // $NON-NLS-1$ } parts.add(columnNames[i]); } } else { parts.add("*"); // $NON-NLS-1$ } if (limit.getRowOffset() > 0) { parts.add(" FROM (SELECT VIEW_FOR_LIMIT.*, ROWNUM ROWNUM_ FROM ("); // $NON-NLS-1$ } else { parts.add(" FROM ("); // $NON-NLS-1$ } parts.add(queryCommand); if (limit.getRowOffset() > 0) { parts.add(") VIEW_FOR_LIMIT WHERE ROWNUM <= "); // $NON-NLS-1$ parts.add(limit.getRowLimit() + limit.getRowOffset()); parts.add(") WHERE ROWNUM_ > "); // $NON-NLS-1$ parts.add(limit.getRowOffset()); } else { parts.add(") WHERE ROWNUM <= "); // $NON-NLS-1$ parts.add(limit.getRowLimit()); } return parts; }
/** Provides the toString() implementation. */ String describeImpl(Session session) throws Exception { StringBuffer sb; sb = new StringBuffer(); int blanks = 0; switch (type) { case StatementTypes.SELECT_CURSOR: { sb.append(queryExpression.describe(session, 0)); appendParms(sb).append('\n'); appendSubqueries(session, sb, 2); return sb.toString(); } case StatementTypes.INSERT: { if (queryExpression == null) { sb.append("INSERT VALUES"); sb.append('[').append('\n'); appendMultiColumns(sb, insertColumnMap).append('\n'); appendTable(sb).append('\n'); appendParms(sb).append('\n'); appendSubqueries(session, sb, 2).append(']'); return sb.toString(); } else { sb.append("INSERT SELECT"); sb.append('[').append('\n'); appendColumns(sb, insertColumnMap).append('\n'); appendTable(sb).append('\n'); sb.append(queryExpression.describe(session, blanks)).append('\n'); appendParms(sb).append('\n'); appendSubqueries(session, sb, 2).append(']'); return sb.toString(); } } case StatementTypes.UPDATE_WHERE: { sb.append("UPDATE"); sb.append('[').append('\n'); appendColumns(sb, updateColumnMap).append('\n'); appendTable(sb).append('\n'); appendCondition(session, sb); for (int i = 0; i < targetRangeVariables.length; i++) { sb.append(targetRangeVariables[i].describe(session, blanks)).append('\n'); } appendParms(sb).append('\n'); appendSubqueries(session, sb, 2).append(']'); return sb.toString(); } case StatementTypes.DELETE_WHERE: { sb.append("DELETE"); sb.append('[').append('\n'); appendTable(sb).append('\n'); appendCondition(session, sb); for (int i = 0; i < targetRangeVariables.length; i++) { sb.append(targetRangeVariables[i].describe(session, blanks)).append('\n'); } appendParms(sb).append('\n'); appendSubqueries(session, sb, 2).append(']'); return sb.toString(); } case StatementTypes.CALL: { sb.append("CALL"); sb.append('[').append(']'); return sb.toString(); } case StatementTypes.MERGE: { sb.append("MERGE"); sb.append('[').append('\n'); appendMultiColumns(sb, insertColumnMap).append('\n'); appendColumns(sb, updateColumnMap).append('\n'); appendTable(sb).append('\n'); appendCondition(session, sb); for (int i = 0; i < targetRangeVariables.length; i++) { sb.append(targetRangeVariables[i].describe(session, blanks)).append('\n'); } appendParms(sb).append('\n'); appendSubqueries(session, sb, 2).append(']'); return sb.toString(); } default: { return "UNKNOWN"; } } }