/* (non-Javadoc)
   * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
   */
  public SQLExpression getExpression(SQLExpression expr, List<SQLExpression> args) {
    if (args == null || args.size() == 0 || args.size() > 1) {
      throw new NucleusException(Localiser.msg("060016", "containsValue", "MapExpression", 1));
    }

    MapExpression mapExpr = (MapExpression) expr;
    SQLExpression valExpr = args.get(0);

    if (valExpr.isParameter()) {
      // Value is a parameter so make sure its type is set
      AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
      if (mmd != null && mmd.getMap() != null) {
        Class valCls =
            stmt.getQueryGenerator()
                .getClassLoaderResolver()
                .classForName(mmd.getMap().getValueType());
        stmt.getQueryGenerator().bindParameter(valExpr.getParameterName(), valCls);
      }
    }

    if (mapExpr instanceof MapLiteral) {
      MapLiteral lit = (MapLiteral) mapExpr;
      Map map = (Map) lit.getValue();
      if (map == null || map.size() == 0) {
        return new BooleanLiteral(stmt, expr.getJavaTypeMapping(), Boolean.FALSE);
      }

      // TODO If valExpr is a parameter and mapExpr is derived from a parameter ?
      MapValueLiteral mapValueLiteral = lit.getValueLiteral();
      BooleanExpression bExpr = null;
      List<SQLExpression> elementExprs = mapValueLiteral.getValueExpressions();
      for (int i = 0; i < elementExprs.size(); i++) {
        if (bExpr == null) {
          bExpr = (elementExprs.get(i)).eq(valExpr);
        } else {
          bExpr = bExpr.ior((elementExprs.get(i)).eq(valExpr));
        }
      }
      if (bExpr != null) {
        bExpr.encloseInParentheses();
      }
      return bExpr;
    }

    if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
      boolean needsSubquery = getNeedsSubquery();

      // TODO Check if *this* "containsValue" is negated, not any of them (and remove above check)
      if (needsSubquery) {
        NucleusLogger.QUERY.debug(
            "map.containsValue on " + mapExpr + "(" + valExpr + ") using SUBQUERY");
        return containsAsSubquery(mapExpr, valExpr);
      }
      NucleusLogger.QUERY.debug(
          "map.containsValue on " + mapExpr + "(" + valExpr + ") using INNERJOIN");
      return containsAsInnerJoin(mapExpr, valExpr);
    }
    return containsAsSubquery(mapExpr, valExpr);
  }
 /* (non-Javadoc)
  * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
  */
 public SQLExpression getExpression(SQLExpression expr, List<SQLExpression> args) {
   if (!expr.isParameter() && expr instanceof StringLiteral) {
     JavaTypeMapping m = exprFactory.getMappingForType(int.class, false);
     String val = (String) ((StringLiteral) expr).getValue();
     return new IntegerLiteral(stmt, m, Integer.valueOf(val.length()), null);
   } else if (expr instanceof StringExpression || expr instanceof ParameterLiteral) {
     ArrayList funcArgs = new ArrayList();
     funcArgs.add(expr);
     return new NumericExpression(stmt, getMappingForClass(int.class), "CHAR_LENGTH", funcArgs);
   } else {
     throw new NucleusException(Localiser.msg("060001", "length", expr));
   }
 }