mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-13 00:13:33 +08:00
🐛 fix(sql-editor): 修复存储过程与返回结果写语句的结果识别
- 补齐 SQL 分类逻辑,识别 SQL Server 裸存储过程调用、RETURNING/OUTPUT、SELECT INTO 及消息块场景 - 调整多语句执行与批量写入分支,避免返回行或服务端消息被 Exec 路径吞掉 - 为 PostgreSQL、OpenGauss、Kingbase、HighGo 补充 notice 回传能力并增加回归测试
This commit is contained in:
@@ -336,6 +336,105 @@ func isSQLKeywordByte(ch byte) bool {
|
||||
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_'
|
||||
}
|
||||
|
||||
func normalizeSQLClassifierDBType(dbType string) string {
|
||||
normalized := strings.ToLower(strings.TrimSpace(dbType))
|
||||
switch normalized {
|
||||
case "postgresql":
|
||||
return "postgres"
|
||||
case "mssql", "sql_server", "sql-server":
|
||||
return "sqlserver"
|
||||
case "open_gauss", "open-gauss":
|
||||
return "opengauss"
|
||||
case "gauss_db", "gauss-db":
|
||||
return "gaussdb"
|
||||
case "kingbase8", "kingbasees", "kingbasev8":
|
||||
return "kingbase"
|
||||
default:
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
|
||||
func isSQLServerDBType(dbType string) bool {
|
||||
return normalizeSQLClassifierDBType(dbType) == "sqlserver"
|
||||
}
|
||||
|
||||
func isOracleLikeDBType(dbType string) bool {
|
||||
switch normalizeSQLClassifierDBType(dbType) {
|
||||
case "oracle", "dameng":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isPostgresNoticeCapableDBType(dbType string) bool {
|
||||
switch normalizeSQLClassifierDBType(dbType) {
|
||||
case "postgres", "opengauss":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isSQLSelectIntoStatement(query string) bool {
|
||||
keyword, _ := sqlDataOperationInfo(query)
|
||||
return keyword == "select" && findTopLevelSQLKeyword(query, 0, "into") >= 0
|
||||
}
|
||||
|
||||
func sqlContainsKeyword(text string, want string) bool {
|
||||
for pos := 0; pos < len(text); {
|
||||
if next, ok := skipSQLQuotedOrComment(text, pos); ok {
|
||||
pos = next
|
||||
continue
|
||||
}
|
||||
if isSQLKeywordByte(text[pos]) {
|
||||
end := pos + 1
|
||||
for end < len(text) && isSQLKeywordByte(text[end]) {
|
||||
end++
|
||||
}
|
||||
if strings.EqualFold(text[pos:end], want) {
|
||||
return true
|
||||
}
|
||||
pos = end
|
||||
continue
|
||||
}
|
||||
pos++
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func sqlWriteStatementReturnsRows(dbType string, query string) bool {
|
||||
keyword, withHasWrite := sqlDataOperationInfo(query)
|
||||
if withHasWrite && keyword == "select" {
|
||||
return true
|
||||
}
|
||||
if !isSQLDataWriteKeyword(keyword) {
|
||||
return false
|
||||
}
|
||||
if !isOracleLikeDBType(dbType) && findTopLevelSQLKeyword(query, 0, "returning") >= 0 {
|
||||
return true
|
||||
}
|
||||
if isSQLServerDBType(dbType) && findTopLevelSQLKeyword(query, 0, "output") >= 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func sqlServerControlFlowMayReturnMessages(query string) bool {
|
||||
switch leadingSQLKeyword(query) {
|
||||
case "if", "begin", "while", "declare", "try", "catch":
|
||||
return sqlContainsKeyword(query, "exec") ||
|
||||
sqlContainsKeyword(query, "execute") ||
|
||||
sqlContainsKeyword(query, "print") ||
|
||||
sqlContainsKeyword(query, "raiserror") ||
|
||||
sqlContainsKeyword(query, "throw") ||
|
||||
sqlContainsKeyword(query, "dbcc") ||
|
||||
sqlContainsKeyword(query, "set")
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isReadOnlySQLQuery(dbType string, query string) bool {
|
||||
if strings.ToLower(strings.TrimSpace(dbType)) == "mongodb" && strings.HasPrefix(strings.TrimSpace(query), "{") {
|
||||
return true
|
||||
@@ -345,6 +444,9 @@ func isReadOnlySQLQuery(dbType string, query string) bool {
|
||||
if withHasWrite {
|
||||
return false
|
||||
}
|
||||
if keyword == "select" && isSQLSelectIntoStatement(query) {
|
||||
return false
|
||||
}
|
||||
switch keyword {
|
||||
case "select", "with", "show", "describe", "desc", "explain", "pragma", "values", "consume":
|
||||
return true
|
||||
@@ -362,6 +464,9 @@ func isBatchableWriteSQLStatement(dbType string, query string) bool {
|
||||
if withHasWrite {
|
||||
return true
|
||||
}
|
||||
if keyword == "select" && isSQLSelectIntoStatement(query) {
|
||||
return true
|
||||
}
|
||||
return isSQLDataWriteKeyword(keyword)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user