コード例 #1
0
ファイル: MySqlExprParser.java プロジェクト: irfen-fork/druid
  protected SQLExpr parseInterval() {
    accept(Token.INTERVAL);

    if (lexer.token() == Token.LPAREN) {
      lexer.nextToken();

      SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr("INTERVAL");
      if (lexer.token() != Token.RPAREN) {
        exprList(methodInvokeExpr.getParameters(), methodInvokeExpr);
      }

      accept(Token.RPAREN);

      return primaryRest(methodInvokeExpr);
    } else {
      SQLExpr value = expr();

      if (lexer.token() != Token.IDENTIFIER) {
        throw new ParserException("Syntax error");
      }

      String unit = lexer.stringVal();
      lexer.nextToken();

      MySqlIntervalExpr intervalExpr = new MySqlIntervalExpr();
      intervalExpr.setValue(value);
      intervalExpr.setUnit(MySqlIntervalUnit.valueOf(unit.toUpperCase()));

      return intervalExpr;
    }
  }
コード例 #2
0
ファイル: MySqlExprParser.java プロジェクト: irfen-fork/druid
  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);
  }