Search in sources :

Example 1 with Casing

use of org.apache.calcite.avatica.util.Casing in project calcite by apache.

the class SqlAdvisor method getReplacement.

public String getReplacement(SqlMoniker hint, String word) {
    Casing preferredCasing = getPreferredCasing(word);
    boolean quoted = !word.isEmpty() && word.charAt(0) == quoteStart();
    return getReplacement(hint, quoted, preferredCasing);
}
Also used : Casing(org.apache.calcite.avatica.util.Casing)

Example 2 with Casing

use of org.apache.calcite.avatica.util.Casing in project calcite by apache.

the class SqlAdvisor method getPreferredCasing.

/**
 * Returns casing which is preferred for replacement.
 * For instance, {@code en => ename, EN => ENAME}.
 * When input has mixed case, {@code Casing.UNCHANGED} is returned.
 * @param word input word
 * @return preferred casing when replacing input word
 */
private Casing getPreferredCasing(String word) {
    if (word == prevWord) {
        return castNonNull(prevPreferredCasing);
    }
    boolean hasLower = false;
    boolean hasUpper = false;
    int i = 0;
    while (i < word.length() && !(hasLower && hasUpper)) {
        int codePoint = word.codePointAt(i);
        hasLower |= Character.isLowerCase(codePoint);
        hasUpper |= Character.isUpperCase(codePoint);
        i += Character.charCount(codePoint);
    }
    Casing preferredCasing;
    if (hasUpper && !hasLower) {
        preferredCasing = Casing.TO_UPPER;
    } else if (!hasUpper && hasLower) {
        preferredCasing = Casing.TO_LOWER;
    } else {
        preferredCasing = Casing.UNCHANGED;
    }
    prevWord = word;
    prevPreferredCasing = preferredCasing;
    return preferredCasing;
}
Also used : Casing(org.apache.calcite.avatica.util.Casing)

Example 3 with Casing

use of org.apache.calcite.avatica.util.Casing in project calcite by apache.

the class SqlAdvisor method getCompletionHints.

/**
 * Gets completion hints for a partially completed or syntactically incorrect
 * sql statement with cursor pointing to the position where completion hints
 * are requested.
 *
 * <p>Writes into <code>replaced[0]</code> the string that is being
 * replaced. Includes the cursor and the preceding identifier. For example,
 * if <code>sql</code> is "select abc^de from t", sets <code>
 * replaced[0]</code> to "abc". If the cursor is in the middle of
 * whitespace, the replaced string is empty. The replaced string is never
 * null.
 *
 * @param sql      A partial or syntactically incorrect sql statement for
 *                 which to retrieve completion hints
 * @param cursor   to indicate the 0-based cursor position in the query at
 * @param replaced String which is being replaced (output)
 * @return completion hints
 */
public List<SqlMoniker> getCompletionHints(String sql, int cursor, String[] replaced) {
    // search backward starting from current position to find a "word"
    int wordStart = cursor;
    boolean quoted = false;
    while (wordStart > 0 && Character.isJavaIdentifierPart(sql.charAt(wordStart - 1))) {
        --wordStart;
    }
    if ((wordStart > 0) && (sql.charAt(wordStart - 1) == quoteStart())) {
        quoted = true;
        --wordStart;
    }
    if (wordStart < 0) {
        return Collections.emptyList();
    }
    // Search forwards to the end of the word we should remove. Eat up
    // trailing double-quote, if any
    int wordEnd = cursor;
    while (wordEnd < sql.length() && Character.isJavaIdentifierPart(sql.charAt(wordEnd))) {
        ++wordEnd;
    }
    if (quoted && (wordEnd < sql.length()) && (sql.charAt(wordEnd) == quoteEnd())) {
        ++wordEnd;
    }
    // remove the partially composed identifier from the
    // sql statement - otherwise we get a parser exception
    String word = replaced[0] = sql.substring(wordStart, cursor);
    if (wordStart < wordEnd) {
        sql = sql.substring(0, wordStart) + sql.substring(wordEnd);
    }
    final List<SqlMoniker> completionHints = getCompletionHints0(sql, wordStart);
    if (quoted) {
        word = word.substring(1);
    }
    if (word.isEmpty()) {
        return ImmutableList.copyOf(completionHints);
    }
    // If cursor was part of the way through a word, only include hints
    // which start with that word in the result.
    final ImmutableList.Builder<SqlMoniker> result = new ImmutableList.Builder<>();
    Casing preferredCasing = getPreferredCasing(word);
    boolean ignoreCase = preferredCasing != Casing.UNCHANGED;
    for (SqlMoniker hint : completionHints) {
        List<String> names = hint.getFullyQualifiedNames();
        // For now we treat only simple cases where the added name is the last
        // See [CALCITE-2439] Smart complete for SqlAdvisor
        String cname = Util.last(names);
        if (cname.regionMatches(ignoreCase, 0, word, 0, word.length())) {
            result.add(hint);
        }
    }
    return result.build();
}
Also used : SqlMoniker(org.apache.calcite.sql.validate.SqlMoniker) ImmutableList(com.google.common.collect.ImmutableList) Casing(org.apache.calcite.avatica.util.Casing)

Example 4 with Casing

use of org.apache.calcite.avatica.util.Casing in project calcite by apache.

the class SqlDialects method createContext.

/**
 * Extracts information from {@link DatabaseMetaData} into {@link SqlDialect.Context}.
 *
 * @param databaseMetaData the database metadata
 * @return a context with information populated from the database metadata
 */
public static SqlDialect.Context createContext(DatabaseMetaData databaseMetaData) {
    String databaseProductName;
    int databaseMajorVersion;
    int databaseMinorVersion;
    String databaseVersion;
    try {
        databaseProductName = databaseMetaData.getDatabaseProductName();
        databaseMajorVersion = databaseMetaData.getDatabaseMajorVersion();
        databaseMinorVersion = databaseMetaData.getDatabaseMinorVersion();
        databaseVersion = databaseMetaData.getDatabaseProductVersion();
    } catch (SQLException e) {
        throw new RuntimeException("while detecting database product", e);
    }
    final String quoteString = getIdentifierQuoteString(databaseMetaData);
    final NullCollation nullCollation = getNullCollation(databaseMetaData);
    final Casing unquotedCasing = getCasing(databaseMetaData, false);
    final Casing quotedCasing = getCasing(databaseMetaData, true);
    final boolean caseSensitive = isCaseSensitive(databaseMetaData);
    final SqlDialect.Context c = SqlDialect.EMPTY_CONTEXT.withDatabaseProductName(databaseProductName).withDatabaseMajorVersion(databaseMajorVersion).withDatabaseMinorVersion(databaseMinorVersion).withDatabaseVersion(databaseVersion).withIdentifierQuoteString(quoteString).withUnquotedCasing(unquotedCasing).withQuotedCasing(quotedCasing).withCaseSensitive(caseSensitive).withNullCollation(nullCollation);
    return c;
}
Also used : SQLException(java.sql.SQLException) NullCollation(org.apache.calcite.config.NullCollation) Casing(org.apache.calcite.avatica.util.Casing)

Aggregations

Casing (org.apache.calcite.avatica.util.Casing)4 ImmutableList (com.google.common.collect.ImmutableList)1 SQLException (java.sql.SQLException)1 NullCollation (org.apache.calcite.config.NullCollation)1 SqlMoniker (org.apache.calcite.sql.validate.SqlMoniker)1