/**
  * destination table : a table whose columns are getting queried intermediate table : a table
  * which is only used as a link between cube and destination table
  *
  * @param alias
  * @param tblName
  * @param isOptional pass false when it's a destination table pass true when it's an intermediate
  *     table when join chain destination is being added, this will be false.
  * @param isChainedDimension pass true when you're adding the dimension as a joinchain
  *     destination, pass false when this table is mentioned by name in the user query
  * @return true if added
  * @throws LensException
  */
 private boolean addQueriedTable(
     String alias, String tblName, boolean isOptional, boolean isChainedDimension)
     throws LensException {
   alias = alias.toLowerCase();
   if (cubeTbls.containsKey(alias)) {
     return true;
   }
   try {
     if (metastoreClient.isCube(tblName)) {
       if (cube != null) {
         if (!cube.getName().equalsIgnoreCase(tblName)) {
           throw new LensException(
               LensCubeErrorCode.MORE_THAN_ONE_CUBE.getLensErrorInfo(), cube.getName(), tblName);
         }
       }
       cube = metastoreClient.getCube(tblName);
       cubeTbls.put(alias, (AbstractCubeTable) cube);
     } else if (metastoreClient.isDimension(tblName)) {
       Dimension dim = metastoreClient.getDimension(tblName);
       if (!isOptional) {
         dimensions.add(dim);
       }
       if (!isChainedDimension) {
         nonChainedDimensions.add(dim);
       }
       cubeTbls.put(alias, dim);
     } else {
       return false;
     }
   } catch (HiveException e) {
     return false;
   }
   return true;
 }
 public boolean hasMeasures(String expr, CubeInterface cube) {
   String alias = cubeql.getAliasForTableName(cube.getName());
   ExpressionContext ec = getExpressionContext(expr, alias);
   boolean hasMeasures = false;
   for (ExprSpecContext esc : ec.allExprs) {
     if (esc.getTblAliasToColumns().get(alias) != null) {
       for (String cubeCol : esc.getTblAliasToColumns().get(alias)) {
         if (cube.getMeasureByName(cubeCol) != null) {
           hasMeasures = true;
           break;
         }
       }
     }
   }
   ec.hasMeasures = hasMeasures;
   return hasMeasures;
 }
 public AbstractCubeTable getQueriedTable(String alias) {
   if (cube != null && cube.getName().equalsIgnoreCase(qb.getTabNameForAlias((alias)))) {
     return (AbstractCubeTable) cube;
   }
   for (Dimension dim : dimensions) {
     if (dim.getName().equalsIgnoreCase(qb.getTabNameForAlias(alias))) {
       return dim;
     }
   }
   return null;
 }
 /**
  * Figure out queried dim attributes and measures from the cube query context
  *
  * @param cubeql
  * @throws LensException
  */
 private void findDimAttributesAndMeasures(CubeQueryContext cubeql) throws LensException {
   CubeInterface cube = cubeql.getCube();
   if (cube != null) {
     Set<String> cubeColsQueried = cubeql.getColumnsQueried(cube.getName());
     Set<String> queriedDimAttrs = new HashSet<String>();
     Set<String> queriedMsrs = new HashSet<String>();
     Set<String> queriedExprs = new HashSet<String>();
     if (cubeColsQueried != null && !cubeColsQueried.isEmpty()) {
       for (String col : cubeColsQueried) {
         if (cube.getMeasureNames().contains(col)) {
           queriedMsrs.add(col);
         } else if (cube.getDimAttributeNames().contains(col)) {
           queriedDimAttrs.add(col);
         } else if (cube.getExpressionNames().contains(col)) {
           queriedExprs.add(col);
         }
       }
     }
     cubeql.addQueriedDimAttrs(queriedDimAttrs);
     cubeql.addQueriedMsrs(queriedMsrs);
     cubeql.addQueriedExprs(queriedExprs);
   }
 }
  public boolean isCubeMeasure(String col) {
    if (col == null) {
      return false;
    }

    col = col.trim();
    // Take care of brackets added around col names in HQLParsrer.getString
    if (col.startsWith("(") && col.endsWith(")") && col.length() > 2) {
      col = col.substring(1, col.length() - 1);
    }

    String[] split = StringUtils.split(col, ".");
    if (split.length <= 1) {
      col = col.trim().toLowerCase();
      if (queriedExprs.contains(col)) {
        return exprCtx
            .getExpressionContext(col, getAliasForTableName(cube.getName()))
            .hasMeasures();
      } else {
        return cube.getMeasureNames().contains(col);
      }
    } else {
      String cubeName = split[0].trim().toLowerCase();
      String colName = split[1].trim().toLowerCase();
      if (cubeName.equalsIgnoreCase(cube.getName())
          || cubeName.equals(getAliasForTableName(cube.getName()))) {
        if (queriedExprs.contains(colName)) {
          return exprCtx.getExpressionContext(colName, cubeName).hasMeasures();
        } else {
          return cube.getMeasureNames().contains(colName.toLowerCase());
        }
      } else {
        return false;
      }
    }
  }
 String getQBFromString(CandidateFact fact, Map<Dimension, CandidateDim> dimsToQuery)
     throws LensException {
   String fromString;
   if (getJoinAST() == null) {
     if (cube != null) {
       if (dimensions.size() > 0) {
         throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAILABLE.getLensErrorInfo());
       }
       fromString = fact.getStorageString(getAliasForTableName(cube.getName()));
     } else {
       if (dimensions.size() != 1) {
         throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAILABLE.getLensErrorInfo());
       }
       Dimension dim = dimensions.iterator().next();
       fromString = dimsToQuery.get(dim).getStorageString(getAliasForTableName(dim.getName()));
     }
   } else {
     StringBuilder builder = new StringBuilder();
     getQLString(qb.getQbJoinTree(), builder, fact, dimsToQuery);
     fromString = builder.toString();
   }
   return fromString;
 }