queryparser.java

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

JAVA
2,704
字号
    }    return funExpr;  }  /**   * Returns the matching identifier.   */  private IdExpr getIdentifier(String name)    throws QueryParseException  {    AbstractQuery query = _query;    for (; query != null; query = query.getParentQuery()) {      ArrayList<FromItem> fromList = query.getFromList();      for (int i = 0; i < fromList.size(); i++) {        FromItem from = fromList.get(i);        if (from.getName().equalsIgnoreCase(name))          return from.getIdExpr();      }    }    return null;    // throw error(L.l("`{0}' is an unknown table", name));  }  /**   * Returns the matching embedded alias.   */  private EmbeddedExpr getEmbeddedAlias(String name)    throws QueryParseException  {    // jpa/0w22    AbstractQuery query = _query;    for (; query != null; query = query.getParentQuery()) {      HashMap<String, EmbeddedExpr> embeddedAliases =        query.getEmbeddedAliases();      for (Map.Entry<String, EmbeddedExpr> entry :             embeddedAliases.entrySet()) {        if (entry.getKey().equalsIgnoreCase(name))          return entry.getValue();      }    }    return null;  }  /**   * Returns true if expr is a collection.   */  private boolean isCollectionExpr(AmberExpr expr)  {    // jpa/10a2    // ManyToMany is implemented as a    // ManyToOne[embeddeding OneToMany]    if ((expr instanceof ManyToOneExpr) &&        (((ManyToOneExpr) expr).getParent() instanceof OneToManyExpr))      return true;    else if (expr instanceof OneToManyExpr)      return true;    else if (expr instanceof CollectionIdExpr)      return true;    return false;  }  /**   * Returns true if expr1 and expr2 are compatible.   */  private boolean isCompatibleExpression(AmberExpr expr1, AmberExpr expr2)  {    // XXX: jpa/106a    if (expr1 instanceof LiteralExpr) {      if (expr2 instanceof LiteralExpr) {        Class javaType1 = ((LiteralExpr) expr1).getJavaType();        Class javaType2 = ((LiteralExpr) expr2).getJavaType();        if (javaType1.isAssignableFrom(javaType2))          return true;        return false;      }    }    return true;  }  /**   * Parses an identifier.   */  private String parseIdentifier()    throws QueryParseException  {    int token = scanToken();    String identifier = _lexeme;    // Resolves ambiguous identifiers:    // 1. 'order': "SELECT o FROM Order o"    if (token == ORDER) {      int parseIndex = _parseIndex;      scanToken();      if (peekToken() != BY) {        token = IDENTIFIER;        // Restores parse index right after ORDER BY.        _parseIndex = parseIndex;        _lexeme = identifier;        _token = -1;      }    } // 2. 'member': "SELECT m FROM Member m" (jpa/0x02)    else if (_parsingFrom && token == MEMBER) {      token = IDENTIFIER;    }    if (token != IDENTIFIER) {      throw error(L.l("expected identifier at `{0}'", tokenName(token)));    }    return identifier;  }  /**   * Peeks the next token   *   * @return integer code for the token   */  private int peekToken()    throws QueryParseException  {    if (_token > 0)      return _token;    _token = scanToken();    return _token;  }  /**   * Scan the next token.  If the lexeme is a string, its string   * representation is in "lexeme".   *   * @return integer code for the token   */  private int scanToken()    throws QueryParseException  {    if (_token > 0) {      int value = _token;      _token = -1;      return value;    }    int sign = 1;    int ch;    for (ch = read(); Character.isWhitespace((char) ch); ch = read()) {    }    switch (ch) {    case -1:    case '.':    case '*':    case '/':    case ',':    case '+':    case '-':    case '[':    case ']':      return ch;    case '(':      _depth++;      return ch;    case ')':      _depth--;      return ch;    case '=':      if ((ch = read()) == '>')        return EXTERNAL_DOT;      else {        unread(ch);        return EQ;      }    case '!':      if ((ch = read()) == '=')        return NE;      else {        unread(ch);        return '!';      }    case '<':      if ((ch = read()) == '=')        return LE;      else if (ch == '>')        return NE;      else {        unread(ch);        return LT;      }    case '>':      if ((ch = read()) == '=')        return GE;      else {        unread(ch);        return GT;      }    case '?':      CharBuffer cb = CharBuffer.allocate();      int index = 0;      for (ch = read(); ch >= '0' && ch <= '9'; ch = read()) {        cb.append((char) ch);        index = 10 * index + ch - '0';      }      unread(ch);      _lexeme = cb.close();      if (_lexeme.length() == 0) {        _lexeme = String.valueOf(++_parameterCount);      }      else if (index <= 0)        throw error(L.l("`{0}' must refer to a positive argument",                        "?" + _lexeme));      return ARG;    case ':':      if (Character.isJavaIdentifierStart((char) (ch = read()))) {        cb = CharBuffer.allocate();        for (; ch > 0 && Character.isJavaIdentifierPart((char) ch); ch = read())          cb.append((char) ch);        unread(ch);        _lexeme = cb.close();        _parameterCount++;      }      else        throw error(L.l("`{0}' must be a valid parameter identifier",                        ":" + ((char) ch)));      return NAMED_ARG;    case '|':      if ((ch = read()) == '|')        return CONCAT_OP;      else        throw error(L.l("unexpected char at {0}", String.valueOf((char) ch)));    // @@ is useless?    case '@':      if ((ch = read()) != '@')        throw error(L.l("`@' expected at {0}", charName(ch)));      return scanToken();    }    if (Character.isJavaIdentifierStart((char) ch)) {      CharBuffer cb = CharBuffer.allocate();      for (; ch > 0 && Character.isJavaIdentifierPart((char) ch); ch = read())        cb.append((char) ch);      unread(ch);      _lexeme = cb.close();      String lower = _lexeme.toLowerCase();      int token = _reserved.get(lower);      if (token > 0)        return token;      else        return IDENTIFIER;    }    else if (ch >= '0' && ch <= '9') {      CharBuffer cb = CharBuffer.allocate();      int type = INTEGER;      if (sign < 0)        cb.append('-');      for (; ch >= '0' && ch <= '9'; ch = read())        cb.append((char) ch);      if (ch == '.') {        type = DOUBLE;        cb.append('.');        for (ch = read(); ch >= '0' && ch <= '9'; ch = read())          cb.append((char) ch);      }      if (ch == 'e' || ch == 'E') {        type = DOUBLE;        cb.append('e');        if ((ch = read()) == '+' || ch == '-') {          cb.append((char) ch);          ch = read();        }        if (! (ch >= '0' && ch <= '9'))          throw error(L.l("exponent needs digits at {0}",                          charName(ch)));        for (; ch >= '0' && ch <= '9'; ch = read())          cb.append((char) ch);      }      if (ch == 'F' || ch == 'D')        type = DOUBLE;      else if (ch == 'L') {        type = LONG;      }      else        unread(ch);      _lexeme = cb.close();      return type;    }    else if (ch == '\'') {      CharBuffer cb = CharBuffer.allocate();      cb.append("'");      for (ch = read(); ch >= 0; ch = read()) {        if (ch == '\'') {          if ((ch = read()) == '\'')            cb.append("''");          else {            unread(ch);            break;          }        }        else          cb.append((char) ch);      }      cb.append("'");      _lexeme = cb.close();      return STRING;    }    throw error(L.l("unexpected char at {0}", "" + (char) ch));  }  /**   * Returns the next character.   */  private int read()  {    if (_parseIndex < _sql.length())      return _sql.charAt(_parseIndex++);    else      return -1;  }  /**   * Unread the last character.   */  private void unread(int ch)  {    if (ch >= 0)      _parseIndex--;  }  /**   * Returns the jdbc meta data, if available.   */  private JdbcMetaData getMetaData()  {    if (_persistenceUnit == null)      return null;    return _persistenceUnit.getMetaData();  }  /**   * Creates an error.   */  public QueryParseException error(String msg)  {    msg += "\nin \"" + _sql + "\"";    return new QueryParseException(msg);  }  /**   * Returns the name for a character   */  private String charName(int ch)  {    if (ch < 0)      return L.l("end of query");    else      return String.valueOf((char) ch);  }  /**   * Returns the name of a token   */  private String tokenName(int token)  {    switch (token) {    case AS: return "AS";    case FROM: return "FROM";    case IN: return "IN";    case SELECT: return "SELECT";    case WHERE: return "WHERE";    case OR: return "OR";    case AND: return "AND";    case NOT: return "NOT";    case BETWEEN: return "BETWEEN";    case THIS: return "THIS";    case TRUE: return "FALSE";    case EMPTY: return "EMPTY";    case MEMBER: return "MEMBER";    case OF: return "OF";    case NULL: return "NULL";    case ORDER: return "ORDER";    case BY: return "BY";    case ASC: return "ASC";    case DESC: return "DESC";    case LIMIT: return "LIMIT";    case EXTERNAL_DOT: return "=>";    case -1:      return L.l("end of query");    default:      if (token < 128)        return "'" + String.valueOf((char) token) + "'";      else        return "'" + _lexeme + "'";    }  }  /**   * Returns a debuggable description of the select.   */  public String toString()  {    return "QueryParser[]";  }  static {    _reserved = new IntMap();    _reserved.put("as", AS);    _reserved.put("from", FROM);    _reserved.put("in", IN);    _reserved.put("select", SELECT);    _reserved.put("update", UPDATE);    _reserved.put("delete", DELETE);    _reserved.put("set", SET);    _reserved.put("distinct", DISTINCT);    _reserved.put("where", WHERE);    _reserved.put("order", ORDER);    _reserved.put("group", GROUP);    _reserved.put("by", BY);    _reserved.put("having", HAVING);    _reserved.put("asc", ASC);    _reserved.put("desc", DESC);    _reserved.put("limit", LIMIT);    _reserved.put("offset", OFFSET);    _reserved.put("join", JOIN);    _reserved.put("inner", INNER);    _reserved.put("left", LEFT);    _reserved.put("outer", OUTER);    _reserved.put("fetch", FETCH);    _reserved.put("or", OR);    _reserved.put("and", AND);    _reserved.put("not", NOT);    _reserved.put("length", LENGTH);    _reserved.put("locate", LOCATE);    _reserved.put("abs", ABS);    _reserved.put("sqrt", SQRT);    _reserved.put("mod", MOD);    _reserved.put("size", SIZE);    _reserved.put("max", MAX);    _reserved.put("min", MIN);    _reserved.put("sum", SUM);    _reserved.put("concat", CONCAT);    _reserved.put("lower", LOWER);    _reserved.put("upper", UPPER);    _reserved.put("substring", SUBSTRING);    _reserved.put("trim", TRIM);    _reserved.put("both", BOTH);    _reserved.put("leading", LEADING);    _reserved.put("trailing", TRAILING);    _reserved.put("current_date", CURRENT_DATE);    _reserved.put("current_time", CURRENT_TIME);    _reserved.put("current_timestamp", CURRENT_TIMESTAMP);    _reserved.put("between", BETWEEN);    _reserved.put("like", LIKE);    _reserved.put("escape", ESCAPE);    _reserved.put("is", IS);    _reserved.put("new", NEW);    _reserved.put("this", THIS);    _reserved.put("true", TRUE);    _reserved.put("false", FALSE);    _reserved.put("unknown", UNKNOWN);    _reserved.put("empty", EMPTY);    _reserved.put("member", MEMBER);    _reserved.put("of", OF);    _reserved.put("null", NULL);  }}

⌨️ 快捷键说明

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