queryparser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,704 行 · 第 1/5 页
JAVA
2,704 行
} /** * Adds an entity path */ public PathExpr addPath(PathExpr path) { PathExpr oldPath = _pathMap.get(path); if (oldPath != null) return oldPath; _pathMap.put(path, path); return path; } /** * Adds a new argument */ public void addArg(ArgExpr arg) { _argList.add(arg); } /** * Parses a schema. */ private SchemaExpr parseSchema() throws QueryParseException { int token = peekToken(); boolean isIn = token == IN; if (isIn) { scanToken(); _joinSemantics = FromItem.JoinSemantics.INNER; if ((token = scanToken()) != '(') throw error(L.l("expected '(' at '{0}'", tokenName(token))); } String name = parseIdentifier(); SchemaExpr schema = null; if (! isIn) { AmberEntityHome home = _persistenceUnit.getHomeBySchema(name); if (home != null) { EntityType type = home.getEntityType(); schema = new TableIdExpr(home.getEntityType(), type.getTable().getName()); } } IdExpr id = null; if (schema == null) { id = getIdentifier(name); if (id != null) schema = new FromIdSchemaExpr(id); } if (! isIn && schema == null) { while (peekToken() == '.') { scanToken(); String segment = parseIdentifier(); name = name + '.' + segment; AmberEntityHome home = _persistenceUnit.getHomeBySchema(name); if (home != null) { schema = new TableIdExpr(home.getEntityType(), name); break; } } } if (schema == null) { throw error(L.l("'{0}' is an unknown entity.", name)); } name = ""; boolean isFirst = true; while (peekToken() == '.') { scanToken(); String segment = parseIdentifier(); if (isFirst) { name += segment; isFirst = false; } else name += "." + segment; schema = schema.createField(this, segment); } if (_isJoinFetch && (! name.equals(""))) { _joinFetchMap.put(id, name); } if (isIn) { if ((token = scanToken()) != ')') throw error(L.l("expected ')' at '{0}'", tokenName(token))); } return schema; } /** * Parses an expression. */ private AmberExpr parseExpr() throws QueryParseException { if (peekToken() == SELECT) { SelectQuery select = parseSelect(true); return new SubSelectExpr(select); } AmberExpr expr = parseOrExpr(); return expr; // .bindSelect(this); } /** * Parses an or expression. */ private AmberExpr parseOrExpr() throws QueryParseException { AmberExpr expr = parseAndExpr(); OrExpr orExpr = null; while (peekToken() == OR) { scanToken(); if (orExpr == null) { orExpr = new OrExpr(); orExpr.add(expr); } AmberExpr andExpr = parseAndExpr(); if (andExpr == null) continue; orExpr.add(andExpr); } return orExpr == null ? expr : orExpr; } /** * Parses an and expression. */ private AmberExpr parseAndExpr() throws QueryParseException { AmberExpr expr = parseNotExpr(); AndExpr andExpr = null; while (peekToken() == AND) { scanToken(); if (andExpr == null) { andExpr = new AndExpr(); andExpr.add(expr); } AmberExpr notExpr = parseNotExpr(); if (notExpr == null) continue; andExpr.add(notExpr); } return andExpr == null ? expr : andExpr; } /** * Parses a NOT expression. * */ private AmberExpr parseNotExpr() throws QueryParseException { AmberExpr expr; if (peekToken() == NOT) { scanToken(); expr = new UnaryExpr(NOT, parseCmpExpr()); } else expr = parseCmpExpr(); // jpa/1199, jpa/119l if (_parsingResult || _parsingHaving) return expr; if (! _isSizeFunExpr) return expr; if (_havingExpr == null) { _havingExpr = expr; } else if (expr != null) { // jpa/1199 _havingExpr = AndExpr.create(_havingExpr, expr); } return null; } /** * Parses a comparison expression. * * <pre> * cmp-expr ::= add-expr '=' add-expr is-term? * ::= add-expr 'NOT'? 'BETWEEN' add-expr 'AND' add-expr is-term? * ::= add-expr 'NOT'? 'LIKE' string ('ESCAPE' string)? is-term? * ::= add-expr 'NOT'? 'IN' ('lit-1', ..., 'lit-n') * ::= add-expr * </pre> * * @return the parsed expression */ private AmberExpr parseCmpExpr() throws QueryParseException { AmberExpr expr = parseConcatExpr(); int token = peekToken(); boolean isNot = false; if (token == NOT) { scanToken(); isNot = true; token = peekToken(); if (token != BETWEEN && token != LIKE && token != MEMBER && token != IN) throw error(L.l("'NOT' is not expected here.")); } if (token >= EQ && token <= GE) { scanToken(); AmberExpr concatExpr = parseConcatExpr(); return parseIs(new BinaryExpr(token, expr, concatExpr)); } else if (token == BETWEEN) { scanToken(); AmberExpr min = parseConcatExpr(); if ((token = scanToken()) != AND) throw error(L.l("Expected 'AND' at {0}", tokenName(token))); AmberExpr max = parseConcatExpr(); // jpa/106a if (! isCompatibleExpression(expr, min)) throw error(L.l("Expected compatible expression at {0} BETWEEN {1}", expr, min)); if (! isCompatibleExpression(expr, max)) throw error(L.l("Expected compatible expression at BETWEEN {0} AND {1}", min, max)); return new BetweenExpr(expr, min, max, isNot); } else if (token == LIKE) { scanToken(); AmberExpr pattern = parseConcatExpr(); // jpa/1075 if (pattern instanceof LiteralExpr) { LiteralExpr literalExpr = (LiteralExpr) pattern; if (literalExpr.getJavaType() != String.class) throw error(L.l("Expected string at {0}", pattern)); } else if (! (pattern instanceof ArgExpr)) // jpa/1076 throw error(L.l("Expected string at {0}", pattern)); String escape = null; if (peekToken() == ESCAPE) { scanToken(); if ((token = scanToken()) != STRING) throw error(L.l("Expected string at {0}", tokenName(token))); escape = _lexeme.toString(); } return parseIs(new LikeExpr(expr, pattern, escape, isNot)); } else if (token == IN) { scanToken(); token = scanToken(); if (token != '(') throw error(L.l("Expected '(' after IN at {0}", tokenName(token))); ArrayList<AmberExpr> args = new ArrayList<AmberExpr>(); while ((token = peekToken()) > 0 && token != ')') { AmberExpr arg = parseExpr(); args.add(arg); token = peekToken(); if (token == ',') { scanToken(); token = peekToken(); } } if (peekToken() != ')') throw error(L.l("Expected ')' after IN at {0}", tokenName(token))); scanToken(); if (expr instanceof IdExpr) { IdExpr idExpr = (IdExpr) expr; // jpa/1174 if (idExpr.getFromItem().isEntityType()) throw error(L.l("Unexpected entity at '{0} IN'", expr)); } return new InExpr(expr, args, isNot); } else if (token == MEMBER) { scanToken(); token = peekToken(); if (token == OF) token = scanToken(); AmberExpr collection = parseExpr(); // jpa/10c8 if (expr instanceof ArgExpr) { addArg((ArgExpr) expr); } else if (! (expr instanceof PathExpr)) throw error(L.l("MEMBER OF requires an entity-valued item.")); if (! isCollectionExpr(collection)) throw error(L.l("MEMBER OF requires an entity-valued collection at '{0}'.", collection.getClass().getName())); return parseIs(MemberExpr.create(this, expr, collection, isNot)); } else return parseIs(expr); } private AmberExpr parseIs(AmberExpr expr) throws QueryParseException { int token = peekToken(); if (token != IS) return expr; scanToken(); boolean isNot = false; token = scanToken(); if (token == NOT) { isNot = true; token = scanToken(); } if (token == NULL) { if (expr instanceof KeyColumnExpr) expr = ((KeyColumnExpr) expr).getParent(); else if (expr instanceof IdExpr) { IdExpr idExpr = (IdExpr) expr; // jpa/1093 if (idExpr.getFromItem().isEntityType()) throw error(L.l("Unexpected entity at '{0} IS'", expr)); } if (isNot) return new UnaryExpr(NOT_NULL, expr); else return new UnaryExpr(NULL, expr); } else if (token == EMPTY) { if (! isCollectionExpr(expr)) throw error(L.l("IS EMPTY requires an entity-valued collection at '{0}'.", expr.getClass().getName())); expr = new EmptyExpr(expr); if (! isNot) expr = new UnaryExpr(NOT, expr); return expr; } else throw error(L.l("expected NULL at '{0}'", tokenName(token))); } /** * Parses a concat expression. */ private AmberExpr parseConcatExpr() throws QueryParseException { AmberExpr expr = parseAddExpr(); while (true) { int token = peekToken(); switch (token) { case CONCAT_OP: scanToken(); ArrayList<AmberExpr> args = new ArrayList<AmberExpr>(); args.add(expr); args.add(parseAddExpr()); expr = ConcatFunExpr.create(this, args); break; default: return expr; } } } /** * Parses an add expression. */ private AmberExpr parseAddExpr() throws QueryParseException { AmberExpr expr = parseMulExpr(); while (true) { int token = peekToken(); switch (token) { case '+': case '-': scanToken(); expr = new BinaryExpr(token, expr, parseMulExpr()); break; default: return expr; } } } /** * Parses a mul expression. */ private AmberExpr parseMulExpr() throws QueryParseException { AmberExpr expr = parseTerm(); while (true) { int token = peekToken(); switch (token) { case '*': case '/': scanToken(); expr = new BinaryExpr(token, expr, parseTerm()); break; default: return expr; } } } /** * Parses a term * * <pre> * term ::= - term * ::= + term * ::= NOT term * </pre> */ private AmberExpr parseTerm() throws QueryParseException { int token = peekToken(); switch (token) { case '+': case '-': case NOT: scanToken(); return new UnaryExpr(token, parseTerm()); default: return parseSimpleTerm(); } } /** * Parses a simple term * * <pre> * term ::= INTEGER | LONG | DOUBLE | STRING * ::= THIS * ::= IDENTIFIER * ::= IDENTIFIER '(' args ')' * ::= '(' expr ')' * </pre> */ private AmberExpr parseSimpleTerm() throws QueryParseException {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?