private void resolveColumnsAndReplaceAlias(CubeQueryContext cubeql, Set<ExprSpecContext> exprs) throws SemanticException { Set<ExprSpecContext> nestedExpressions = new LinkedHashSet<ExprSpecContext>(); for (ExprSpecContext esc : exprs) { for (Map.Entry<String, Set<String>> entry : esc.getTblAliasToColumns().entrySet()) { if (entry.getKey().equals(CubeQueryContext.DEFAULT_TABLE)) { continue; } AbstractBaseTable baseTable = (AbstractBaseTable) cubeql.getCubeTableForAlias(entry.getKey()); Set<String> exprCols = new HashSet<String>(); for (String col : entry.getValue()) { // col is an expression if (baseTable.getExpressionNames().contains(col)) { exprCols.add(col); } } // get all combinations of expression replaced with inner exprs AST. addAllNestedExpressions(cubeql, esc, baseTable, nestedExpressions, exprCols); } } for (ExprSpecContext esc : nestedExpressions) { esc.resolveColumns(cubeql); esc.replaceAliasInAST(cubeql); for (String table : esc.getTblAliasToColumns().keySet()) { try { if (!CubeQueryContext.DEFAULT_TABLE.equalsIgnoreCase(table) && !srcAlias.equals(table)) { cubeql.addOptionalDimTable( table, null, false, null, false, esc.getTblAliasToColumns().get(table).toArray(new String[0])); esc.exprDims.add((Dimension) cubeql.getCubeTableForAlias(table)); } } catch (HiveException e) { throw new SemanticException(e); } } } exprs.addAll(nestedExpressions); }
private void addAllNestedExpressions( CubeQueryContext cubeql, ExprSpecContext baseEsc, AbstractBaseTable baseTable, Set<ExprSpecContext> nestedExpressions, Set<String> exprCols) throws SemanticException { for (String col : exprCols) { Set<ExprSpecContext> replacedExpressions = new LinkedHashSet<ExprSpecContext>(); for (ExprSpec es : baseTable.getExpressionByName(col).getExpressionSpecs()) { ASTNode finalAST = HQLParser.copyAST(baseEsc.getFinalAST()); replaceColumnInAST(finalAST, col, es.getASTNode()); ExprSpecContext replacedESC = new ExprSpecContext(baseEsc, es, finalAST, cubeql); nestedExpressions.add(replacedESC); replacedExpressions.add(replacedESC); } Set<String> remaining = new LinkedHashSet<String>(exprCols); remaining.remove(col); for (ExprSpecContext replacedESC : replacedExpressions) { addAllNestedExpressions(cubeql, replacedESC, baseTable, nestedExpressions, remaining); } } }
void pruneExpressions() { for (Set<ExpressionContext> ecSet : allExprsQueried.values()) { for (ExpressionContext ec : ecSet) { Set<ExprSpecContext> removedEsc = new HashSet<ExprSpecContext>(); for (Iterator<ExprSpecContext> iterator = ec.getAllExprs().iterator(); iterator.hasNext(); ) { ExprSpecContext esc = iterator.next(); boolean removed = false; // Go over expression dims and remove expression involving dimensions for which // candidate tables are // not there for (Dimension exprDim : esc.exprDims) { if (cubeql.getCandidateDims().get(exprDim) == null || cubeql.getCandidateDims().get(exprDim).isEmpty()) { log.info( "Removing expression {} as {} it does not have any candidate tables", esc, exprDim); iterator.remove(); removedEsc.add(esc); removed = true; break; } } if (removed) { continue; } // remove expressions which are not valid in the timerange queried // If an expression is defined as // ex = a + b // from t1 to t2; // ex = c + d // from t2 to t3 // With range queried, invalid expressions will be removed // If range is including more than one expression, queries can be unioned as an // improvement at later time. // But for now, they are not eligible expressions for (TimeRange range : cubeql.getTimeRanges()) { if (!esc.isValidInTimeRange(range)) { log.info("Removing expression {} as it is not valid in timerange queried", esc); iterator.remove(); removedEsc.add(esc); removed = true; break; } } if (removed) { continue; } // Go over expressions and remove expression containing unavailable columns in timerange // In the example above, // if ex = a +b ; and a is not available in timerange queried, it will be removed. for (TimeRange range : cubeql.getTimeRanges()) { boolean toRemove = false; for (Map.Entry<String, Set<String>> entry : esc.getTblAliasToColumns().entrySet()) { if (CubeQueryContext.DEFAULT_TABLE.equalsIgnoreCase(entry.getKey())) { continue; } AbstractBaseTable baseTable = (AbstractBaseTable) cubeql.getCubeTableForAlias(entry.getKey()); for (String col : entry.getValue()) { if (!baseTable.getColumnByName(col).isColumnAvailableInTimeRange(range)) { toRemove = true; break; } } if (toRemove) { break; } } if (toRemove) { log.info( "Removing expression {} as its columns are unavailable in timerange queried", esc); iterator.remove(); removedEsc.add(esc); removed = true; break; } } } for (Set<ExprSpecContext> evalSet : ec.evaluableExpressions.values()) { evalSet.removeAll(removedEsc); } } } }