private void verifyTypeOperation(Value val, Value param, boolean isNotEqual) {
    if (val.getPath() == null) return;
    PCPath path = (PCPath) val.getPath();
    Discriminator disc = ((Type) val).getDiscriminator();
    if (disc == null
        || !(val.getMetaData().getPCSuperclass() != null
            || val.getMetaData().getPCSubclasses().length > 0))
      throw new UserException(
          _loc.get(
              "invalid-type-argument",
              path.last() != null ? path.getPCPathString() : path.getSchemaAlias()));

    if (disc.getColumns().length == 0) {
      if (disc.getStrategy() instanceof NoneDiscriminatorStrategy) {
        // limited support for table per class inheritance hierarchy
        if (path.last() != null)
          throw new UserException(_loc.get("type-argument-unsupported", path.last().getName()));
        if (isNotEqual) {
          if (param != null && param instanceof Null)
            throw new UserException(
                _loc.get("type-in-expression-unsupported", path.getSchemaAlias()));
          else
            throw new UserException(_loc.get("type-not-equal-unsupported", path.getSchemaAlias()));
        }
      }
      if (param != null && param instanceof CollectionParam)
        throw new UserException(_loc.get("collection-param-unsupported"));
    }
  }
 public Expression bindKeyVariable(Value var, Value val) {
   // handle the strange case of using a constant path to bind a
   // variable; in these cases the variable acts like an unbound
   // variable that we limit by using an IN clause on the constant
   // value collection
   if (val instanceof Const) {
     PCPath path = new PCPath(_type, (Variable) var);
     path.setMetaData(var.getMetaData());
     return new InKeyExpression(path, (Const) val);
   }
   return new BindVariableExpression((Variable) var, (PCPath) val, true);
 }
  public Expression contains(Value map, Value arg) {
    if (map instanceof Const) {
      if (arg instanceof Type) {
        // limited support for table per class inheritance
        verifyTypeOperation(arg, map, false);
        if (((ClassMapping) arg.getMetaData()).getDiscriminator().getColumns().length == 0)
          return new EqualTypeExpression((Val) arg, (Val) map);
      }

      return new InExpression((Val) arg, (Const) map);
    }
    if (map instanceof SubQ) return new InSubQExpression((Val) arg, (SubQ) map);
    return new ContainsExpression((Val) map, (Val) arg);
  }