use of org.apache.calcite.sql.validate.SqlMoniker in project calcite by apache.
the class SqlAdvisorGetHintsFunction method getCompletionHints.
/**
* Returns completion hints for a given SQL statement.
*
* <p>Typically this is called from generated code
* (via {@link SqlAdvisorGetHintsFunction#IMPLEMENTOR}).
*
* @param advisor Advisor to produce completion hints
* @param sql SQL to complete
* @param pos Cursor position in SQL
* @return the table that contains completion hints for a given SQL statement
*/
public static Enumerable<SqlAdvisorHint> getCompletionHints(final SqlAdvisor advisor, final String sql, final int pos) {
final String[] replaced = { null };
final List<SqlMoniker> hints = advisor.getCompletionHints(sql, pos, replaced);
final List<SqlAdvisorHint> res = new ArrayList<>(hints.size() + 1);
res.add(new SqlAdvisorHint(replaced[0], null, "MATCH"));
for (SqlMoniker hint : hints) {
res.add(new SqlAdvisorHint(hint));
}
return Linq4j.asEnumerable(res).asQueryable();
}
use of org.apache.calcite.sql.validate.SqlMoniker in project calcite by apache.
the class SqlAdvisorTest method convertCompletionHints.
private String convertCompletionHints(List<SqlMoniker> hints) {
List<String> list = new ArrayList<String>();
for (SqlMoniker hint : hints) {
if (hint.getType() != SqlMonikerType.FUNCTION) {
list.add(hint.id());
}
}
Collections.sort(list);
return toString(list);
}
use of org.apache.calcite.sql.validate.SqlMoniker in project calcite by apache.
the class SqlAdvisorTest method assertComplete.
/**
* Tests that a given SQL which may be invalid or incomplete simplifies
* itself and yields the salesTables set of completion hints. This is an
* integration test of {@link #assertHint} and {@link #assertSimplify}.
*
* @param sql SQL statement
* @param expectedResults Expected list of hints
* @param expectedWord Word that we expect to be replaced, or null if we
* don't care
*/
protected void assertComplete(String sql, String expectedResults, String expectedWord) {
SqlValidatorWithHints validator = (SqlValidatorWithHints) tester.getValidator();
SqlAdvisor advisor = tester.getFactory().createAdvisor(validator);
SqlParserUtil.StringAndPos sap = SqlParserUtil.findPos(sql);
final String[] replaced = { null };
List<SqlMoniker> results = advisor.getCompletionHints(sap.sql, sap.cursor, replaced);
assertNotNull(replaced[0]);
assertNotNull(results);
Assert.assertEquals(expectedResults, convertCompletionHints(results));
if (expectedWord != null) {
Assert.assertEquals(expectedWord, replaced[0]);
}
}
use of org.apache.calcite.sql.validate.SqlMoniker in project calcite by apache.
the class SqlAdvisorTest method assertHint.
/**
* Checks that a given SQL statement yields the expected set of completion
* hints.
*
* @param sql SQL statement
* @param expectedResults Expected list of hints
* @throws Exception on error
*/
protected void assertHint(String sql, String expectedResults) throws Exception {
SqlValidatorWithHints validator = (SqlValidatorWithHints) tester.getValidator();
SqlAdvisor advisor = tester.getFactory().createAdvisor(validator);
SqlParserUtil.StringAndPos sap = SqlParserUtil.findPos(sql);
List<SqlMoniker> results = advisor.getCompletionHints(sap.sql, sap.pos);
Assert.assertEquals(expectedResults, convertCompletionHints(results));
}
use of org.apache.calcite.sql.validate.SqlMoniker in project calcite by apache.
the class SqlAdvisor method getCompletionHints.
// ~ Methods ----------------------------------------------------------------
/**
* 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) == '"')) {
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) == '"')) {
++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, sql.length());
}
final List<SqlMoniker> completionHints = getCompletionHints0(sql, wordStart);
// If cursor was part of the way through a word, only include hints
// which start with that word in the result.
final List<SqlMoniker> result;
if (word.length() > 0) {
result = new ArrayList<SqlMoniker>();
if (quoted) {
// Quoted identifier. Case-sensitive match.
word = word.substring(1);
for (SqlMoniker hint : completionHints) {
String cname = hint.toString();
if (cname.startsWith(word)) {
result.add(hint);
}
}
} else {
// Regular identifier. Case-insensitive match.
for (SqlMoniker hint : completionHints) {
String cname = hint.toString();
if ((cname.length() >= word.length()) && cname.substring(0, word.length()).equalsIgnoreCase(word)) {
result.add(hint);
}
}
}
} else {
result = completionHints;
}
return result;
}
Aggregations