mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-12 16:02:48 +08:00
🐛 fix(tdengine): 修复低版本驱动连接与表元数据兼容问题
- 修复 TDengine 历史驱动源码构建未按所选版本切换依赖的问题 - 为 DESCRIBE 与 SHOW CREATE 增加旧版本语法降级,避免表详情加载报错 - 为表概览补充 TDengine 专用查询分支,避免误查 information_schema - 补充 TDengine 兼容性与驱动构建回归测试 Refs #531
This commit is contained in:
@@ -5,6 +5,7 @@ package db
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
@@ -267,11 +268,7 @@ func (t *TDengineDB) GetTables(dbName string) ([]string, error) {
|
||||
}
|
||||
|
||||
func (t *TDengineDB) GetCreateStatement(dbName, tableName string) (string, error) {
|
||||
qualified := quoteTDengineTable(dbName, tableName)
|
||||
queries := []string{
|
||||
fmt.Sprintf("SHOW CREATE TABLE %s", qualified),
|
||||
fmt.Sprintf("SHOW CREATE STABLE %s", qualified),
|
||||
}
|
||||
queries := tdengineCreateStatementQueries(dbName, tableName)
|
||||
|
||||
var lastErr error
|
||||
for _, query := range queries {
|
||||
@@ -308,9 +305,25 @@ func (t *TDengineDB) GetCreateStatement(dbName, tableName string) (string, error
|
||||
}
|
||||
|
||||
func (t *TDengineDB) GetColumns(dbName, tableName string) ([]connection.ColumnDefinition, error) {
|
||||
query := fmt.Sprintf("DESCRIBE %s", quoteTDengineTable(dbName, tableName))
|
||||
data, _, err := t.Query(query)
|
||||
var (
|
||||
data []map[string]interface{}
|
||||
err error
|
||||
lastErr error
|
||||
)
|
||||
for _, query := range tdengineDescribeQueries(dbName, tableName) {
|
||||
data, _, err = t.Query(query)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
lastErr = err
|
||||
if !isTDengineSyntaxCompatibilityError(err) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if lastErr != nil {
|
||||
return nil, lastErr
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -502,6 +515,77 @@ func escapeBacktickIdent(ident string) string {
|
||||
return strings.ReplaceAll(strings.TrimSpace(ident), "`", "``")
|
||||
}
|
||||
|
||||
func tdengineDescribeQueries(dbName, tableName string) []string {
|
||||
qualified := quoteTDengineTable(dbName, tableName)
|
||||
legacyQualified := quoteTDengineTableLegacy(dbName, tableName)
|
||||
queries := []string{fmt.Sprintf("DESCRIBE %s", qualified)}
|
||||
if legacyQualified != qualified {
|
||||
queries = append(queries, fmt.Sprintf("DESCRIBE %s", legacyQualified))
|
||||
}
|
||||
return queries
|
||||
}
|
||||
|
||||
func tdengineCreateStatementQueries(dbName, tableName string) []string {
|
||||
queries := make([]string, 0, 4)
|
||||
appendQualifiedQueries := func(qualified string) {
|
||||
if strings.TrimSpace(qualified) == "" {
|
||||
return
|
||||
}
|
||||
queries = append(queries,
|
||||
fmt.Sprintf("SHOW CREATE TABLE %s", qualified),
|
||||
fmt.Sprintf("SHOW CREATE STABLE %s", qualified),
|
||||
)
|
||||
}
|
||||
qualified := quoteTDengineTable(dbName, tableName)
|
||||
appendQualifiedQueries(qualified)
|
||||
legacyQualified := quoteTDengineTableLegacy(dbName, tableName)
|
||||
if legacyQualified != qualified {
|
||||
appendQualifiedQueries(legacyQualified)
|
||||
}
|
||||
return queries
|
||||
}
|
||||
|
||||
func quoteTDengineTableLegacy(dbName, tableName string) string {
|
||||
table := strings.TrimSpace(tableName)
|
||||
if table == "" {
|
||||
return ""
|
||||
}
|
||||
if strings.Contains(table, ".") {
|
||||
return strings.Join(splitTDengineIdentifierParts(table), ".")
|
||||
}
|
||||
db := strings.TrimSpace(dbName)
|
||||
if db == "" {
|
||||
return table
|
||||
}
|
||||
return db + "." + table
|
||||
}
|
||||
|
||||
func splitTDengineIdentifierParts(path string) []string {
|
||||
parts := strings.Split(strings.TrimSpace(path), ".")
|
||||
result := make([]string, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
trimmed := strings.Trim(strings.TrimSpace(part), "`")
|
||||
if trimmed == "" {
|
||||
continue
|
||||
}
|
||||
result = append(result, trimmed)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func isTDengineSyntaxCompatibilityError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
text := strings.ToLower(strings.TrimSpace(err.Error()))
|
||||
if text == "" {
|
||||
return false
|
||||
}
|
||||
return strings.Contains(text, "syntax error near") ||
|
||||
strings.Contains(text, "[0x2600]") ||
|
||||
errors.Is(err, sql.ErrNoRows)
|
||||
}
|
||||
|
||||
func quoteTDengineTable(dbName, tableName string) string {
|
||||
t := escapeBacktickIdent(tableName)
|
||||
if t == "" {
|
||||
|
||||
Reference in New Issue
Block a user