@Override public boolean visit(MySqlMatchAgainstExpr x) { print("MATCH ("); printAndAccept(x.getColumns(), ", "); print(")"); print(" AGAINST ("); x.getAgainst().accept(this); if (x.getSearchModifier() != null) { print(' '); print(x.getSearchModifier().name); } print(')'); return false; }
public final SQLExpr primaryRest(SQLExpr expr) { if (expr == null) { throw new IllegalArgumentException("expr"); } if (lexer.token() == Token.LITERAL_CHARS) { if (expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr; String ident = identExpr.getName(); if (ident.equalsIgnoreCase("x")) { String charValue = lexer.stringVal(); lexer.nextToken(); expr = new SQLHexExpr(charValue); return primaryRest(expr); } else if (ident.equalsIgnoreCase("b")) { String charValue = lexer.stringVal(); lexer.nextToken(); expr = new SQLBinaryExpr(charValue); return primaryRest(expr); } else if (ident.startsWith("_")) { String charValue = lexer.stringVal(); lexer.nextToken(); MySqlCharExpr mysqlCharExpr = new MySqlCharExpr(charValue); mysqlCharExpr.setCharset(identExpr.getName()); if (identifierEquals("COLLATE")) { lexer.nextToken(); String collate = lexer.stringVal(); mysqlCharExpr.setCollate(collate); accept(Token.IDENTIFIER); } expr = mysqlCharExpr; return primaryRest(expr); } } else if (expr instanceof SQLCharExpr) { SQLMethodInvokeExpr concat = new SQLMethodInvokeExpr("CONCAT"); concat.addParameter(expr); do { String chars = lexer.stringVal(); concat.addParameter(new SQLCharExpr(chars)); lexer.nextToken(); } while (lexer.token() == Token.LITERAL_CHARS || lexer.token() == Token.LITERAL_ALIAS); expr = concat; } } else if (lexer.token() == Token.IDENTIFIER) { if (expr instanceof SQLHexExpr) { if ("USING".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { throw new ParserException("syntax error, illegal hex"); } String charSet = lexer.stringVal(); lexer.nextToken(); expr.getAttributes().put("USING", charSet); return primaryRest(expr); } } else if ("COLLATE".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); if (lexer.token() == Token.EQ) { lexer.nextToken(); } if (lexer.token() != Token.IDENTIFIER) { throw new ParserException("syntax error"); } String collate = lexer.stringVal(); lexer.nextToken(); SQLBinaryOpExpr binaryExpr = new SQLBinaryOpExpr( expr, SQLBinaryOperator.COLLATE, new SQLIdentifierExpr(collate), JdbcConstants.MYSQL); expr = binaryExpr; return primaryRest(expr); } else if (expr instanceof SQLVariantRefExpr) { if ("COLLATE".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { throw new ParserException("syntax error"); } String collate = lexer.stringVal(); lexer.nextToken(); expr.putAttribute("COLLATE", collate); return primaryRest(expr); } } else if (expr instanceof SQLIntegerExpr) { SQLIntegerExpr intExpr = (SQLIntegerExpr) expr; String binaryString = lexer.stringVal(); if (intExpr.getNumber().intValue() == 0 && binaryString.startsWith("b")) { lexer.nextToken(); expr = new SQLBinaryExpr(binaryString.substring(1)); return primaryRest(expr); } } } if (lexer.token() == Token.LPAREN && expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr; String ident = identExpr.getName(); if ("EXTRACT".equalsIgnoreCase(ident)) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { throw new ParserException("syntax error"); } String unitVal = lexer.stringVal(); MySqlIntervalUnit unit = MySqlIntervalUnit.valueOf(unitVal.toUpperCase()); lexer.nextToken(); accept(Token.FROM); SQLExpr value = expr(); MySqlExtractExpr extract = new MySqlExtractExpr(); extract.setValue(value); extract.setUnit(unit); accept(Token.RPAREN); expr = extract; return primaryRest(expr); } else if ("SUBSTRING".equalsIgnoreCase(ident)) { lexer.nextToken(); SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident); for (; ; ) { SQLExpr param = expr(); methodInvokeExpr.addParameter(param); if (lexer.token() == Token.COMMA) { lexer.nextToken(); continue; } else if (lexer.token() == Token.FROM) { lexer.nextToken(); SQLExpr from = expr(); methodInvokeExpr.addParameter(from); if (lexer.token() == Token.FOR) { lexer.nextToken(); SQLExpr forExpr = expr(); methodInvokeExpr.addParameter(forExpr); } break; } else if (lexer.token() == Token.RPAREN) { break; } else { throw new ParserException("syntax error"); } } accept(Token.RPAREN); expr = methodInvokeExpr; return primaryRest(expr); } else if ("TRIM".equalsIgnoreCase(ident)) { lexer.nextToken(); SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident); if (lexer.token() == Token.IDENTIFIER) { String flagVal = lexer.stringVal(); if ("LEADING".equalsIgnoreCase(flagVal)) { lexer.nextToken(); methodInvokeExpr.getAttributes().put("TRIM_TYPE", "LEADING"); } else if ("BOTH".equalsIgnoreCase(flagVal)) { lexer.nextToken(); methodInvokeExpr.getAttributes().put("TRIM_TYPE", "BOTH"); } else if ("TRAILING".equalsIgnoreCase(flagVal)) { lexer.nextToken(); methodInvokeExpr.putAttribute("TRIM_TYPE", "TRAILING"); } } SQLExpr param = expr(); methodInvokeExpr.addParameter(param); if (lexer.token() == Token.FROM) { lexer.nextToken(); SQLExpr from = expr(); methodInvokeExpr.putAttribute("FROM", from); } accept(Token.RPAREN); expr = methodInvokeExpr; return primaryRest(expr); } else if ("MATCH".equalsIgnoreCase(ident)) { lexer.nextToken(); MySqlMatchAgainstExpr matchAgainstExpr = new MySqlMatchAgainstExpr(); if (lexer.token() == Token.RPAREN) { lexer.nextToken(); } else { exprList(matchAgainstExpr.getColumns(), matchAgainstExpr); accept(Token.RPAREN); } acceptIdentifier("AGAINST"); accept(Token.LPAREN); SQLExpr against = primary(); matchAgainstExpr.setAgainst(against); if (lexer.token() == Token.IN) { lexer.nextToken(); if (identifierEquals("NATURAL")) { lexer.nextToken(); acceptIdentifier("LANGUAGE"); acceptIdentifier("MODE"); if (lexer.token() == Token.WITH) { lexer.nextToken(); acceptIdentifier("QUERY"); acceptIdentifier("EXPANSION"); matchAgainstExpr.setSearchModifier( SearchModifier.IN_NATURAL_LANGUAGE_MODE_WITH_QUERY_EXPANSION); } else { matchAgainstExpr.setSearchModifier(SearchModifier.IN_NATURAL_LANGUAGE_MODE); } } else if (identifierEquals("BOOLEAN")) { lexer.nextToken(); acceptIdentifier("MODE"); matchAgainstExpr.setSearchModifier(SearchModifier.IN_BOOLEAN_MODE); } else { throw new ParserException("TODO"); } } else if (lexer.token() == Token.WITH) { throw new ParserException("TODO"); } accept(Token.RPAREN); expr = matchAgainstExpr; return primaryRest(expr); } else if (("CONVERT".equalsIgnoreCase(ident)) || ("CHAR".equalsIgnoreCase(ident))) { lexer.nextToken(); SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(ident); if (lexer.token() != Token.RPAREN) { exprList(methodInvokeExpr.getParameters(), methodInvokeExpr); } if (identifierEquals("USING")) { lexer.nextToken(); if (lexer.token() != Token.IDENTIFIER) { throw new ParserException("syntax error"); } String charset = lexer.stringVal(); lexer.nextToken(); methodInvokeExpr.putAttribute("USING", charset); } accept(Token.RPAREN); expr = methodInvokeExpr; return primaryRest(expr); } else if ("POSITION".equalsIgnoreCase(ident)) { accept(Token.LPAREN); SQLExpr subStr = this.primary(); accept(Token.IN); SQLExpr str = this.expr(); accept(Token.RPAREN); SQLMethodInvokeExpr locate = new SQLMethodInvokeExpr("LOCATE"); locate.addParameter(subStr); locate.addParameter(str); expr = locate; return primaryRest(expr); } } if (lexer.token() == Token.VARIANT && "@".equals(lexer.stringVal())) { lexer.nextToken(); MySqlUserName userName = new MySqlUserName(); if (expr instanceof SQLCharExpr) { userName.setUserName(((SQLCharExpr) expr).toString()); } else { userName.setUserName(((SQLIdentifierExpr) expr).getName()); } if (lexer.token() == Token.LITERAL_CHARS) { userName.setHost("'" + lexer.stringVal() + "'"); } else { userName.setHost(lexer.stringVal()); } lexer.nextToken(); return userName; } if (lexer.token() == Token.ERROR) { throw new ParserException( "syntax error, token: " + lexer.token() + " " + lexer.stringVal() + ", pos : " + lexer.pos()); } return super.primaryRest(expr); }