Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
suliangchun
dbeaver
提交
82097d2e
D
dbeaver
项目概览
suliangchun
/
dbeaver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dbeaver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
82097d2e
编写于
4月 01, 2021
作者:
S
ShadelessFox
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#10858 Eliminate the usage of regex in favor of dialect-specific rules
上级
dde76df4
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
129 addition
and
97 deletion
+129
-97
bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java
bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java
+1
-1
plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/completion/SQLCompletionAnalyzer.java
...s/dbeaver/model/sql/completion/SQLCompletionAnalyzer.java
+111
-96
plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/completion/SQLCompletionRequest.java
...ss/dbeaver/model/sql/completion/SQLCompletionRequest.java
+17
-0
未找到文件。
bundles/org.jkiss.utils/src/org/jkiss/utils/CommonUtils.java
浏览文件 @
82097d2e
...
@@ -743,7 +743,7 @@ public class CommonUtils {
...
@@ -743,7 +743,7 @@ public class CommonUtils {
return
String
.
format
(
"%1$"
+
length
+
"s"
,
string
);
return
String
.
format
(
"%1$"
+
length
+
"s"
,
string
);
}
}
public
static
boolean
startsWithIgnoreCase
(
@N
otNull
String
str
,
@NotNull
String
startPart
)
{
public
static
boolean
startsWithIgnoreCase
(
@N
ullable
String
str
,
@Nullable
String
startPart
)
{
if
(
isEmpty
(
str
)
||
isEmpty
(
startPart
))
{
if
(
isEmpty
(
str
)
||
isEmpty
(
startPart
))
{
return
false
;
return
false
;
}
}
...
...
plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/completion/SQLCompletionAnalyzer.java
浏览文件 @
82097d2e
...
@@ -19,6 +19,8 @@ package org.jkiss.dbeaver.model.sql.completion;
...
@@ -19,6 +19,8 @@ package org.jkiss.dbeaver.model.sql.completion;
import
net.sf.jsqlparser.schema.Table
;
import
net.sf.jsqlparser.schema.Table
;
import
net.sf.jsqlparser.statement.Statement
;
import
net.sf.jsqlparser.statement.Statement
;
import
net.sf.jsqlparser.util.TablesNamesFinder
;
import
net.sf.jsqlparser.util.TablesNamesFinder
;
import
org.eclipse.jface.text.BadLocationException
;
import
org.eclipse.jface.text.IDocument
;
import
org.jkiss.code.NotNull
;
import
org.jkiss.code.NotNull
;
import
org.jkiss.code.Nullable
;
import
org.jkiss.code.Nullable
;
import
org.jkiss.dbeaver.DBException
;
import
org.jkiss.dbeaver.DBException
;
...
@@ -39,16 +41,18 @@ import org.jkiss.dbeaver.model.runtime.DBRRunnableParametrized;
...
@@ -39,16 +41,18 @@ import org.jkiss.dbeaver.model.runtime.DBRRunnableParametrized;
import
org.jkiss.dbeaver.model.sql.*
;
import
org.jkiss.dbeaver.model.sql.*
;
import
org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions
;
import
org.jkiss.dbeaver.model.sql.parser.SQLParserPartitions
;
import
org.jkiss.dbeaver.model.sql.parser.SQLWordPartDetector
;
import
org.jkiss.dbeaver.model.sql.parser.SQLWordPartDetector
;
import
org.jkiss.dbeaver.model.sql.parser.tokens.SQLTokenType
;
import
org.jkiss.dbeaver.model.struct.*
;
import
org.jkiss.dbeaver.model.struct.*
;
import
org.jkiss.dbeaver.model.text.TextUtils
;
import
org.jkiss.dbeaver.model.text.TextUtils
;
import
org.jkiss.dbeaver.model.text.parser.TPRuleBasedScanner
;
import
org.jkiss.dbeaver.model.text.parser.TPToken
;
import
org.jkiss.dbeaver.model.text.parser.TPTokenDefault
;
import
org.jkiss.utils.ArrayUtils
;
import
org.jkiss.utils.ArrayUtils
;
import
org.jkiss.utils.CommonUtils
;
import
org.jkiss.utils.CommonUtils
;
import
org.jkiss.utils.Pair
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.*
;
import
java.util.*
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.regex.PatternSyntaxException
;
/**
/**
* Completion analyzer
* Completion analyzer
...
@@ -168,7 +172,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -168,7 +172,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
DBPObject
rootObject
=
null
;
DBPObject
rootObject
=
null
;
if
(
queryType
==
SQLCompletionRequest
.
QueryType
.
COLUMN
&&
dataSource
instanceof
DBSObjectContainer
)
{
if
(
queryType
==
SQLCompletionRequest
.
QueryType
.
COLUMN
&&
dataSource
instanceof
DBSObjectContainer
)
{
// Try to detect current table
// Try to detect current table
rootObject
=
getTableFromAlias
((
DBSObjectContainer
)
dataSource
,
null
,
true
);
rootObject
=
getTableFromAlias
((
DBSObjectContainer
)
dataSource
,
null
);
if
(
rootObject
instanceof
DBSEntity
)
{
if
(
rootObject
instanceof
DBSEntity
)
{
switch
(
prevKeyWord
)
{
switch
(
prevKeyWord
)
{
case
SQLConstants
.
KEYWORD_ON
:
case
SQLConstants
.
KEYWORD_ON
:
...
@@ -210,7 +214,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -210,7 +214,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
}
}
if
(
queryType
==
SQLCompletionRequest
.
QueryType
.
JOIN
&&
!
proposals
.
isEmpty
()
&&
dataSource
instanceof
DBSObjectContainer
)
{
if
(
queryType
==
SQLCompletionRequest
.
QueryType
.
JOIN
&&
!
proposals
.
isEmpty
()
&&
dataSource
instanceof
DBSObjectContainer
)
{
// Filter out non-joinable tables
// Filter out non-joinable tables
DBSObject
leftTable
=
getTableFromAlias
((
DBSObjectContainer
)
dataSource
,
null
,
true
);
DBSObject
leftTable
=
getTableFromAlias
((
DBSObjectContainer
)
dataSource
,
null
);
if
(
leftTable
instanceof
DBSEntity
)
{
if
(
leftTable
instanceof
DBSEntity
)
{
filterNonJoinableProposals
((
DBSEntity
)
leftTable
);
filterNonJoinableProposals
((
DBSEntity
)
leftTable
);
}
}
...
@@ -244,14 +248,14 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -244,14 +248,14 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
}
}
if
(
tableAlias
==
null
&&
!
CommonUtils
.
isEmpty
(
wordPart
))
{
if
(
tableAlias
==
null
&&
!
CommonUtils
.
isEmpty
(
wordPart
))
{
// May be an incomplete table alias. Try to find such table
// May be an incomplete table alias. Try to find such table
rootObject
=
getTableFromAlias
(
sc
,
wordPart
,
false
);
rootObject
=
getTableFromAlias
(
sc
,
wordPart
);
if
(
rootObject
!=
null
)
{
if
(
rootObject
!=
null
)
{
// Found alias - no proposals
// Found alias - no proposals
searchFinished
=
true
;
searchFinished
=
true
;
return
;
return
;
}
}
}
}
rootObject
=
getTableFromAlias
(
sc
,
tableAlias
,
false
);
rootObject
=
getTableFromAlias
(
sc
,
tableAlias
);
if
(
rootObject
==
null
&&
tableAlias
!=
null
)
{
if
(
rootObject
==
null
&&
tableAlias
!=
null
)
{
// Maybe alias ss a table name
// Maybe alias ss a table name
String
[]
allNames
=
SQLUtils
.
splitFullIdentifier
(
String
[]
allNames
=
SQLUtils
.
splitFullIdentifier
(
...
@@ -540,19 +544,10 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -540,19 +544,10 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
if
(
wordPart
.
indexOf
(
request
.
getContext
().
getSyntaxManager
().
getStructSeparator
())
!=
-
1
||
wordPart
.
equals
(
ALL_COLUMNS_PATTERN
))
{
if
(
wordPart
.
indexOf
(
request
.
getContext
().
getSyntaxManager
().
getStructSeparator
())
!=
-
1
||
wordPart
.
equals
(
ALL_COLUMNS_PATTERN
))
{
return
;
return
;
}
}
SQLDialect
sqlDialect
=
request
.
getContext
().
getDataSource
().
getSQLDialect
();
final
Pair
<
String
,
String
>
name
=
extractTableName
(
wordPart
,
true
);
String
tableNamePattern
=
getTableNamePattern
(
sqlDialect
);
if
(
name
!=
null
)
{
String
tableAliasPattern
=
getTableAliasPattern
(
"("
+
wordPart
+
"[a-z]*)"
,
tableNamePattern
);
final
String
tableName
=
name
.
getFirst
();
Pattern
rp
=
Pattern
.
compile
(
tableAliasPattern
);
final
String
tableAlias
=
name
.
getSecond
();
// Append trailing space to let alias regex match correctly
Matcher
matcher
=
rp
.
matcher
(
request
.
getActiveQuery
().
getText
()
+
" "
);
while
(
matcher
.
find
())
{
String
tableName
=
matcher
.
group
(
1
);
String
tableAlias
=
matcher
.
group
(
2
);
if
(
tableAlias
.
equals
(
wordPart
))
{
continue
;
}
if
(!
hasProposal
(
proposals
,
tableName
))
{
if
(!
hasProposal
(
proposals
,
tableName
))
{
proposals
.
add
(
proposals
.
add
(
0
,
0
,
...
@@ -716,7 +711,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -716,7 +711,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
if
(
childObject
==
null
)
{
if
(
childObject
==
null
)
{
if
(
i
==
0
)
{
if
(
i
==
0
)
{
// Assume it's a table alias ?
// Assume it's a table alias ?
childObject
=
getTableFromAlias
(
sc
,
token
,
false
);
childObject
=
getTableFromAlias
(
sc
,
token
);
if
(
childObject
==
null
&&
!
request
.
isSimpleMode
())
{
if
(
childObject
==
null
&&
!
request
.
isSimpleMode
())
{
// Search using structure assistant
// Search using structure assistant
DBSStructureAssistant
structureAssistant
=
DBUtils
.
getAdapter
(
DBSStructureAssistant
.
class
,
sc
);
DBSStructureAssistant
structureAssistant
=
DBUtils
.
getAdapter
(
DBSStructureAssistant
.
class
,
sc
);
...
@@ -784,7 +779,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -784,7 +779,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
}
}
@Nullable
@Nullable
private
DBSObject
getTableFromAlias
(
DBSObjectContainer
sc
,
@Nullable
String
token
,
boolean
firstMatch
)
private
DBSObject
getTableFromAlias
(
DBSObjectContainer
sc
,
@Nullable
String
token
)
{
{
if
(
token
==
null
)
{
if
(
token
==
null
)
{
token
=
""
;
token
=
""
;
...
@@ -796,90 +791,110 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -796,90 +791,110 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
if
(
dataSource
==
null
)
{
if
(
dataSource
==
null
)
{
return
null
;
return
null
;
}
}
SQLScriptElement
activeQuery
=
request
.
getActiveQuery
();
if
(
activeQuery
==
null
)
{
final
SQLDialect
sqlDialect
=
dataSource
.
getSQLDialect
();
return
null
;
final
String
catalogSeparator
=
sqlDialect
.
getCatalogSeparator
();
while
(
token
.
endsWith
(
catalogSeparator
))
{
token
=
token
.
substring
(
0
,
token
.
length
()
-
1
);
}
}
final
List
<
String
>
nameList
=
new
ArrayList
<>();
final
Pair
<
String
,
String
>
name
=
extractTableName
(
token
,
false
);
SQLDialect
sqlDialect
=
dataSource
.
getSQLDialect
();
if
(
name
!=
null
&&
CommonUtils
.
isNotEmpty
(
name
.
getFirst
()))
{
{
final
String
[][]
quoteStrings
=
sqlDialect
.
getIdentifierQuoteStrings
();
// Regex matching MUST be very fast.
final
String
[]
allNames
=
SQLUtils
.
splitFullIdentifier
(
name
.
getFirst
(),
catalogSeparator
,
quoteStrings
,
false
);
// Otherwise UI will freeze during SQL typing.
return
SQLSearchUtils
.
findObjectByFQN
(
monitor
,
sc
,
request
.
getContext
().
getExecutionContext
(),
Arrays
.
asList
(
allNames
),
!
request
.
isSimpleMode
(),
request
.
getWordDetector
());
// So let's make regex as simple as possible.
}
// TODO: will be replaced by SQL preparse + structure analysis
// String quote = quoteString == null ? SQLConstants.STR_QUOTE_DOUBLE :
// SQLConstants.STR_QUOTE_DOUBLE.equals(quoteString) || SQLConstants.STR_QUOTE_APOS.equals(quoteString) ?
// quoteString :
// Pattern.quote(quoteString);
String
catalogSeparator
=
sqlDialect
.
getCatalogSeparator
();
while
(
token
.
endsWith
(
catalogSeparator
))
{
token
=
token
.
substring
(
0
,
token
.
length
()
-
1
);
}
// Use silly pattern with all possible characters
return
null
;
// Valid regex for quote identifiers and FQ names is monstrous and very slow
}
String
tableNamePattern
=
getTableNamePattern
(
sqlDialect
);
String
structNamePattern
;
if
(
CommonUtils
.
isEmpty
(
token
))
{
String
kwList
=
"from|update|join|into"
;
if
(
request
.
getQueryType
()
!=
SQLCompletionRequest
.
QueryType
.
COLUMN
)
{
kwList
=
kwList
+
"|,"
;
}
structNamePattern
=
"(?:"
+
kwList
+
")\\s+"
+
tableNamePattern
;
}
else
{
structNamePattern
=
getTableAliasPattern
(
token
,
tableNamePattern
);
}
Pattern
aliasPattern
;
@Nullable
try
{
private
Pair
<
String
,
String
>
extractTableName
(
@Nullable
String
tableAlias
,
boolean
allowPartialMatch
)
{
aliasPattern
=
Pattern
.
compile
(
structNamePattern
,
Pattern
.
CASE_INSENSITIVE
);
final
IDocument
document
=
request
.
getDocument
();
}
catch
(
PatternSyntaxException
e
)
{
final
TPRuleBasedScanner
scanner
=
request
.
getScanner
();
// Bad pattern - seems to be a bad token
final
SQLScriptElement
activeQuery
=
request
.
getActiveQuery
();
return
null
;
}
scanner
.
setRange
(
document
,
activeQuery
.
getOffset
(),
activeQuery
.
getLength
());
// Append trailing space to let alias regex match correctly
String
testQuery
=
SQLUtils
.
stripComments
(
request
.
getContext
().
getSyntaxManager
().
getDialect
(),
activeQuery
.
getText
())
+
" "
;
/*
Matcher
matcher
=
aliasPattern
.
matcher
(
testQuery
);
When we search for table name knowing its alias, we want to match the following sequence:
while
(
matcher
.
find
())
{
[FROM|UPDATE|JOIN|INTO] <table-name> [AS]? <known-alias-name>
if
(!
nameList
.
isEmpty
()
&&
(
firstMatch
||
matcher
.
start
()
>
request
.
getDocumentOffset
()
-
activeQuery
.
getOffset
()))
{
// Do not search after cursor
If we don't know the alias, the following sequence must be used instead:
[FROM|UPDATE|JOIN|INTO] <table-name>
We use "state machine" to process such sequences. The transition table is listed below:
UNMATCHED -> TABLE_NAME ; if found starting token (FROM, UPDATE, JOIN, INTO, etc.).
TABLE_NAME -> ALIAS_AS ; if found string token, and the alias is known.
TABLE_NAME -> MATCHED ; if found string token, and the alias is unknown.
ALIAS_AS -> ALIAS_NAME ; if found 'as' token.
ALIAS_NAME -> MATCHED ; if found string token.
*/
try
{
final
int
STATE_UNMATCHED
=
0
;
final
int
STATE_TABLE_NAME
=
1
;
final
int
STATE_ALIAS_AS
=
2
;
final
int
STATE_ALIAS_NAME
=
3
;
final
int
STATE_MATCHED
=
4
;
int
state
=
STATE_UNMATCHED
;
String
matchedTableName
=
null
;
String
matchedTableAlias
=
null
;
while
(
true
)
{
final
TPToken
tok
=
scanner
.
nextToken
();
if
(
tok
.
isEOF
())
{
break
;
break
;
}
}
nameList
.
clear
();
if
(!(
tok
instanceof
TPTokenDefault
))
{
int
groupCount
=
matcher
.
groupCount
();
continue
;
for
(
int
i
=
1
;
i
<=
groupCount
;
i
++)
{
}
String
group
=
matcher
.
group
(
i
);
final
String
value
=
document
.
get
(
scanner
.
getTokenOffset
(),
scanner
.
getTokenLength
());
if
(!
CommonUtils
.
isEmpty
(
group
))
{
if
(
state
==
STATE_UNMATCHED
&&
tok
.
getData
()
==
SQLTokenType
.
T_KEYWORD
&&
String
[][]
quoteStrings
=
sqlDialect
.
getIdentifierQuoteStrings
();
(
value
.
equalsIgnoreCase
(
SQLConstants
.
KEYWORD_FROM
)
||
value
.
equalsIgnoreCase
(
SQLConstants
.
KEYWORD_UPDATE
)
||
String
[]
allNames
=
SQLUtils
.
splitFullIdentifier
(
group
,
catalogSeparator
,
quoteStrings
,
false
);
value
.
equalsIgnoreCase
(
SQLConstants
.
KEYWORD_JOIN
)
||
Collections
.
addAll
(
nameList
,
allNames
);
value
.
equalsIgnoreCase
(
SQLConstants
.
KEYWORD_INTO
)))
{
state
=
STATE_TABLE_NAME
;
continue
;
}
if
(
state
==
STATE_TABLE_NAME
&&
(
tok
.
getData
()
==
SQLTokenType
.
T_QUOTED
||
tok
.
getData
()
==
SQLTokenType
.
T_OTHER
))
{
matchedTableName
=
value
;
if
(
CommonUtils
.
isEmpty
(
tableAlias
))
{
state
=
STATE_MATCHED
;
}
else
{
state
=
STATE_ALIAS_AS
;
continue
;
}
}
if
(
state
==
STATE_ALIAS_AS
&&
tok
.
getData
()
==
SQLTokenType
.
T_KEYWORD
&&
"AS"
.
equalsIgnoreCase
(
value
))
{
state
=
STATE_ALIAS_NAME
;
continue
;
}
if
((
state
==
STATE_ALIAS_AS
||
state
==
STATE_ALIAS_NAME
)
&&
(
tok
.
getData
()
==
SQLTokenType
.
T_QUOTED
||
tok
.
getData
()
==
SQLTokenType
.
T_OTHER
))
{
matchedTableAlias
=
value
;
state
=
STATE_MATCHED
;
}
if
(
state
==
STATE_MATCHED
)
{
final
boolean
fullMatch
=
CommonUtils
.
isEmpty
(
tableAlias
)
||
tableAlias
.
equals
(
matchedTableAlias
);
final
boolean
partialMatch
=
fullMatch
||
(
allowPartialMatch
&&
CommonUtils
.
startsWithIgnoreCase
(
matchedTableAlias
,
tableAlias
));
if
(!
fullMatch
&&
!
partialMatch
)
{
// The presented alias does not fully or partially match the matched token, reset
state
=
STATE_UNMATCHED
;
matchedTableName
=
null
;
matchedTableAlias
=
null
;
}
else
{
return
new
Pair
<>(
matchedTableName
,
matchedTableAlias
);
}
}
}
}
}
}
}
catch
(
BadLocationException
e
)
{
log
.
debug
(
e
);
}
}
return
SQLSearchUtils
.
findObjectByFQN
(
monitor
,
sc
,
request
.
getContext
().
getExecutionContext
(),
nameList
,
!
request
.
isSimpleMode
(),
request
.
getWordDetector
());
return
null
;
}
private
String
getTableAliasPattern
(
String
alias
,
String
tableNamePattern
)
{
return
tableNamePattern
+
"\\s+(?:as\\s)?"
+
alias
+
"[\\s,]+"
;
}
private
static
String
getTableNamePattern
(
SQLDialect
sqlDialect
)
{
String
[][]
quoteStrings
=
sqlDialect
.
getIdentifierQuoteStrings
();
StringBuilder
quotes
=
new
StringBuilder
();
if
(
quoteStrings
!=
null
)
{
for
(
String
[]
quotePair
:
quoteStrings
)
{
if
(
quotes
.
indexOf
(
quotePair
[
0
])
==
-
1
)
quotes
.
append
(
'\\'
).
append
(
quotePair
[
0
]);
if
(
quotes
.
indexOf
(
quotePair
[
1
])
==
-
1
)
quotes
.
append
(
'\\'
).
append
(
quotePair
[
1
]);
}
}
// Use silly pattern with all possible characters
// Valid regex for quote identifiers and FQ names is monstrous and very slow
return
"([\\p{L}0-9_$§#@\\.\\-"
+
quotes
.
toString
()
+
"]+)"
;
}
}
private
void
makeProposalsFromChildren
(
DBPObject
parent
,
@Nullable
String
startPart
,
boolean
addFirst
,
Map
<
String
,
Object
>
params
)
throws
DBException
{
private
void
makeProposalsFromChildren
(
DBPObject
parent
,
@Nullable
String
startPart
,
boolean
addFirst
,
Map
<
String
,
Object
>
params
)
throws
DBException
{
...
@@ -1115,7 +1130,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
...
@@ -1115,7 +1130,7 @@ public class SQLCompletionAnalyzer implements DBRRunnableParametrized<DBRProgres
if
(
aliases
.
contains
(
s
)
||
sqlDialect
.
getKeywordType
(
s
)
!=
null
)
{
if
(
aliases
.
contains
(
s
)
||
sqlDialect
.
getKeywordType
(
s
)
!=
null
)
{
return
true
;
return
true
;
}
}
return
Pattern
.
compile
(
"\\s+"
+
s
+
"[^\\w]+"
).
matcher
(
queryText
).
find
()
;
return
extractTableName
(
s
,
false
)
!=
null
;
});
});
if
(
alias
.
equalsIgnoreCase
(
object
.
getName
()))
{
if
(
alias
.
equalsIgnoreCase
(
object
.
getName
()))
{
// Don't use alias, when it's identical to entity name
// Don't use alias, when it's identical to entity name
...
...
plugins/org.jkiss.dbeaver.model.sql/src/org/jkiss/dbeaver/model/sql/completion/SQLCompletionRequest.java
浏览文件 @
82097d2e
...
@@ -18,7 +18,10 @@ package org.jkiss.dbeaver.model.sql.completion;
...
@@ -18,7 +18,10 @@ package org.jkiss.dbeaver.model.sql.completion;
import
org.eclipse.jface.text.IDocument
;
import
org.eclipse.jface.text.IDocument
;
import
org.jkiss.dbeaver.model.sql.SQLScriptElement
;
import
org.jkiss.dbeaver.model.sql.SQLScriptElement
;
import
org.jkiss.dbeaver.model.sql.SQLSyntaxManager
;
import
org.jkiss.dbeaver.model.sql.parser.SQLRuleManager
;
import
org.jkiss.dbeaver.model.sql.parser.SQLWordPartDetector
;
import
org.jkiss.dbeaver.model.sql.parser.SQLWordPartDetector
;
import
org.jkiss.dbeaver.model.text.parser.TPRuleBasedScanner
;
public
class
SQLCompletionRequest
{
public
class
SQLCompletionRequest
{
...
@@ -35,6 +38,7 @@ public class SQLCompletionRequest {
...
@@ -35,6 +38,7 @@ public class SQLCompletionRequest {
private
final
SQLScriptElement
activeQuery
;
private
final
SQLScriptElement
activeQuery
;
private
final
boolean
simpleMode
;
private
final
boolean
simpleMode
;
private
final
TPRuleBasedScanner
scanner
;
private
final
SQLWordPartDetector
wordDetector
;
private
final
SQLWordPartDetector
wordDetector
;
private
String
wordPart
;
private
String
wordPart
;
...
@@ -48,6 +52,15 @@ public class SQLCompletionRequest {
...
@@ -48,6 +52,15 @@ public class SQLCompletionRequest {
this
.
activeQuery
=
activeQuery
;
this
.
activeQuery
=
activeQuery
;
this
.
simpleMode
=
simpleMode
;
this
.
simpleMode
=
simpleMode
;
final
SQLSyntaxManager
syntaxManager
=
new
SQLSyntaxManager
();
syntaxManager
.
init
(
context
.
getDataSource
());
final
SQLRuleManager
ruleManager
=
new
SQLRuleManager
(
syntaxManager
);
ruleManager
.
loadRules
(
context
.
getDataSource
(),
false
);
this
.
scanner
=
new
TPRuleBasedScanner
();
this
.
scanner
.
setRules
(
ruleManager
.
getAllRules
());
this
.
wordDetector
=
new
SQLWordPartDetector
(
document
,
context
.
getSyntaxManager
(),
documentOffset
);
this
.
wordDetector
=
new
SQLWordPartDetector
(
document
,
context
.
getSyntaxManager
(),
documentOffset
);
this
.
wordPart
=
wordDetector
.
getWordPart
();
this
.
wordPart
=
wordDetector
.
getWordPart
();
}
}
...
@@ -72,6 +85,10 @@ public class SQLCompletionRequest {
...
@@ -72,6 +85,10 @@ public class SQLCompletionRequest {
return
simpleMode
;
return
simpleMode
;
}
}
public
TPRuleBasedScanner
getScanner
()
{
return
scanner
;
}
public
SQLWordPartDetector
getWordDetector
()
{
public
SQLWordPartDetector
getWordDetector
()
{
return
wordDetector
;
return
wordDetector
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录