use of net.sf.jsqlparser.schema.Table in project dbeaver by serge-rider.
the class SQLCompletionAnalyzer method runAnalyzer.
private void runAnalyzer() throws DBException {
String searchPrefix = request.getWordPart();
request.setQueryType(null);
SQLWordPartDetector wordDetector = request.getWordDetector();
SQLSyntaxManager syntaxManager = request.getContext().getSyntaxManager();
String prevKeyWord = wordDetector.getPrevKeyWord();
boolean isPrevWordEmpty = CommonUtils.isEmpty(wordDetector.getPrevWords());
String prevDelimiter = wordDetector.getPrevDelimiter();
{
if (!CommonUtils.isEmpty(prevKeyWord)) {
if (syntaxManager.getDialect().isEntityQueryWord(prevKeyWord)) {
// TODO: its an ugly hack. Need a better way
if (SQLConstants.KEYWORD_DELETE.equals(prevKeyWord)) {
request.setQueryType(null);
} else if (SQLConstants.KEYWORD_INTO.equals(prevKeyWord) && !isPrevWordEmpty && ("(".equals(prevDelimiter) || ",".equals(prevDelimiter))) {
request.setQueryType(SQLCompletionRequest.QueryType.COLUMN);
} else if (SQLConstants.KEYWORD_INTO.equals(prevKeyWord) && !isPrevWordEmpty && ("(*".equals(prevDelimiter) || "{*".equals(prevDelimiter) || "[*".equals(prevDelimiter))) {
wordDetector.shiftOffset(-SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN.length());
searchPrefix = SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN;
request.setQueryType(SQLCompletionRequest.QueryType.COLUMN);
} else if (SQLConstants.KEYWORD_JOIN.equals(prevKeyWord)) {
request.setQueryType(SQLCompletionRequest.QueryType.JOIN);
} else {
if (!isPrevWordEmpty && CommonUtils.isEmpty(prevDelimiter)) {
// Seems to be table alias
return;
}
request.setQueryType(SQLCompletionRequest.QueryType.TABLE);
}
} else if (syntaxManager.getDialect().isAttributeQueryWord(prevKeyWord)) {
request.setQueryType(SQLCompletionRequest.QueryType.COLUMN);
if (!request.isSimpleMode() && CommonUtils.isEmpty(request.getWordPart()) && prevDelimiter.equals(SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN)) {
wordDetector.shiftOffset(-SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN.length());
searchPrefix = SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN;
}
} else if (SQLUtils.isExecQuery(syntaxManager.getDialect(), prevKeyWord)) {
request.setQueryType(SQLCompletionRequest.QueryType.EXEC);
}
}
}
request.setWordPart(searchPrefix);
DBPDataSource dataSource = request.getContext().getDataSource();
if (dataSource == null) {
return;
}
String wordPart = request.getWordPart();
boolean emptyWord = wordPart.length() == 0;
SQLCompletionRequest.QueryType queryType = request.getQueryType();
Map<String, Object> parameters = new LinkedHashMap<>();
List<String> prevWords = wordDetector.getPrevWords();
String previousWord = "";
if (!CommonUtils.isEmpty(prevWords)) {
previousWord = prevWords.get(0).toUpperCase(Locale.ENGLISH);
}
if (!CommonUtils.isEmpty(prevWords) && (SQLConstants.KEYWORD_PROCEDURE.equals(previousWord) || SQLConstants.KEYWORD_FUNCTION.equals(previousWord))) {
parameters.put(SQLCompletionProposalBase.PARAM_EXEC, false);
} else {
parameters.put(SQLCompletionProposalBase.PARAM_EXEC, true);
}
if (queryType != null) {
// or get list of root database objects
if (emptyWord) {
// Get root objects
DBPObject rootObject = null;
if (queryType == SQLCompletionRequest.QueryType.COLUMN && dataSource instanceof DBSObjectContainer) {
// Try to detect current table
rootObject = getTableFromAlias((DBSObjectContainer) dataSource, null, true);
if (rootObject instanceof DBSEntity) {
switch(prevKeyWord) {
case SQLConstants.KEYWORD_ON:
// Join?
if (makeJoinColumnProposals((DBSObjectContainer) dataSource, (DBSEntity) rootObject)) {
return;
}
// Fall-thru
case SQLConstants.KEYWORD_WHERE:
case SQLConstants.KEYWORD_AND:
case SQLConstants.KEYWORD_OR:
if (!request.isSimpleMode()) {
boolean waitsForValue = rootObject instanceof DBSEntity && !CommonUtils.isEmpty(prevWords) && !CommonUtils.isEmpty(prevDelimiter) && !prevDelimiter.endsWith(")");
if (waitsForValue) {
makeProposalsFromAttributeValues(dataSource, wordDetector, (DBSEntity) rootObject);
}
}
break;
}
}
} else if (dataSource instanceof DBSObjectContainer) {
// Try to get from active object
DBSObject selectedObject = DBUtils.getActiveInstanceObject(request.getContext().getExecutionContext());
if (selectedObject != null) {
makeProposalsFromChildren(selectedObject, null, false, parameters);
rootObject = DBUtils.getPublicObject(selectedObject.getParentObject());
} else {
rootObject = dataSource;
}
}
if (rootObject != null) {
makeProposalsFromChildren(rootObject, null, false, parameters);
}
if (queryType == SQLCompletionRequest.QueryType.JOIN && !proposals.isEmpty() && dataSource instanceof DBSObjectContainer) {
// Filter out non-joinable tables
DBSObject leftTable = getTableFromAlias((DBSObjectContainer) dataSource, null, true);
if (leftTable instanceof DBSEntity) {
filterNonJoinableProposals((DBSEntity) leftTable);
}
}
} else {
DBSObject rootObject = null;
if (queryType == SQLCompletionRequest.QueryType.COLUMN && dataSource instanceof DBSObjectContainer) {
// Part of column name
// Try to get from active object
DBSObjectContainer sc = (DBSObjectContainer) dataSource;
DBSObject selectedObject = DBUtils.getActiveInstanceObject(request.getContext().getExecutionContext());
if (selectedObject instanceof DBSObjectContainer) {
sc = (DBSObjectContainer) selectedObject;
}
SQLDialect sqlDialect = request.getContext().getDataSource().getSQLDialect();
String tableAlias = null;
if (ALL_COLUMNS_PATTERN.equals(wordPart)) {
if (!isPrevWordEmpty) {
if (!prevKeyWord.equalsIgnoreCase("INTO")) {
String prevWord = wordDetector.getPrevWords().get(0);
if (prevWord.contains(sqlDialect.getCatalogSeparator())) {
int divPos = prevWord.lastIndexOf(sqlDialect.getCatalogSeparator());
tableAlias = prevWord.substring(0, divPos);
}
}
}
}
if (tableAlias == null) {
int divPos = wordPart.lastIndexOf(syntaxManager.getStructSeparator());
tableAlias = divPos == -1 ? null : wordPart.substring(0, divPos);
}
if (tableAlias == null && !CommonUtils.isEmpty(wordPart)) {
// May be an incomplete table alias. Try to find such table
rootObject = getTableFromAlias(sc, wordPart, false);
if (rootObject != null) {
// Found alias - no proposals
searchFinished = true;
return;
}
}
rootObject = getTableFromAlias(sc, tableAlias, false);
if (rootObject == null && tableAlias != null) {
// Maybe alias ss a table name
String[] allNames = SQLUtils.splitFullIdentifier(tableAlias, sqlDialect.getCatalogSeparator(), sqlDialect.getIdentifierQuoteStrings(), false);
rootObject = SQLSearchUtils.findObjectByFQN(monitor, sc, request.getContext().getExecutionContext(), Arrays.asList(allNames), !request.isSimpleMode(), wordDetector);
}
}
if (rootObject != null) {
makeProposalsFromChildren(rootObject, wordPart, false, parameters);
} else {
// Get root object or objects from active database (if any)
if (queryType != SQLCompletionRequest.QueryType.COLUMN && queryType != SQLCompletionRequest.QueryType.EXEC) {
makeDataSourceProposals();
}
}
}
if (!request.isSimpleMode() && (queryType == SQLCompletionRequest.QueryType.EXEC || (queryType == SQLCompletionRequest.QueryType.COLUMN && request.getContext().isSearchProcedures())) && dataSource instanceof DBSObjectContainer) {
makeProceduresProposals(dataSource, wordPart, true);
}
} else {
if (!request.isSimpleMode() && !CommonUtils.isEmpty(prevWords)) {
if (SQLConstants.KEYWORD_PROCEDURE.equals(previousWord) || SQLConstants.KEYWORD_FUNCTION.equals(previousWord)) {
makeProceduresProposals(dataSource, wordPart, false);
}
// may be useful in the future for procedures autocomplete
/*if (SQLConstants.BLOCK_BEGIN.equalsIgnoreCase(prevWords.get(0))) {
makeProceduresProposals(dataSource, wordPart, true);
}*/
}
}
if (!emptyWord) {
makeProposalsFromQueryParts();
}
// Final filtering
if (!searchFinished) {
List<String> matchedKeywords = Collections.emptyList();
Set<String> allowedKeywords = null;
SQLDialect sqlDialect = request.getContext().getDataSource().getSQLDialect();
if (CommonUtils.isEmpty(prevKeyWord)) {
allowedKeywords = new HashSet<>();
Collections.addAll(allowedKeywords, sqlDialect.getQueryKeywords());
Collections.addAll(allowedKeywords, sqlDialect.getDMLKeywords());
Collections.addAll(allowedKeywords, sqlDialect.getDDLKeywords());
Collections.addAll(allowedKeywords, sqlDialect.getExecuteKeywords());
} else if (ArrayUtils.contains(sqlDialect.getQueryKeywords(), prevKeyWord.toUpperCase(Locale.ENGLISH))) {
// SELECT ..
// Limit with FROM if we already have some expression
String delimiter = wordDetector.getPrevDelimiter();
if (!isPrevWordEmpty && (CommonUtils.isEmpty(delimiter) || delimiter.endsWith(")"))) {
// last expression ends with space or with ")"
allowedKeywords = new HashSet<>();
allowedKeywords.add(SQLConstants.KEYWORD_FROM);
if (CommonUtils.isEmpty(request.getWordPart())) {
matchedKeywords = Arrays.asList(SQLConstants.KEYWORD_FROM);
}
}
} else if (sqlDialect.isEntityQueryWord(prevKeyWord)) {
allowedKeywords = new HashSet<>();
if (SQLConstants.KEYWORD_DELETE.equals(prevKeyWord)) {
allowedKeywords.add(SQLConstants.KEYWORD_FROM);
} else {
allowedKeywords.add(SQLConstants.KEYWORD_WHERE);
}
}
if (!CommonUtils.isEmpty(request.getWordPart())) {
// Keyword assist
matchedKeywords = syntaxManager.getDialect().getMatchedKeywords(request.getWordPart());
if (!request.isSimpleMode()) {
// Sort using fuzzy match
matchedKeywords.sort(Comparator.comparingInt(o -> TextUtils.fuzzyScore(o, request.getWordPart())));
}
}
for (String keyWord : matchedKeywords) {
DBPKeywordType keywordType = syntaxManager.getDialect().getKeywordType(keyWord);
if (keywordType != null) {
if (keywordType == DBPKeywordType.TYPE) {
continue;
}
if (request.getQueryType() == SQLCompletionRequest.QueryType.COLUMN && !(keywordType == DBPKeywordType.FUNCTION || keywordType == DBPKeywordType.KEYWORD || keywordType == DBPKeywordType.OTHER)) {
continue;
}
if (allowedKeywords != null && !allowedKeywords.contains(keyWord)) {
continue;
}
proposals.add(SQLCompletionAnalyzer.createCompletionProposal(request, keyWord, keyWord, keywordType, null, false, null, Collections.emptyMap()));
}
}
}
filterProposals(dataSource);
}
use of net.sf.jsqlparser.schema.Table in project dbeaver by serge-rider.
the class SQLSemanticProcessor method getOrderConstraintExpression.
private static Expression getOrderConstraintExpression(DBRProgressMonitor monitor, DBPDataSource dataSource, PlainSelect select, DBDAttributeConstraint co, boolean forceNumeric) throws JSQLParserException, DBException {
Expression orderExpr;
String attrName = DBUtils.getQuotedIdentifier(dataSource, co.getAttributeName());
if (forceNumeric || attrName.isEmpty()) {
orderExpr = new LongValue(co.getOrderPosition());
} else if (CommonUtils.isJavaIdentifier(attrName)) {
// Use column table only if there are multiple source tables (joins)
Table orderTable = CommonUtils.isEmpty(select.getJoins()) ? null : getConstraintTable(select, co);
if (!isValidTableColumn(monitor, dataSource, orderTable, co)) {
orderTable = null;
}
orderExpr = new Column(orderTable, attrName);
} else {
// TODO: set tableAlias for all column references in expression
orderExpr = CCJSqlParserUtil.parseExpression(attrName);
// orderExpr = new CustomExpression(attrName);
// orderExpr = new LongValue(co.getAttribute().getOrdinalPosition() + 1);
}
return orderExpr;
}
use of net.sf.jsqlparser.schema.Table in project spanner-jdbc by olavloite.
the class CloudSpannerPreparedStatement method setPlainSelectParameters.
private void setPlainSelectParameters(PlainSelect plainSelect, com.google.cloud.spanner.Statement.Builder builder) {
if (plainSelect.getFromItem() != null) {
plainSelect.getFromItem().accept(new FromItemVisitorAdapter() {
private int tableCount = 0;
@Override
public void visit(Table table) {
tableCount++;
if (tableCount == 1)
getParameterStore().setTable(unquoteIdentifier(table.getFullyQualifiedName()));
else
getParameterStore().setTable(null);
}
@Override
public void visit(SubSelect subSelect) {
if (subSelect.getSelectBody() instanceof PlainSelect) {
setPlainSelectParameters((PlainSelect) subSelect.getSelectBody(), builder);
} else {
subSelect.getSelectBody().accept(new SelectVisitorAdapter() {
@Override
public void visit(PlainSelect plainSelect) {
setPlainSelectParameters(plainSelect, builder);
}
@Override
public void visit(SetOperationList setOpList) {
for (SelectBody body : setOpList.getSelects()) {
setSelectParameters(body, builder);
}
}
});
}
}
});
}
if (plainSelect.getSelectItems() != null) {
for (SelectItem selectItem : plainSelect.getSelectItems()) {
selectItem.accept(new SelectItemVisitorAdapter() {
@Override
public void visit(SelectExpressionItem item) {
item.getExpression().accept(new ExpressionVisitorAdapter() {
private String currentCol = null;
@Override
public void visit(Column col) {
currentCol = unquoteIdentifier(col.getFullyQualifiedName());
}
@Override
public void visit(JdbcParameter parameter) {
parameter.accept(new ValueBinderExpressionVisitorAdapter<>(getParameterStore(), builder.bind("p" + parameter.getIndex()), currentCol));
currentCol = null;
}
@Override
public void visit(SubSelect subSelect) {
setSelectParameters(subSelect.getSelectBody(), builder);
}
});
}
});
}
}
setWhereParameters(plainSelect.getWhere(), builder);
if (plainSelect.getLimit() != null) {
setWhereParameters(plainSelect.getLimit().getRowCount(), builder);
}
if (plainSelect.getOffset() != null && plainSelect.getOffset().getOffsetJdbcParameter() != null) {
ValueBinderExpressionVisitorAdapter<com.google.cloud.spanner.Statement.Builder> binder = new ValueBinderExpressionVisitorAdapter<>(getParameterStore(), builder.bind("p" + getParameterStore().getHighestIndex()), null);
binder.setValue(getParameterStore().getParameter(getParameterStore().getHighestIndex()), Types.BIGINT);
getParameterStore().setType(getParameterStore().getHighestIndex(), Types.BIGINT);
}
}
use of net.sf.jsqlparser.schema.Table in project spanner-jdbc by olavloite.
the class AbstractCloudSpannerStatement method createInsertSelectOnDuplicateKeyUpdateStatement.
/**
* Transform the given UPDATE-statement into an "INSERT INTO TAB1 (...) SELECT ... FROM TAB1 WHERE
* ... ON DUPLICATE KEY UPDATE"
*
* @param update The UPDATE-statement
* @return An SQL-statement equal to the UPDATE-statement but in INSERT form
* @throws SQLException if a database exception occurs while getting the table meta data or if the
* statement tries to update the primary key value
*/
protected String createInsertSelectOnDuplicateKeyUpdateStatement(Update update) throws SQLException {
String tableName = unquoteIdentifier(update.getTables().get(0).getName());
TableKeyMetaData table = getConnection().getTable(tableName);
List<String> keyColumns = table.getKeyColumns();
List<String> updateColumns = update.getColumns().stream().map(Column::getColumnName).map(String::toUpperCase).collect(Collectors.toList());
List<String> quotedKeyColumns = keyColumns.stream().map(this::quoteIdentifier).collect(Collectors.toList());
List<String> quotedAndQualifiedKeyColumns = keyColumns.stream().map(x -> quoteIdentifier(tableName) + "." + quoteIdentifier(x)).collect(Collectors.toList());
List<String> quotedUpdateColumns = updateColumns.stream().map(this::quoteIdentifier).collect(Collectors.toList());
List<String> expressions = update.getExpressions().stream().map(Object::toString).collect(Collectors.toList());
if (updateColumns.stream().anyMatch(keyColumns::contains)) {
String invalidCols = updateColumns.stream().filter(keyColumns::contains).collect(Collectors.joining());
throw new CloudSpannerSQLException("UPDATE of a primary key value is not allowed, cannot UPDATE the column(s) " + invalidCols, Code.INVALID_ARGUMENT);
}
StringBuilder res = new StringBuilder();
res.append("INSERT INTO ").append(quoteIdentifier(tableName)).append("\n(");
res.append(String.join(", ", quotedKeyColumns)).append(", ");
res.append(String.join(", ", quotedUpdateColumns)).append(")");
res.append("\nSELECT ").append(String.join(", ", quotedAndQualifiedKeyColumns)).append(", ");
res.append(String.join(", ", expressions));
res.append("\nFROM ").append(quoteIdentifier(tableName));
if (update.getWhere() != null)
res.append("\n").append("WHERE ").append(update.getWhere().toString());
res.append("\nON DUPLICATE KEY UPDATE");
return res.toString();
}
use of net.sf.jsqlparser.schema.Table in project dbeaver by dbeaver.
the class SQLCompletionAnalyzer method runAnalyzer.
private void runAnalyzer() throws DBException {
String searchPrefix = request.getWordPart();
request.setQueryType(null);
SQLWordPartDetector wordDetector = request.getWordDetector();
SQLSyntaxManager syntaxManager = request.getContext().getSyntaxManager();
String prevKeyWord = wordDetector.getPrevKeyWord();
boolean isPrevWordEmpty = CommonUtils.isEmpty(wordDetector.getPrevWords());
String prevDelimiter = wordDetector.getPrevDelimiter();
{
if (!CommonUtils.isEmpty(prevKeyWord)) {
if (syntaxManager.getDialect().isEntityQueryWord(prevKeyWord)) {
// TODO: its an ugly hack. Need a better way
if (SQLConstants.KEYWORD_DELETE.equals(prevKeyWord)) {
request.setQueryType(null);
} else if (SQLConstants.KEYWORD_INTO.equals(prevKeyWord) && !isPrevWordEmpty && ("(".equals(prevDelimiter) || ",".equals(prevDelimiter))) {
request.setQueryType(SQLCompletionRequest.QueryType.COLUMN);
} else if (SQLConstants.KEYWORD_INTO.equals(prevKeyWord) && !isPrevWordEmpty && ("(*".equals(prevDelimiter) || "{*".equals(prevDelimiter) || "[*".equals(prevDelimiter))) {
wordDetector.shiftOffset(-SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN.length());
searchPrefix = SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN;
request.setQueryType(SQLCompletionRequest.QueryType.COLUMN);
} else if (SQLConstants.KEYWORD_JOIN.equals(prevKeyWord)) {
request.setQueryType(SQLCompletionRequest.QueryType.JOIN);
} else {
if (!isPrevWordEmpty && CommonUtils.isEmpty(prevDelimiter)) {
// Seems to be table alias
return;
}
request.setQueryType(SQLCompletionRequest.QueryType.TABLE);
}
} else if (syntaxManager.getDialect().isAttributeQueryWord(prevKeyWord)) {
request.setQueryType(SQLCompletionRequest.QueryType.COLUMN);
if (!request.isSimpleMode() && CommonUtils.isEmpty(request.getWordPart()) && prevDelimiter.equals(SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN)) {
wordDetector.shiftOffset(-SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN.length());
searchPrefix = SQLCompletionAnalyzer.ALL_COLUMNS_PATTERN;
}
} else if (SQLUtils.isExecQuery(syntaxManager.getDialect(), prevKeyWord)) {
request.setQueryType(SQLCompletionRequest.QueryType.EXEC);
}
}
}
request.setWordPart(searchPrefix);
DBPDataSource dataSource = request.getContext().getDataSource();
if (dataSource == null) {
return;
}
String wordPart = request.getWordPart();
boolean emptyWord = wordPart.length() == 0;
SQLCompletionRequest.QueryType queryType = request.getQueryType();
Map<String, Object> parameters = new LinkedHashMap<>();
List<String> prevWords = wordDetector.getPrevWords();
String previousWord = "";
if (!CommonUtils.isEmpty(prevWords)) {
previousWord = prevWords.get(0).toUpperCase(Locale.ENGLISH);
}
if (!CommonUtils.isEmpty(prevWords) && (SQLConstants.KEYWORD_PROCEDURE.equals(previousWord) || SQLConstants.KEYWORD_FUNCTION.equals(previousWord))) {
parameters.put(SQLCompletionProposalBase.PARAM_EXEC, false);
} else {
parameters.put(SQLCompletionProposalBase.PARAM_EXEC, true);
}
if (queryType != null) {
// or get list of root database objects
if (emptyWord) {
// Get root objects
DBPObject rootObject = null;
if (queryType == SQLCompletionRequest.QueryType.COLUMN && dataSource instanceof DBSObjectContainer) {
// Try to detect current table
rootObject = getTableFromAlias((DBSObjectContainer) dataSource, null, true);
if (rootObject instanceof DBSEntity) {
switch(prevKeyWord) {
case SQLConstants.KEYWORD_ON:
// Join?
if (makeJoinColumnProposals((DBSObjectContainer) dataSource, (DBSEntity) rootObject)) {
return;
}
// Fall-thru
case SQLConstants.KEYWORD_WHERE:
case SQLConstants.KEYWORD_AND:
case SQLConstants.KEYWORD_OR:
if (!request.isSimpleMode()) {
boolean waitsForValue = rootObject instanceof DBSEntity && !CommonUtils.isEmpty(prevWords) && !CommonUtils.isEmpty(prevDelimiter) && !prevDelimiter.endsWith(")");
if (waitsForValue) {
makeProposalsFromAttributeValues(dataSource, wordDetector, (DBSEntity) rootObject);
}
}
break;
}
}
} else if (dataSource instanceof DBSObjectContainer) {
// Try to get from active object
DBSObject selectedObject = DBUtils.getActiveInstanceObject(request.getContext().getExecutionContext());
if (selectedObject != null) {
makeProposalsFromChildren(selectedObject, null, false, parameters);
rootObject = DBUtils.getPublicObject(selectedObject.getParentObject());
} else {
rootObject = dataSource;
}
}
if (rootObject != null) {
makeProposalsFromChildren(rootObject, null, false, parameters);
}
if (queryType == SQLCompletionRequest.QueryType.JOIN && !proposals.isEmpty() && dataSource instanceof DBSObjectContainer) {
// Filter out non-joinable tables
DBSObject leftTable = getTableFromAlias((DBSObjectContainer) dataSource, null, true);
if (leftTable instanceof DBSEntity) {
filterNonJoinableProposals((DBSEntity) leftTable);
}
}
} else {
DBSObject rootObject = null;
if (queryType == SQLCompletionRequest.QueryType.COLUMN && dataSource instanceof DBSObjectContainer) {
// Part of column name
// Try to get from active object
DBSObjectContainer sc = (DBSObjectContainer) dataSource;
DBSObject selectedObject = DBUtils.getActiveInstanceObject(request.getContext().getExecutionContext());
if (selectedObject instanceof DBSObjectContainer) {
sc = (DBSObjectContainer) selectedObject;
}
SQLDialect sqlDialect = request.getContext().getDataSource().getSQLDialect();
String tableAlias = null;
if (ALL_COLUMNS_PATTERN.equals(wordPart)) {
if (!isPrevWordEmpty) {
if (!prevKeyWord.equalsIgnoreCase("INTO")) {
String prevWord = wordDetector.getPrevWords().get(0);
if (prevWord.contains(sqlDialect.getCatalogSeparator())) {
int divPos = prevWord.lastIndexOf(sqlDialect.getCatalogSeparator());
tableAlias = prevWord.substring(0, divPos);
}
}
}
}
if (tableAlias == null) {
int divPos = wordPart.lastIndexOf(syntaxManager.getStructSeparator());
tableAlias = divPos == -1 ? null : wordPart.substring(0, divPos);
}
if (tableAlias == null && !CommonUtils.isEmpty(wordPart)) {
// May be an incomplete table alias. Try to find such table
rootObject = getTableFromAlias(sc, wordPart, false);
if (rootObject != null) {
// Found alias - no proposals
searchFinished = true;
return;
}
}
rootObject = getTableFromAlias(sc, tableAlias, false);
if (rootObject == null && tableAlias != null) {
// Maybe alias ss a table name
String[] allNames = SQLUtils.splitFullIdentifier(tableAlias, sqlDialect.getCatalogSeparator(), sqlDialect.getIdentifierQuoteStrings(), false);
rootObject = SQLSearchUtils.findObjectByFQN(monitor, sc, request.getContext().getExecutionContext(), Arrays.asList(allNames), !request.isSimpleMode(), wordDetector);
}
}
if (rootObject != null) {
makeProposalsFromChildren(rootObject, wordPart, false, parameters);
} else {
// Get root object or objects from active database (if any)
if (queryType != SQLCompletionRequest.QueryType.COLUMN && queryType != SQLCompletionRequest.QueryType.EXEC) {
makeDataSourceProposals();
}
}
}
if (!request.isSimpleMode() && (queryType == SQLCompletionRequest.QueryType.EXEC || (queryType == SQLCompletionRequest.QueryType.COLUMN && request.getContext().isSearchProcedures())) && dataSource instanceof DBSObjectContainer) {
makeProceduresProposals(dataSource, wordPart, true);
}
} else {
if (!request.isSimpleMode() && !CommonUtils.isEmpty(prevWords)) {
if (SQLConstants.KEYWORD_PROCEDURE.equals(previousWord) || SQLConstants.KEYWORD_FUNCTION.equals(previousWord)) {
makeProceduresProposals(dataSource, wordPart, false);
}
// may be useful in the future for procedures autocomplete
/*if (SQLConstants.BLOCK_BEGIN.equalsIgnoreCase(prevWords.get(0))) {
makeProceduresProposals(dataSource, wordPart, true);
}*/
}
}
if (!emptyWord) {
makeProposalsFromQueryParts();
}
// Final filtering
if (!searchFinished) {
List<String> matchedKeywords = Collections.emptyList();
Set<String> allowedKeywords = null;
SQLDialect sqlDialect = request.getContext().getDataSource().getSQLDialect();
if (CommonUtils.isEmpty(prevKeyWord)) {
allowedKeywords = new HashSet<>();
Collections.addAll(allowedKeywords, sqlDialect.getQueryKeywords());
Collections.addAll(allowedKeywords, sqlDialect.getDMLKeywords());
Collections.addAll(allowedKeywords, sqlDialect.getDDLKeywords());
Collections.addAll(allowedKeywords, sqlDialect.getExecuteKeywords());
} else if (ArrayUtils.contains(sqlDialect.getQueryKeywords(), prevKeyWord.toUpperCase(Locale.ENGLISH))) {
// SELECT ..
// Limit with FROM if we already have some expression
String delimiter = wordDetector.getPrevDelimiter();
if (!isPrevWordEmpty && (CommonUtils.isEmpty(delimiter) || delimiter.endsWith(")"))) {
// last expression ends with space or with ")"
allowedKeywords = new HashSet<>();
allowedKeywords.add(SQLConstants.KEYWORD_FROM);
if (CommonUtils.isEmpty(request.getWordPart())) {
matchedKeywords = Arrays.asList(SQLConstants.KEYWORD_FROM);
}
}
} else if (sqlDialect.isEntityQueryWord(prevKeyWord)) {
allowedKeywords = new HashSet<>();
if (SQLConstants.KEYWORD_DELETE.equals(prevKeyWord)) {
allowedKeywords.add(SQLConstants.KEYWORD_FROM);
} else {
allowedKeywords.add(SQLConstants.KEYWORD_WHERE);
}
}
if (!CommonUtils.isEmpty(request.getWordPart())) {
// Keyword assist
matchedKeywords = syntaxManager.getDialect().getMatchedKeywords(request.getWordPart());
if (!request.isSimpleMode()) {
// Sort using fuzzy match
matchedKeywords.sort(Comparator.comparingInt(o -> TextUtils.fuzzyScore(o, request.getWordPart())));
}
}
for (String keyWord : matchedKeywords) {
DBPKeywordType keywordType = syntaxManager.getDialect().getKeywordType(keyWord);
if (keywordType != null) {
if (keywordType == DBPKeywordType.TYPE) {
continue;
}
if (request.getQueryType() == SQLCompletionRequest.QueryType.COLUMN && !(keywordType == DBPKeywordType.FUNCTION || keywordType == DBPKeywordType.KEYWORD || keywordType == DBPKeywordType.OTHER)) {
continue;
}
if (allowedKeywords != null && !allowedKeywords.contains(keyWord)) {
continue;
}
proposals.add(SQLCompletionAnalyzer.createCompletionProposal(request, keyWord, keyWord, keywordType, null, false, null, Collections.emptyMap()));
}
}
}
filterProposals(dataSource);
}
Aggregations