@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();
                  }
                }
              }
            }
          }
        }
      }
    }
  }
 // 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);
 }