From 21fd13b3fb44fd6ace97d5cf86a16e64b0f5a404 Mon Sep 17 00:00:00 2001 From: ShadelessFox Date: Tue, 29 Jun 2021 20:12:25 +0300 Subject: [PATCH] #12182 Move word start/part checks to dialect; proposals fix --- .../ext/mssql/model/SQLServerDialect.java | 10 +++++++++ .../model/sql/parser/SQLRuleManager.java | 2 +- .../model/sql/parser/rules/SQLWordRule.java | 22 +++++++++++-------- .../model/impl/sql/AbstractSQLDialect.java | 10 +++++++++ .../jkiss/dbeaver/model/sql/SQLDialect.java | 4 ++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDialect.java b/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDialect.java index 257c78cc65..b1a882f8dd 100644 --- a/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDialect.java +++ b/plugins/org.jkiss.dbeaver.ext.mssql/src/org/jkiss/dbeaver/ext/mssql/model/SQLServerDialect.java @@ -293,6 +293,16 @@ public class SQLServerDialect extends JDBCSQLDialect implements TPRuleProvider { return super.getUnquotedString(string); } + @Override + public boolean isWordStart(int ch) { + return super.isWordStart(ch) || ch == '#'; + } + + @Override + public boolean isWordPart(int ch) { + return super.isWordPart(ch) || ch == '#'; + } + @Override public String[] getSingleLineComments() { if (!isSqlServer) { diff --git a/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/SQLRuleManager.java b/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/SQLRuleManager.java index 059cc481c0..ad3e40ca3a 100644 --- a/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/SQLRuleManager.java +++ b/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/SQLRuleManager.java @@ -202,7 +202,7 @@ public class SQLRuleManager { if (!minimalRules) { // Add word rule for keywords, functions, types, and constants. - SQLWordRule wordRule = new SQLWordRule(delimRule, typeToken, otherToken); + SQLWordRule wordRule = new SQLWordRule(delimRule, typeToken, otherToken, dialect); for (String reservedWord : dialect.getReservedWords()) { DBPKeywordType keywordType = dialect.getKeywordType(reservedWord); // Functions without parentheses has type 'DBPKeywordType.OTHER' (#8710) diff --git a/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLWordRule.java b/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLWordRule.java index 4874028f41..00269fec22 100644 --- a/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLWordRule.java +++ b/plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/parser/rules/SQLWordRule.java @@ -16,6 +16,8 @@ */ package org.jkiss.dbeaver.model.sql.parser.rules; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.sql.SQLDialect; import org.jkiss.dbeaver.model.text.parser.TPCharacterScanner; import org.jkiss.dbeaver.model.text.parser.TPRule; import org.jkiss.dbeaver.model.text.parser.TPToken; @@ -32,18 +34,20 @@ import java.util.Set; */ public class SQLWordRule implements TPRule { - private SQLDelimiterRule delimRule; - private TPToken functionToken; - private TPToken defaultToken; - private Map words = new HashMap<>(); - private Set functions = new HashSet<>(); - private StringBuilder buffer = new StringBuilder(); + private final SQLDelimiterRule delimRule; + private final TPToken functionToken; + private final TPToken defaultToken; + private final Map words = new HashMap<>(); + private final Set functions = new HashSet<>(); + private final StringBuilder buffer = new StringBuilder(); + private final SQLDialect dialect; private char[][] delimiters; - public SQLWordRule(SQLDelimiterRule delimRule, TPToken functionToken, TPToken defaultToken) { + public SQLWordRule(SQLDelimiterRule delimRule, TPToken functionToken, TPToken defaultToken, @NotNull SQLDialect dialect) { this.delimRule = delimRule; this.functionToken = functionToken; this.defaultToken = defaultToken; + this.dialect = dialect; } public boolean hasWord(String word) { @@ -65,7 +69,7 @@ public class SQLWordRule implements TPRule { @Override public TPToken evaluate(TPCharacterScanner scanner) { int c = scanner.read(); - if (c != TPCharacterScanner.EOF && Character.isUnicodeIdentifierStart(c)) { + if (c != TPCharacterScanner.EOF && dialect.isWordStart(c)) { buffer.setLength(0); delimiters = delimRule.getDelimiters(); char prevC; @@ -108,7 +112,7 @@ public class SQLWordRule implements TPRule { } private boolean isWordPart(char c, char prevC, TPCharacterScanner scanner) { - if (!Character.isUnicodeIdentifierPart(c) && c != '$') { + if (!dialect.isWordPart(c) && c != '$') { return false; } if (c == '$' && prevC == '$') { diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/sql/AbstractSQLDialect.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/sql/AbstractSQLDialect.java index 16c88dc53d..46db46c0f1 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/sql/AbstractSQLDialect.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/sql/AbstractSQLDialect.java @@ -298,6 +298,16 @@ public abstract class AbstractSQLDialect implements SQLDialect { return null; } + @Override + public boolean isWordStart(int ch) { + return Character.isUnicodeIdentifierStart(ch); + } + + @Override + public boolean isWordPart(int ch) { + return Character.isUnicodeIdentifierPart(ch); + } + @Override public boolean validIdentifierStart(char c) { return Character.isLetter(c); diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLDialect.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLDialect.java index 8a5dfda100..04c7b1744f 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLDialect.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/sql/SQLDialect.java @@ -233,6 +233,10 @@ public interface SQLDialect { @NotNull SQLStateType getSQLStateType(); + boolean isWordStart(int ch); + + boolean isWordPart(int ch); + boolean validIdentifierStart(char c); /** * Checks that specified character is a valid identifier part. Non-valid characters should be quoted in queries. -- GitLab