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

io.prestosql.plugin.hive.HiveQlToPrestoTranslator Maven / Gradle / Ivy

There is a newer version: 350
Show newest version
/*
 * Licensed 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 io.prestosql.plugin.hive;

import com.google.common.collect.Lists;
import com.google.common.collect.PeekingIterator;
import io.prestosql.spi.PrestoException;

import static com.google.common.collect.Iterators.peekingIterator;
import static io.prestosql.plugin.hive.HiveErrorCode.HIVE_VIEW_TRANSLATION_ERROR;
import static org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer.unescapeSQLString;

/**
 * Translate statements in Hive QL to Presto SQL.
 *
 * Only translation of quoted literals is currently included.
 */
public final class HiveQlToPrestoTranslator
{
    // Translation methods consume data from the iterator
    private final PeekingIterator input;
    private final StringBuilder output = new StringBuilder();

    /**
     * Translate a HiveQL statement to Presto SQL by fixing quoted identifiers
     * and string literals. No other translation is performed.
     *
     * 

Backquotes are replaced with double quotes, including SQL-style * escapes (`` becomes ` and " becomes ""). * *

Single and double quotes are replaced with single quotes, with * minimal processing of escape sequences to ensure that the strings end in * the right place. */ public static String translateHiveViewToPresto(String hiveStatement) { HiveQlToPrestoTranslator translator = new HiveQlToPrestoTranslator(hiveStatement); return translator.translateQuotedLiterals(); } private HiveQlToPrestoTranslator(String hiveQl) { input = peekingIterator(Lists.charactersOf(hiveQl).iterator()); } private String translateQuotedLiterals() { // Consume input, passing control to other translation methods when // their delimiters are encountered. while (input.hasNext()) { char c = input.next(); switch (c) { case '"': case '\'': translateString(c); break; case '`': translateQuotedIdentifier(); break; default: output.append(c); break; } } return output.toString(); } private void translateString(char delimiter) { // Build a copy of the string to pass to Hive's string unescaper StringBuilder string = new StringBuilder(String.valueOf(delimiter)); while (input.hasNext()) { char c = input.next(); if (c == delimiter) { string.append(delimiter); String unescaped = unescapeSQLString(string.toString()); output.append("'"); output.append(unescaped.replace("'", "''")); output.append("'"); return; } string.append(c); if (c == '\\') { if (!input.hasNext()) { break; // skip to end-of-input error } string.append(input.next()); } } throw hiveViewParseError("unexpected end of input in string"); } private void translateQuotedIdentifier() { output.append('"'); while (input.hasNext()) { char c = input.next(); if (c == '"') { // escape " as "" output.append("\"\""); } else if (c == '`' && input.hasNext() && input.peek() == '`') { // un-escape `` as ` output.append('`'); input.next(); } else if (c == '`') { // end of identifier output.append('"'); return; } else { // don't change characters besides ` and " output.append(c); } } throw hiveViewParseError("unexpected end of input in identifier"); } private static PrestoException hiveViewParseError(String message) { return new PrestoException(HIVE_VIEW_TRANSLATION_ERROR, "Error translating Hive view to Presto: " + message); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy