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