use of org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken in project dbeaver by dbeaver.
the class ExasolSQLDialect method extendRules.
@Override
public void extendRules(@NotNull List<IRule> rules, @NotNull SQLRuleProvider.RulePosition position) {
if (position == SQLRuleProvider.RulePosition.CONTROL) {
final SQLControlToken defineToken = new SQLControlToken(new TextAttribute(UIUtils.getGlobalColor(SQLConstants.CONFIG_COLOR_COMMAND), null, SWT.BOLD), "exasol.define");
// $NON-NLS-1$
SQLFullLineRule defineRule = new SQLFullLineRule("define", defineToken);
rules.add(defineRule);
// $NON-NLS-1$
SQLFullLineRule defineRule2 = new SQLFullLineRule("DEFINE", defineToken);
rules.add(defineRule2);
}
}
use of org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken in project dbeaver by dbeaver.
the class MySQLDialect method extendRules.
@Override
public void extendRules(@NotNull List<IRule> rules, @NotNull RulePosition position) {
if (position == RulePosition.CONTROL) {
final SQLControlToken sourceToken = new SQLControlToken(new TextAttribute(UIUtils.getGlobalColor(SQLConstants.CONFIG_COLOR_COMMAND), null, SWT.BOLD), "mysql.source");
// $NON-NLS-1$
SQLFullLineRule sourceRule2 = new SQLFullLineRule("SOURCE", sourceToken);
rules.add(sourceRule2);
}
}
use of org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLControlToken in project dbeaver by dbeaver.
the class SQLEditorBase method parseQuery.
protected SQLScriptElement parseQuery(final IDocument document, final int startPos, final int endPos, final int currentPos, final boolean scriptMode, final boolean keepDelimiters) {
if (endPos - startPos <= 0) {
return null;
}
SQLDialect dialect = getSQLDialect();
// Parse range
boolean useBlankLines = !scriptMode && syntaxManager.isBlankLineDelimiter();
ruleManager.setRange(document, startPos, endPos - startPos);
int statementStart = startPos;
int bracketDepth = 0;
boolean hasBlocks = false;
boolean hasValuableTokens = false;
boolean hasBlockHeader = false;
String blockTogglePattern = null;
int lastTokenLineFeeds = 0;
int prevNotEmptyTokenType = SQLToken.T_UNKNOWN;
for (; ; ) {
IToken token = ruleManager.nextToken();
int tokenOffset = ruleManager.getTokenOffset();
int tokenLength = ruleManager.getTokenLength();
int tokenType = token instanceof SQLToken ? ((SQLToken) token).getType() : SQLToken.T_UNKNOWN;
if (tokenOffset < startPos) {
// This may happen with EOF tokens (bug in jface?)
return null;
}
boolean isDelimiter = tokenType == SQLToken.T_DELIMITER;
boolean isControl = false;
String delimiterText = null;
try {
if (isDelimiter) {
// Save delimiter text
try {
delimiterText = document.get(tokenOffset, tokenLength);
} catch (BadLocationException e) {
log.debug(e);
}
} else if (useBlankLines && token.isWhitespace() && tokenLength >= 1) {
// Check for blank line delimiter
if (lastTokenLineFeeds + countLineFeeds(document, tokenOffset, tokenLength) >= 2) {
isDelimiter = true;
}
}
lastTokenLineFeeds = 0;
if (tokenLength == 1) {
// Check for bracket block begin/end
try {
char aChar = document.getChar(tokenOffset);
if (aChar == '(' || aChar == '{' || aChar == '[') {
bracketDepth++;
} else if (aChar == ')' || aChar == '}' || aChar == ']') {
bracketDepth--;
}
} catch (BadLocationException e) {
log.warn(e);
}
}
if (tokenType == SQLToken.T_BLOCK_BEGIN && prevNotEmptyTokenType == SQLToken.T_BLOCK_END) {
// This is a tricky thing.
// In some dialects block end looks like END CASE, END LOOP. It is parsed as
// Block end followed by block begin (as CASE and LOOP are block begin tokens)
// So let's ignore block begin if previos token was block end and there were no delimtiers.
tokenType = SQLToken.T_UNKNOWN;
}
if (tokenType == SQLToken.T_BLOCK_HEADER) {
bracketDepth++;
hasBlocks = true;
hasBlockHeader = true;
} else if (tokenType == SQLToken.T_BLOCK_TOGGLE) {
String togglePattern;
try {
togglePattern = document.get(tokenOffset, tokenLength);
} catch (BadLocationException e) {
log.warn(e);
togglePattern = "";
}
// Toggles can be nested (PostgreSQL) and we need to count only outer
if (bracketDepth == 1 && togglePattern.equals(blockTogglePattern)) {
bracketDepth--;
blockTogglePattern = null;
} else if (bracketDepth == 0 && blockTogglePattern == null) {
bracketDepth++;
blockTogglePattern = togglePattern;
} else {
log.debug("Block toggle token inside another block. Can't process it");
}
hasBlocks = true;
} else if (tokenType == SQLToken.T_BLOCK_BEGIN) {
if (!hasBlockHeader) {
bracketDepth++;
}
hasBlocks = true;
hasBlockHeader = false;
} else if (bracketDepth > 0 && tokenType == SQLToken.T_BLOCK_END) {
// This END doesn't mean block
if (hasBlocks) {
bracketDepth--;
}
hasBlockHeader = false;
} else if (isDelimiter && bracketDepth > 0) {
// Delimiter in some brackets - ignore it
continue;
} else if (tokenType == SQLToken.T_SET_DELIMITER || tokenType == SQLToken.T_CONTROL) {
isDelimiter = true;
isControl = true;
} else if (tokenType == SQLToken.T_COMMENT) {
lastTokenLineFeeds = tokenLength < 2 ? 0 : countLineFeeds(document, tokenOffset + tokenLength - 2, 2);
}
boolean cursorInsideToken = currentPos >= tokenOffset && currentPos < tokenOffset + tokenLength;
if (isControl && (scriptMode || cursorInsideToken) && !hasValuableTokens) {
// Control query
try {
String controlText = document.get(tokenOffset, tokenLength);
String commandId = null;
if (token instanceof SQLControlToken) {
commandId = ((SQLControlToken) token).getCommandId();
}
return new SQLControlCommand(getDataSource(), syntaxManager, controlText.trim(), commandId, tokenOffset, tokenLength, tokenType == SQLToken.T_SET_DELIMITER);
} catch (BadLocationException e) {
// $NON-NLS-1$
log.warn("Can't extract control statement", e);
return null;
}
}
if (hasValuableTokens && (token.isEOF() || (isDelimiter && tokenOffset >= currentPos) || tokenOffset > endPos)) {
if (tokenOffset > endPos) {
tokenOffset = endPos;
}
if (tokenOffset >= document.getLength()) {
// Sometimes (e.g. when comment finishing script text)
// last token offset is beyond document range
tokenOffset = document.getLength();
}
assert (tokenOffset >= currentPos);
try {
// remove leading spaces
while (statementStart < tokenOffset && Character.isWhitespace(document.getChar(statementStart))) {
statementStart++;
}
/*
while (statementStart < tokenOffset && Character.isWhitespace(document.getChar(tokenOffset - 1))) {
tokenOffset--;
tokenLength++;
}
*/
if (tokenOffset == statementStart) {
// Empty statement
if (token.isEOF()) {
return null;
}
statementStart = tokenOffset + tokenLength;
continue;
}
String queryText = document.get(statementStart, tokenOffset - statementStart);
queryText = SQLUtils.fixLineFeeds(queryText);
if (isDelimiter && (keepDelimiters || (hasBlocks ? dialect.isDelimiterAfterBlock() : dialect.isDelimiterAfterQuery()))) {
if (delimiterText != null && delimiterText.equals(SQLConstants.DEFAULT_STATEMENT_DELIMITER)) {
// Add delimiter in the end of query. Do this only for semicolon delimiters
// Quite dirty workaround needed for SQL server
queryText += delimiterText;
}
}
int queryEndPos = tokenOffset;
if (tokenType == SQLToken.T_DELIMITER) {
queryEndPos += tokenLength;
}
// make script line
return new SQLQuery(getDataSource(), queryText, statementStart, queryEndPos - statementStart);
} catch (BadLocationException ex) {
// $NON-NLS-1$
log.warn("Can't extract query", ex);
return null;
}
}
if (isDelimiter) {
statementStart = tokenOffset + tokenLength;
}
if (token.isEOF()) {
return null;
}
if (!hasValuableTokens && !token.isWhitespace() && !isControl) {
if (tokenType == SQLToken.T_COMMENT) {
hasValuableTokens = dialect.supportsCommentQuery();
} else {
hasValuableTokens = true;
}
}
} finally {
if (!token.isWhitespace() && !token.isEOF()) {
prevNotEmptyTokenType = tokenType;
}
}
}
}
Aggregations