// When candidate table does not have the field, this method checks // if the field can be reached through reference, // if yes adds the ref usage and returns to true, if not returns false. boolean addRefUsage(CandidateTable table, String col, String srcTbl) throws LensException { // available as referenced col if (referencedCols.containsKey(col)) { for (ReferencedQueriedColumn refer : referencedCols.get(col)) { if (refer.srcTable.getName().equalsIgnoreCase(srcTbl)) { // check if reference source column is available in src table? // should not be required here. Join resolution will figure out if // there is no path // to the source table log.info("Adding denormalized column for column:{} for table:{}", col, table); Set<ReferencedQueriedColumn> refCols = tableToRefCols.get(table.getName()); if (refCols == null) { refCols = new HashSet<>(); tableToRefCols.put(table.getName(), refCols); } refCols.add(refer); // Add to optional tables for (ChainRefCol refCol : refer.col.getChainRefColumns()) { cubeql.addOptionalDimTable( refCol.getChainName(), table, false, refer.col.getName(), true, refCol.getRefColumn()); } return true; } } } return false; }
// updates all expression specs which are evaluable public void updateEvaluables(String expr, CandidateTable cTable) throws SemanticException { String alias = cubeql.getAliasForTableName(cTable.getBaseTable().getName()); ExpressionContext ec = getExpressionContext(expr, alias); if (cTable.getColumns().contains(expr)) { // expression is directly materialized in candidate table ec.addDirectlyAvailable(cTable); } for (ExprSpecContext esc : ec.allExprs) { if (esc.getTblAliasToColumns().get(alias) == null) { log.debug("{} = {} is evaluable in {}", expr, esc, cTable); ec.addEvaluable(cubeql, cTable, esc); } else { Set<String> columns = esc.getTblAliasToColumns().get(alias); boolean isEvaluable = true; for (String col : columns) { if (!cTable.getColumns().contains(col.toLowerCase())) { if (!cubeql .getDeNormCtx() .addRefUsage(cTable, col, cTable.getBaseTable().getName())) { // check if it is available as reference, if not expression is not evaluable log.debug("{} = {} is not evaluable in {}", expr, esc, cTable); isEvaluable = false; break; } } } if (isEvaluable) { log.debug("{} = {} is evaluable in {}", expr, esc, cTable); ec.addEvaluable(cubeql, cTable, esc); } } } }
private void pickExpressionsForTable(CandidateTable cTable) { for (Map.Entry<String, Set<ExpressionContext>> ecEntry : allExprsQueried.entrySet()) { Set<ExpressionContext> ecSet = ecEntry.getValue(); for (ExpressionContext ec : ecSet) { if (ec.getSrcTable().getName().equals(cTable.getBaseTable().getName())) { if (!ec.directlyAvailableIn.contains(cTable)) { if (ec.evaluableExpressions.get(cTable) != null && !ec.evaluableExpressions.get(cTable).isEmpty()) { // pick first evaluable expression Set<PickedExpression> peSet = pickedExpressions.get(ecEntry.getKey()); if (peSet == null) { peSet = new HashSet<PickedExpression>(); pickedExpressions.put(ecEntry.getKey(), peSet); } peSet.add( new PickedExpression( ec.srcAlias, ec.evaluableExpressions.get(cTable).iterator().next())); } } } } } }
// checks if expr is evaluable public boolean isEvaluable(String expr, CandidateTable cTable) { ExpressionContext ec = getExpressionContext(expr, cubeql.getAliasForTableName(cTable.getBaseTable().getName())); return ec.isEvaluable(cTable); }