queryparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,704 行 · 第 1/5 页

JAVA
2,704
字号
    int token = scanToken();    switch (token) {    case IDENTIFIER:    case LOCATE:    case LENGTH:    case MAX:    case MIN:    case SUM:    case ABS:    case SQRT:    case MOD:    case SIZE:    case CONCAT:    case LOWER:    case UPPER:    case SUBSTRING:    case TRIM:      {        String name = _lexeme.toString();        if (peekToken() != '(') {          // Either IdExpr or EmbeddedExpr          AbstractPathExpr tableExpr = getIdentifier(name);          if (tableExpr == null) {            // jpa/0w22            tableExpr = getEmbeddedAlias(name);          }          if (tableExpr == null) {            // jpa/11z6            AmberExpr amberExpr = parseEnum(name);            if (amberExpr != null)              return amberExpr;          }          if (tableExpr != null) {            AmberExpr amberExpr = parsePath(tableExpr);            return amberExpr;          }          if (_query.getFromList().size() == 0)            throw error(L.l("Expected a FROM clause before '{0}'", name));          FromItem fromItem = _query.getFromList().get(0);          tableExpr = fromItem.getIdExpr();          AmberExpr next = tableExpr.createField(this, name);          if (next instanceof PathExpr)            return addPath((PathExpr) next);          else if (next != null)            return next;          throw error(L.l("'{0}' is an unknown table or column", name));        }        else {          name = name.toLowerCase();          // EXISTS | ALL | ANY | SOME          if (name.equals("exists") ||              name.equals("all") ||              name.equals("any") ||              name.equals("some")) {            scanToken();            if (peekToken() != SELECT && peekToken() != FROM)              throw error(L.l(name.toUpperCase() + " requires '(SELECT'"));            SelectQuery select = parseSelect(true);            if (peekToken() != ')')              throw error(L.l(name.toUpperCase() + " requires ')'"));            scanToken();            ArrayList<FromItem> parentFromList;            parentFromList = select.getParentQuery().getFromList();            // jpa/1178            select.getFromList().addAll(0, parentFromList);            if (name.equals("exists"))              return new ExistsExpr(select);            else if (name.equals("all"))              return new AllExpr(select);            else // SOME is a synonymous with ANY              return new AnyExpr(select);          }          else {            return parseFunction(name, token);          }        }      }    case CURRENT_DATE:    case CURRENT_TIME:    case CURRENT_TIMESTAMP:      {        String name = _lexeme.toString();        return parseFunction(name, token);      }    case FALSE:      return new LiteralExpr(this, _lexeme, boolean.class);    case TRUE:      return new LiteralExpr(this, _lexeme, boolean.class);    case NULL:      return new NullExpr();    case INTEGER:      return new LiteralExpr(this, _lexeme, int.class);    case LONG:      return new LiteralExpr(this, _lexeme, long.class);    case DOUBLE:      return new LiteralExpr(this, _lexeme, double.class);    case STRING:      return new LiteralExpr(this, _lexeme, String.class);    case ARG:      {        ArgExpr arg = new ArgExpr(this, Integer.parseInt(_lexeme));        /*          if (_addArgToQuery)          addArg(arg);        */        return arg;      }    case NAMED_ARG:      {        ArgExpr arg = new ArgExpr(this, _lexeme, _parameterCount);        return arg;      }      /*        case THIS:        {        if (_thisExpr == null) {        _thisExpr = new IdExpr(this, "caucho_this", _bean);        addFromItem("caucho_this", _bean.getSQLTable());        _argList.add(0, new ThisExpr(this, _bean));        }        return _thisExpr;        }      */    case '(':      AmberExpr expr = parseExpr();      if ((token = scanToken()) != ')')        throw error(L.l("expected `)' at {0}", tokenName(token)));      return expr;    default:      throw error(L.l("expected term at {0}", tokenName(token)));    }  }  /**   * Parses a path   *   * <pre>   * path ::= IDENTIFIER   *      ::= path . IDENTIFIER   * </pre>   */  private AmberExpr parsePath(PathExpr path)    throws QueryParseException  {    while (peekToken() == '.') {      scanToken();      String field = parseIdentifier();      AmberExpr next = path.createField(this, field);      if (next == null)        throw error(L.l("'{0}' does not have a field '{1}'",                        path, field));      if (! (next instanceof PathExpr))        return next;      PathExpr nextPath = addPath((PathExpr) next);      if (peekToken() == '[') {        scanToken();        AmberExpr index = parseExpr();        next = nextPath.createArray(index);        if (next == null)          throw error(L.l("'{0}' does not have a map field '{1}'",                          path, field));        if (peekToken() != ']') {          throw error(L.l("expected ']' at '{0}'", tokenName(peekToken())));        }        scanToken();      }      if (next instanceof PathExpr)        path = addPath((PathExpr) next);      else        return next;    }    return path;  }  /**   * Parses a enum value   *   * <pre>   * enum ::= (IDENTIFIER '.')+ IDENTIFIER   * </pre>   */  private EnumExpr parseEnum(String head)    throws QueryParseException  {    CharBuffer cb = CharBuffer.allocate();    int token;    while ((token = scanToken()) == '.') {      if (cb.length() > 0)        cb.append('.');      cb.append(head);      token = scanToken();      if (token != IDENTIFIER)        throw error(L.l("expected identifier for enumerated type {0} at {1}",                        cb.toString(),                        tokenName(token)));      head = _lexeme.toString();    }    int value = -1;    Class cl = null;    try {      ClassLoader loader = Thread.currentThread().getContextClassLoader();      cl = Class.forName(cb.toString(), false, loader);      Enum enumValue = Enum.valueOf(cl, head);      value = enumValue.ordinal();    } catch (ClassNotFoundException e) {      // Not an error; only this is not a enum.      // Continue - see parseSimpleTerm().      return null;    }    return new EnumExpr(cl, head, value);  }  /**   * Parses a function   *   * <pre>   * fun ::= IDENTIFIER ( expr* )   *     ::= IDENTIFIER ( DISTINCT expr* )   * </pre>   */  private AmberExpr parseFunction(String id,                                  int functionToken)    throws QueryParseException  {    // Function with no arguments.    switch (functionToken) {    case CURRENT_DATE:      return CurrentDateFunExpr.create(this);    case CURRENT_TIME:      return CurrentTimeFunExpr.create(this);    case CURRENT_TIMESTAMP:      return CurrentTimestampFunExpr.create(this);    }    // Function with arguments.    scanToken();    // Example: "'c'"    AmberExpr trimChar = null;    TrimFunExpr.TrimSemantics trimSemantics      = TrimFunExpr.TrimSemantics.BOTH;    boolean distinct = false;    ArrayList<AmberExpr> args = new ArrayList<AmberExpr>();    if (functionToken == TRIM) {      switch (peekToken()) {      case LEADING:        trimSemantics = TrimFunExpr.TrimSemantics.LEADING;        scanToken();        break;      case TRAILING:        trimSemantics = TrimFunExpr.TrimSemantics.TRAILING;        scanToken();        break;      case BOTH:        scanToken();        break;        // default: [BOTH], but no scanToken().      }      AmberExpr arg = null;      if (peekToken() != FROM) {        arg = parseExpr();        if (arg instanceof LiteralExpr) {          String v = ((LiteralExpr) arg).getValue();          if (v.length() != 3) // "'c'"            throw error(L.l("expected a single char expression for TRIM at {0}", v));        }      }      if (peekToken() == FROM) {        scanToken();        trimChar = arg;        arg = parseExpr();      }      args.add(arg);    }    else {      if (peekToken() == DISTINCT) {        distinct = true;        scanToken();      }      while ((peekToken() >= 0) && (peekToken() != ')')) {        AmberExpr arg = parseExpr();        if (id.equalsIgnoreCase("object")) {          if (arg instanceof PathExpr) {            PathExpr pathExpr = (PathExpr) arg;            arg = LoadExpr.create(pathExpr);            arg = arg.bindSelect(this);            int token = scanToken();            if (token != ')')              throw error(L.l("expected ')' at '{0}'", tokenName(token)));            return arg;          }        }        args.add(arg);        if (peekToken() != ',')          break;        scanToken();      }    }    if (peekToken() != ')')      throw error(L.l("expected ')' at '{0}'", tokenName(scanToken())));    scanToken();    FunExpr funExpr;    switch (functionToken) {    case LOCATE:      funExpr = LocateFunExpr.create(this, args);      break;    case LENGTH:      funExpr = LengthFunExpr.create(this, args);      break;    case MAX:      funExpr = MaxFunExpr.create(this, id, args, distinct);      break;    case MIN:      funExpr = MinFunExpr.create(this, id, args, distinct);      break;    case SUM:      funExpr = SumFunExpr.create(this, id, args, distinct);      break;    case ABS:      funExpr = AbsFunExpr.create(this, args);      break;    case SQRT:      funExpr = SqrtFunExpr.create(this, args);      break;    case MOD:      funExpr = ModFunExpr.create(this, args);      break;    case SIZE:      if (! (_query instanceof SelectQuery))        throw error(L.l("The SIZE() function is only supported for SELECT or subselect queries"));      // jpa/119l      AmberExpr arg = args.get(0);      if (arg instanceof ManyToOneExpr) {        // @ManyToMany        arg = ((ManyToOneExpr) arg).getParent();      }      if (! (arg instanceof OneToManyExpr))        throw error(L.l("The SIZE() function is only supported for @ManyToMany or @OneToMany relationships. The argument '{0}' is not supported.", args.get(0)));      OneToManyExpr oneToMany = (OneToManyExpr) arg;      _groupList = new ArrayList<AmberExpr>();      LinkColumns linkColumns = oneToMany.getLinkColumns();      ForeignColumn fkColumn = linkColumns.getColumns().get(0);      AmberExpr groupExpr = oneToMany.getParent();      if (groupExpr instanceof PathExpr) {        // jpa/119n        PathExpr pathExpr = (PathExpr) groupExpr;        groupExpr = LoadExpr.create(pathExpr);        groupExpr = groupExpr.bindSelect(this);      }      // groupExpr = new ColumnExpr(oneToMany.getParent(),      //                            fkColumn.getTargetColumn());      _groupList.add(groupExpr);      ((SelectQuery) _query).setGroupList(_groupList);      funExpr = SizeFunExpr.create(this, args);      // jpa/1199, jpa/119l      if (! _parsingResult) {        if (_query instanceof SelectQuery) {          SelectQuery query = (SelectQuery) _query;          ArrayList<AmberExpr> resultList = query.getResultList();          for (AmberExpr expr : resultList) {            if (expr instanceof SizeFunExpr) {              SizeFunExpr sizeFun = (SizeFunExpr) expr;              AmberExpr amberExpr = sizeFun.getArgs().get(0);              // @ManyToMany              if (amberExpr instanceof ManyToOneExpr) {                amberExpr = ((ManyToOneExpr) amberExpr).getParent();              }              if (amberExpr.equals(arg))                args.set(0, amberExpr);            }          }        }        if (_appendResultList == null)          _appendResultList = new ArrayList<AmberExpr>();        _appendResultList.add(funExpr.bindSelect(this));        _isSizeFunExpr = true;      }      break;    case CONCAT:      funExpr = ConcatFunExpr.create(this, args);      break;    case LOWER:      funExpr = LowerFunExpr.create(this, args);      break;    case UPPER:      funExpr = UpperFunExpr.create(this, args);      break;    case SUBSTRING:      funExpr = SubstringFunExpr.create(this, args);      break;    case TRIM:      {        TrimFunExpr trimFunExpr = TrimFunExpr.create(this, args);        trimFunExpr.setTrimChar(trimChar);        trimFunExpr.setTrimSemantics(trimSemantics);        funExpr = trimFunExpr;        break;      }    default:      funExpr = FunExpr.create(this, id, args, distinct);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?