All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.phoenix.parse.SQLParser Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.phoenix.parse;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;

import org.antlr.runtime.ANTLRReaderStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.apache.phoenix.exception.PhoenixParserException;

/**
 * 
 * SQL Parser for Phoenix
 *
 * 
 * @since 0.1
 */
public class SQLParser {
    private static final ParseNodeFactory DEFAULT_NODE_FACTORY = new ParseNodeFactory();

    private final PhoenixSQLParser parser;

    public static ParseNode parseCondition(String expression) throws SQLException {
        if (expression == null) return null;
        SQLParser parser = new SQLParser(expression);
        return parser.parseExpression();
    }
    
    public SQLParser(String query) {
        this(query,DEFAULT_NODE_FACTORY);
    }

    public SQLParser(String query, ParseNodeFactory factory) {
        PhoenixSQLLexer lexer;
        try {
            lexer = new PhoenixSQLLexer(new CaseInsensitiveReaderStream(new StringReader(query)));
        } catch (IOException e) {
            throw new RuntimeException(e); // Impossible
        }
        CommonTokenStream cts = new CommonTokenStream(lexer);
        parser = new PhoenixSQLParser(cts);
        parser.setParseNodeFactory(factory);
    }

    public SQLParser(Reader queryReader, ParseNodeFactory factory) throws IOException {
        PhoenixSQLLexer lexer = new PhoenixSQLLexer(new CaseInsensitiveReaderStream(queryReader));
        CommonTokenStream cts = new CommonTokenStream(lexer);
        parser = new PhoenixSQLParser(cts);
        parser.setParseNodeFactory(factory);
    }

    public SQLParser(Reader queryReader) throws IOException {
        PhoenixSQLLexer lexer = new PhoenixSQLLexer(new CaseInsensitiveReaderStream(queryReader));
        CommonTokenStream cts = new CommonTokenStream(lexer);
        parser = new PhoenixSQLParser(cts);
        parser.setParseNodeFactory(DEFAULT_NODE_FACTORY);
    }

    /**
     * Parses the input as a series of semicolon-terminated SQL statements.
     * @throws SQLException 
     */
    public BindableStatement nextStatement(ParseNodeFactory factory) throws SQLException {
        try {
            parser.resetBindCount();
            parser.setParseNodeFactory(factory);
            BindableStatement statement = parser.nextStatement();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (UnsupportedOperationException e) {
            throw new SQLFeatureNotSupportedException(e);
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL select or upsert statement.
     * @throws SQLException 
     */
    public BindableStatement parseStatement() throws SQLException {
        try {
            BindableStatement statement = parser.statement();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (UnsupportedOperationException e) {
            throw new SQLFeatureNotSupportedException(e);
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL select statement.
     * Used only in tests
     * @throws SQLException 
     */
    public SelectStatement parseQuery() throws SQLException {
        try {
            SelectStatement statement = parser.query();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL declare cursor statement.
     * Used only in tests
     * @throws SQLException
     */
    public DeclareCursorStatement parseDeclareCursor() throws SQLException {
        try {
            DeclareCursorStatement statement = parser.declare_cursor_node();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL cursor open statement.
     * Used only in tests
     * @throws SQLException
     */
    public OpenStatement parseOpen() throws SQLException {
        try {
            OpenStatement statement = parser.cursor_open_node();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL cursor close statement.
     * Used only in tests
     * @throws SQLException
     */
    public CloseStatement parseClose() throws SQLException {
        try {
            CloseStatement statement = parser.cursor_close_node();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL cursor fetch statement.
     * Used only in tests
     * @throws SQLException
     */
    public FetchStatement parseFetch() throws SQLException {
        try {
            FetchStatement statement = parser.cursor_fetch_node();
            return statement;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL select statement.
     * Used only in tests
     * @throws SQLException 
     */
    public ParseNode parseExpression() throws SQLException {
        try {
            ParseNode node = parser.expression();
            return node;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    /**
     * Parses the input as a SQL literal
     * @throws SQLException 
     */
    public LiteralParseNode parseLiteral() throws SQLException {
        try {
            LiteralParseNode literalNode = parser.literal();
            return literalNode;
        } catch (RecognitionException e) {
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw PhoenixParserException.newException(e, parser.getTokenNames());
        }
    }

    private static class CaseInsensitiveReaderStream extends ANTLRReaderStream {
        CaseInsensitiveReaderStream(Reader script) throws IOException {
            super(script);
        }

        @Override
        public int LA(int i) {
            if (i == 0) { return 0; // undefined
            }
            if (i < 0) {
                i++; // e.g., translate LA(-1) to use offset 0
            }

            if ((p + i - 1) >= n) { return CharStream.EOF; }
            return Character.toLowerCase(data[p + i - 1]);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy