🐛 fix(kingbase): 修复无模式前缀查询失败

- 缓存连接初始化时探测出的 search_path
- 新建固定会话后先同步 schema 搜索路径
- 补充金仓会话初始化顺序回归测试
This commit is contained in:
Syngnat
2026-07-24 18:12:25 +08:00
parent 7398873435
commit b40214e65c
2 changed files with 52 additions and 4 deletions

View File

@@ -420,8 +420,9 @@ func (c *optionalDriverAgentClient) close() error {
}
type OptionalDriverAgentDB struct {
driverType string
client *optionalDriverAgentClient
driverType string
client *optionalDriverAgentClient
kingbaseSearchPath string
}
type optionalDriverAgentTransactionalDB struct {
@@ -462,6 +463,7 @@ func newOptionalDriverAgentTransactionalDatabase(driverType string) databaseFact
}
func (d *OptionalDriverAgentDB) Connect(config connection.ConnectionConfig) error {
d.kingbaseSearchPath = ""
if d.client != nil {
_ = d.client.close()
d.client = nil
@@ -692,11 +694,18 @@ func (d *OptionalDriverAgentDB) OpenSessionExecer(ctx context.Context) (Statemen
if sessionID == "" {
return nil, fmt.Errorf("%s 驱动代理未返回事务会话 ID", driverDisplayName(d.driverType))
}
return &optionalDriverAgentSession{
session := &optionalDriverAgentSession{
client: client,
driver: d.driverType,
sessionID: sessionID,
}, nil
}
if searchPath := strings.TrimSpace(d.kingbaseSearchPath); searchPath != "" {
if _, err := session.ExecContext(ctx, fmt.Sprintf("SET search_path TO %s", searchPath)); err != nil {
_ = session.Close()
return nil, fmt.Errorf("人大金仓会话初始化 search_path 失败:%w", err)
}
}
return session, nil
}
func (d *optionalDriverAgentTransactionalDB) OpenTransactionExecer(ctx context.Context) (TransactionExecer, error) {
@@ -1086,6 +1095,7 @@ func (d *OptionalDriverAgentDB) ensureKingbaseSearchPath(config connection.Conne
if strings.TrimSpace(searchPath) == "" {
return
}
d.kingbaseSearchPath = searchPath
if _, err := d.ExecContext(ctx, fmt.Sprintf("SET search_path TO %s", searchPath)); err != nil {
logger.Warnf("人大金仓驱动代理设置 search_path 失败:%v", err)

View File

@@ -244,6 +244,44 @@ func TestOptionalDriverAgentDBQueryMultiWithMessagesParsesResultSets(t *testing.
}
}
func TestKingbaseOptionalDriverAgentSessionInitializesSearchPath(t *testing.T) {
var stdin optionalAgentTestWriteCloser
stdout := strings.Join([]string{
`{"id":1,"success":true,"data":"session-1"}`,
`{"id":2,"success":true,"rowsAffected":0}`,
`{"id":3,"success":true}`,
}, "\n") + "\n"
dbInst := &OptionalDriverAgentDB{
driverType: "kingbase",
kingbaseSearchPath: `"$user",public,ldf_server`,
client: &optionalDriverAgentClient{
stdin: &stdin,
reader: bufio.NewReader(strings.NewReader(stdout)),
driver: "kingbase",
},
}
session, err := dbInst.OpenSessionExecer(context.Background())
if err != nil {
t.Fatalf("OpenSessionExecer returned error: %v", err)
}
if err := session.Close(); err != nil {
t.Fatalf("Close returned error: %v", err)
}
requests := stdin.String()
for _, fragment := range []string{
`"method":"openSession"`,
`"method":"exec","sessionId":"session-1","query":"SET search_path TO \"$user\",public,ldf_server"`,
`"method":"closeSession","sessionId":"session-1"`,
} {
if !strings.Contains(requests, fragment) {
t.Fatalf("expected request fragment %q, got %s", fragment, requests)
}
}
}
func TestDamengOptionalDriverAgentSupportsManagedTransactions(t *testing.T) {
damengDB, err := NewDatabase("dameng")
if err != nil {