fix(oracle): apply visible schema filter

This commit is contained in:
t8y2 committed 2026-06-25 15:19:20 +08:00
1 parent 1ded7e8332
commit b2edf7cad6
20 files changed
+469 -102

No files matched your search

+66 -3
View File
@@ -323,7 +323,7 @@ func (s *server) dispatch(method string, params map[string]json.RawMessage) (any
result, err := s.listDatabases()
return result, false, err
case "list_schemas":
result, err := s.listSchemas()
result, err := s.listSchemas(stringSliceParam(params, "visible_schemas"))
return result, false, err
case "list_tables":
schema := stringParam(params, "schema")
@@ -570,8 +570,11 @@ func (s *server) currentSchemaDatabase() ([]databaseInfo, error) {
return []databaseInfo{{Name: schema}}, nil
}
func (s *server) listSchemas() ([]string, error) {
databases, err := s.listDatabases()
func (s *server) listSchemas(visibleSchemas []string) ([]string, error) {
if visibleSchemas != nil && len(visibleSchemas) == 0 {
return []string{}, nil
}
databases, err := s.listDatabasesFiltered(visibleSchemas)
if err != nil {
return nil, err
}
@@ -582,6 +585,55 @@ func (s *server) listSchemas() ([]string, error) {
return emptyIfNil(result), nil
}
func (s *server) listDatabasesFiltered(visibleSchemas []string) ([]databaseInfo, error) {
if visibleSchemas == nil {
return s.listDatabases()
}
sqlText, args := oracleListDatabasesSQLWithVisibleSchemas(visibleSchemas)
rows, err := s.queryRows(sqlText, args)
if err != nil {
if isOraclePGALimitError(err) {
return s.currentSchemaDatabase()
}
return nil, err
}
defer rows.Close()
var result []databaseInfo
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
return nil, err
}
result = append(result, databaseInfo{Name: name})
}
if err := rows.Err(); err != nil {
if isOraclePGALimitError(err) {
return s.currentSchemaDatabase()
}
return nil, err
}
return emptyIfNil(result), nil
}
func oracleListDatabasesSQLWithVisibleSchemas(visibleSchemas []string) (string, []any) {
if len(visibleSchemas) == 0 {
return oracleListDatabasesSQL, nil
}
placeholders := make([]string, 0, len(visibleSchemas))
args := make([]any, 0, len(visibleSchemas))
for i, schema := range visibleSchemas {
placeholders = append(placeholders, fmt.Sprintf(":%d", i+1))
args = append(args, schema)
}
sqlText := strings.Replace(
oracleListDatabasesSQL,
"\nORDER BY CASE",
"\n AND username IN ("+strings.Join(placeholders, ",")+")\nORDER BY CASE",
1,
)
return sqlText, args
}
func (s *server) currentSchema() (string, error) {
db, err := s.requireDB()
if err != nil {
@@ -1352,6 +1404,17 @@ func stringParam(params map[string]json.RawMessage, key string) string {
return value
}
func stringSliceParam(params map[string]json.RawMessage, key string) []string {
if params == nil || len(params[key]) == 0 {
return nil
}
var value []string
if err := json.Unmarshal(params[key], &value); err != nil {
return nil
}
return value
}
func intParam(params map[string]json.RawMessage, key string) int {
if params == nil || len(params[key]) == 0 {
return 0
+18
View File
@@ -265,6 +265,24 @@ func TestListDatabasesSQLUsesUserDictionaryInsteadOfObjectDictionary(t *testing.
}
}
func TestListDatabasesSQLCanApplyVisibleSchemaFilter(t *testing.T) {
sqlText, args := oracleListDatabasesSQLWithVisibleSchemas([]string{"APP", "REPORTING"})
upperSQL := strings.ToUpper(sqlText)
if !strings.Contains(upperSQL, "ALL_USERS") {
t.Fatalf("schema listing should query ALL_USERS, got: %s", sqlText)
}
if !strings.Contains(upperSQL, "USERNAME IN (:1,:2)") {
t.Fatalf("schema listing should apply visible schema filter, got: %s", sqlText)
}
if len(args) != 2 || args[0] != "APP" || args[1] != "REPORTING" {
t.Fatalf("visible schema args were not preserved: %#v", args)
}
if strings.Contains(upperSQL, "ALL_TABLES") || strings.Contains(upperSQL, "ALL_VIEWS") {
t.Fatalf("schema listing should not scan object dictionaries, got: %s", sqlText)
}
}
func TestListTablesSQLUsesSplitDictionaryQuery(t *testing.T) {
sqlText := strings.ToUpper(oracleListTablesSQL)