Search in sources :

Example 1 with ImpalaSqlParser

use of io.hetu.core.migration.source.impala.ImpalaSqlParser in project hetu-core by openlookeng.

the class ImpalaParser method invokeParser.

public JSONObject invokeParser(String sql, Function<ImpalaSqlParser, ParserRuleContext> parseFunction, ParsingOptions parsingOptions) {
    try {
        ImpalaSqlLexer lexer = new ImpalaSqlLexer(new CaseInsensitiveStream(CharStreams.fromString(sql)));
        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        ImpalaSqlParser parser = new ImpalaSqlParser(tokenStream);
        // Override the default error strategy to not attempt inserting or deleting a token.
        // Otherwise, it messes up error reporting
        parser.setErrorHandler(new DefaultErrorStrategy() {

            @Override
            public Token recoverInline(Parser recognizer) throws RecognitionException {
                if (nextTokensContext == null) {
                    throw new InputMismatchException(recognizer);
                } else {
                    throw new InputMismatchException(recognizer, nextTokensState, nextTokensContext);
                }
            }
        });
        parser.addParseListener(new PostProcessor(Arrays.asList(parser.getRuleNames())));
        lexer.removeErrorListeners();
        lexer.addErrorListener(LEXER_ERROR_LISTENER);
        parser.removeErrorListeners();
        if (enhancedErrorHandlerEnabled) {
            parser.addErrorListener(PARSER_ERROR_HANDLER);
        } else {
            parser.addErrorListener(LEXER_ERROR_LISTENER);
        }
        String convertedSql = "";
        String conversionStatus = "";
        String errorMessage = "";
        JSONArray diffArray = new JSONArray();
        ImpalaAstBuilder impalaAstBuilder = null;
        try {
            ParserRuleContext tree;
            try {
                // first, try parsing with potentially faster SLL mode
                parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
                tree = parseFunction.apply(parser);
            } catch (ParseCancellationException ex) {
                // if we fail, parse with LL mode
                // rewind input stream
                tokenStream.reset();
                parser.reset();
                parser.getInterpreter().setPredictionMode(PredictionMode.LL);
                tree = parseFunction.apply(parser);
            }
            impalaAstBuilder = new ImpalaAstBuilder(parsingOptions);
            Statement statement = (Statement) impalaAstBuilder.visit(tree);
            if (statement == null) {
                conversionStatus = Constants.FAILED;
                errorMessage = "The input sql is not valid or empty.";
            } else {
                convertedSql = SqlFormatter.formatSql(statement, Optional.empty());
                if (impalaAstBuilder.getParserDiffsList().isEmpty()) {
                    conversionStatus = Constants.SUCCESS;
                } else {
                    conversionStatus = Constants.SUCCESS;
                    for (ParserDiffs diffs : impalaAstBuilder.getParserDiffsList()) {
                        if (diffs.getDiffType().equals(DiffType.DELETED) || diffs.getDiffType().equals(DiffType.FUNCTION_WARNING)) {
                            conversionStatus = Constants.WARNING;
                        }
                        diffArray.put(diffs.toJsonObject());
                    }
                }
            }
        } catch (UnsupportedException e) {
            // handle the unsupported keywords
            conversionStatus = Constants.UNSUPPORTED;
            if (impalaAstBuilder != null) {
                for (ParserDiffs diffs : impalaAstBuilder.getParserDiffsList()) {
                    if (diffs.getDiffType().equals(DiffType.UNSUPPORTED)) {
                        diffArray.put(diffs.toJsonObject());
                        errorMessage += diffs.getMessage().isPresent() ? diffs.getMessage().get() : "";
                    }
                }
            }
            if (errorMessage.isEmpty()) {
                errorMessage = e.getMessage();
            }
        } catch (IllegalArgumentException | UnsupportedOperationException | ParsingException e) {
            errorMessage = e.getMessage();
            conversionStatus = Constants.FAILED;
        }
        // Construct json format result
        JSONObject result = new JSONObject();
        result.put(Constants.ORIGINAL_SQL, sql);
        result.put(Constants.ORIGINAL_SQL_TYPE, IMPALA.getValue());
        result.put(Constants.CONVERTED_SQL, convertedSql);
        result.put(Constants.STATUS, conversionStatus);
        result.put(Constants.MESSAGE, errorMessage);
        result.put(Constants.DIFFS, diffArray);
        return result;
    } catch (JSONException e) {
        throw new ParsingException("Construct parsing result failed." + e.getMessage());
    } catch (StackOverflowError e) {
        throw new ParsingException("statement is too large (stack overflow while parsing)");
    }
}
Also used : Token(org.antlr.v4.runtime.Token) CommonToken(org.antlr.v4.runtime.CommonToken) DefaultErrorStrategy(org.antlr.v4.runtime.DefaultErrorStrategy) ParsingException(io.prestosql.sql.parser.ParsingException) CommonTokenStream(org.antlr.v4.runtime.CommonTokenStream) ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) Statement(io.prestosql.sql.tree.Statement) JSONArray(org.codehaus.jettison.json.JSONArray) JSONException(org.codehaus.jettison.json.JSONException) InputMismatchException(org.antlr.v4.runtime.InputMismatchException) ImpalaSqlParser(io.hetu.core.migration.source.impala.ImpalaSqlParser) Parser(org.antlr.v4.runtime.Parser) ImpalaSqlParser(io.hetu.core.migration.source.impala.ImpalaSqlParser) JSONObject(org.codehaus.jettison.json.JSONObject) ImpalaSqlLexer(io.hetu.core.migration.source.impala.ImpalaSqlLexer) ParseCancellationException(org.antlr.v4.runtime.misc.ParseCancellationException) CaseInsensitiveStream(io.prestosql.sql.parser.CaseInsensitiveStream) RecognitionException(org.antlr.v4.runtime.RecognitionException)

Aggregations

ImpalaSqlLexer (io.hetu.core.migration.source.impala.ImpalaSqlLexer)1 ImpalaSqlParser (io.hetu.core.migration.source.impala.ImpalaSqlParser)1 CaseInsensitiveStream (io.prestosql.sql.parser.CaseInsensitiveStream)1 ParsingException (io.prestosql.sql.parser.ParsingException)1 Statement (io.prestosql.sql.tree.Statement)1 CommonToken (org.antlr.v4.runtime.CommonToken)1 CommonTokenStream (org.antlr.v4.runtime.CommonTokenStream)1 DefaultErrorStrategy (org.antlr.v4.runtime.DefaultErrorStrategy)1 InputMismatchException (org.antlr.v4.runtime.InputMismatchException)1 Parser (org.antlr.v4.runtime.Parser)1 ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)1 RecognitionException (org.antlr.v4.runtime.RecognitionException)1 Token (org.antlr.v4.runtime.Token)1 ParseCancellationException (org.antlr.v4.runtime.misc.ParseCancellationException)1 JSONArray (org.codehaus.jettison.json.JSONArray)1 JSONException (org.codehaus.jettison.json.JSONException)1 JSONObject (org.codehaus.jettison.json.JSONObject)1