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 + -
显示快捷键?