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);
}
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;
}
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();
}
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;
}
Aggregations