public Set<Dimension> rewriteDenormctx( CandidateFact cfact, Map<Dimension, CandidateDim> dimsToQuery, boolean replaceFact) throws LensException { Set<Dimension> refTbls = new HashSet<>(); if (!tableToRefCols.isEmpty()) { // pick referenced columns for fact if (cfact != null) { pickColumnsForTable(cfact.getName()); } // pick referenced columns for dimensions if (dimsToQuery != null && !dimsToQuery.isEmpty()) { for (CandidateDim cdim : dimsToQuery.values()) { pickColumnsForTable(cdim.getName()); } } // Replace picked reference in all the base trees replaceReferencedColumns(cfact, replaceFact); // Add the picked references to dimsToQuery for (PickedReference picked : pickedRefs) { if (isPickedFor(picked, cfact, dimsToQuery)) { refTbls.add( (Dimension) cubeql.getCubeTableForAlias(picked.getChainRef().getChainName())); cubeql.addColumnsQueried( picked.getChainRef().getChainName(), picked.getChainRef().getRefColumn()); } } } return refTbls; }
// checks if the reference if picked for facts and dimsToQuery passed private boolean isPickedFor( PickedReference picked, CandidateFact cfact, Map<Dimension, CandidateDim> dimsToQuery) { if (cfact != null && picked.pickedFor.equalsIgnoreCase(cfact.getName())) { return true; } if (dimsToQuery != null) { for (CandidateDim cdim : dimsToQuery.values()) { if (picked.pickedFor.equalsIgnoreCase(cdim.getName())) { return true; } } } return false; }
/** * Find all de-normalized columns, if these columns are not directly available in candidate * tables, query will be replaced with the corresponding table reference */ @Override public void rewriteContext(CubeQueryContext cubeql) throws LensException { DenormalizationContext denormCtx = cubeql.getDeNormCtx(); if (denormCtx == null) { // Adds all the reference dimensions as eligible for denorm fields denormCtx = new DenormalizationContext(cubeql); cubeql.setDeNormCtx(denormCtx); // add ref columns in cube addRefColsQueried(cubeql, cubeql, denormCtx); // add ref columns from expressions for (Set<ExpressionContext> ecSet : cubeql.getExprCtx().getAllExprsQueried().values()) { for (ExpressionContext ec : ecSet) { for (ExprSpecContext esc : ec.getAllExprs()) { addRefColsQueried(cubeql, esc, denormCtx); } } } } else if (!denormCtx.tableToRefCols.isEmpty()) { // In the second iteration of denorm resolver // candidate tables which require denorm fields and the refernces are no // more valid will be pruned if (cubeql.getCube() != null && !cubeql.getCandidateFacts().isEmpty()) { for (Iterator<CandidateFact> i = cubeql.getCandidateFacts().iterator(); i.hasNext(); ) { CandidateFact cfact = i.next(); if (denormCtx.tableToRefCols.containsKey(cfact.getName())) { for (ReferencedQueriedColumn refcol : denormCtx.tableToRefCols.get(cfact.getName())) { if (denormCtx.getReferencedCols().get(refcol.col.getName()).isEmpty()) { log.info( "Not considering fact table:{} as column {} is not available", cfact, refcol.col); cubeql.addFactPruningMsgs( cfact.fact, CandidateTablePruneCause.columnNotFound(refcol.col.getName())); i.remove(); } } } } if (cubeql.getCandidateFacts().size() == 0) { throw new LensException( LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), cubeql.getColumnsQueried(cubeql.getCube().getName()).toString()); } cubeql.pruneCandidateFactSet(CandidateTablePruneCode.COLUMN_NOT_FOUND); } if (cubeql.getDimensions() != null && !cubeql.getDimensions().isEmpty()) { for (Dimension dim : cubeql.getDimensions()) { for (Iterator<CandidateDim> i = cubeql.getCandidateDimTables().get(dim).iterator(); i.hasNext(); ) { CandidateDim cdim = i.next(); if (denormCtx.tableToRefCols.containsKey(cdim.getName())) { for (ReferencedQueriedColumn refcol : denormCtx.tableToRefCols.get(cdim.getName())) { if (denormCtx.getReferencedCols().get(refcol.col.getName()).isEmpty()) { log.info( "Not considering dim table:{} as column {} is not available", cdim, refcol.col); cubeql.addDimPruningMsgs( dim, cdim.dimtable, CandidateTablePruneCause.columnNotFound(refcol.col.getName())); i.remove(); } } } } if (cubeql.getCandidateDimTables().get(dim).size() == 0) { throw new LensException( LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.toString(), cubeql.getColumnsQueried(dim.getName()).toString()); } } } } }
@Override public void rewriteContext(CubeQueryContext cubeql) throws SemanticException { ExpressionResolverContext exprCtx = cubeql.getExprCtx(); if (exprCtx == null) { exprCtx = new ExpressionResolverContext(cubeql); cubeql.setExprCtx(exprCtx); for (Map.Entry<String, Set<String>> entry : cubeql.getTblAliasToColumns().entrySet()) { String alias = entry.getKey(); // skip default alias if (alias == CubeQueryContext.DEFAULT_TABLE) { continue; } AbstractCubeTable tbl = cubeql.getCubeTableForAlias(alias); Set<String> columns = entry.getValue(); for (String column : columns) { CubeColumn col; if (tbl instanceof CubeInterface) { col = ((CubeInterface) tbl).getColumnByName(column); } else { col = ((Dimension) tbl).getColumnByName(column); } if (col instanceof ExprColumn) { exprCtx.addExpressionQueried( new ExpressionContext(cubeql, (ExprColumn) col, (AbstractBaseTable) tbl, alias)); } } } Set<String> exprsWithMeasures = new HashSet<String>(); for (String expr : cubeql.getQueriedExprs()) { if (cubeql.getExprCtx().hasMeasures(expr, cubeql.getCube())) { // expression has measures exprsWithMeasures.add(expr); } } cubeql.addQueriedExprsWithMeasures(exprsWithMeasures); } else { // prune invalid expressions cubeql.getExprCtx().pruneExpressions(); // prune candidate facts without any valid expressions if (cubeql.getCube() != null && !cubeql.getCandidateFacts().isEmpty()) { for (Map.Entry<String, Set<ExpressionContext>> ecEntry : exprCtx.allExprsQueried.entrySet()) { String expr = ecEntry.getKey(); Set<ExpressionContext> ecSet = ecEntry.getValue(); for (ExpressionContext ec : ecSet) { if (ec.getSrcTable().getName().equals(cubeql.getCube().getName())) { if (cubeql.getQueriedExprsWithMeasures().contains(expr)) { for (Iterator<Set<CandidateFact>> sItr = cubeql.getCandidateFactSets().iterator(); sItr.hasNext(); ) { Set<CandidateFact> factSet = sItr.next(); boolean evaluableInSet = false; for (CandidateFact cfact : factSet) { if (ec.isEvaluable(cfact)) { evaluableInSet = true; } } if (!evaluableInSet) { log.info( "Not considering fact table set:{} as {} is not evaluable", factSet, ec.exprCol.getName()); sItr.remove(); } } } else { for (Iterator<CandidateFact> i = cubeql.getCandidateFacts().iterator(); i.hasNext(); ) { CandidateFact cfact = i.next(); if (!ec.isEvaluable(cfact)) { log.info( "Not considering fact table:{} as {} is not evaluable", cfact, ec.exprCol.getName()); cubeql.addFactPruningMsgs( cfact.fact, CandidateTablePruneCause.expressionNotEvaluable(ec.exprCol.getName())); i.remove(); } } } } } } cubeql.pruneCandidateFactWithCandidateSet(CandidateTablePruneCode.EXPRESSION_NOT_EVALUABLE); } // prune candidate dims without any valid expressions if (cubeql.getDimensions() != null && !cubeql.getDimensions().isEmpty()) { for (Dimension dim : cubeql.getDimensions()) { for (Iterator<CandidateDim> i = cubeql.getCandidateDimTables().get(dim).iterator(); i.hasNext(); ) { CandidateDim cdim = i.next(); for (Map.Entry<String, Set<ExpressionContext>> ecEntry : exprCtx.allExprsQueried.entrySet()) { Set<ExpressionContext> ecSet = ecEntry.getValue(); for (ExpressionContext ec : ecSet) { if (ec.getSrcTable().getName().equals(cdim.getBaseTable().getName())) { if (!ec.isEvaluable(cdim)) { log.info( "Not considering dim table:{} as {} is not evaluable", cdim, ec.exprCol.getName()); cubeql.addDimPruningMsgs( dim, cdim.dimtable, CandidateTablePruneCause.expressionNotEvaluable(ec.exprCol.getName())); i.remove(); } } } } } } } } }