perf(oracle): fetch view source from ALL_VIEWS before GET_DDL

This commit is contained in:
zipg
2026-09-14 17:51:49 +08:00
committed by GitHub
parent d9154ee2b7
commit 2e3b7da533
3 changed files with 43 additions and 38 deletions
+14 -16
View File
@@ -3401,6 +3401,15 @@ func (s *server) getViewSource(schema, name string) (string, error) {
return "", err
}
viewName := strings.TrimSpace(name)
var source string
viewsErr := db.QueryRow(
"SELECT TEXT FROM ALL_VIEWS WHERE OWNER = :1 AND VIEW_NAME = :2",
schema, viewName,
).Scan(&source)
if viewsErr == nil && strings.TrimSpace(source) != "" {
return strings.TrimSpace(source), nil
}
var ddl string
metadataErr := db.QueryRow(
"SELECT DBMS_METADATA.GET_DDL('VIEW', :1, :2) FROM DUAL",
@@ -3410,22 +3419,11 @@ func (s *server) getViewSource(schema, name string) (string, error) {
return strings.TrimSpace(ddl), nil
}
var source string
fallbackErr := db.QueryRow(
"SELECT TEXT FROM ALL_VIEWS WHERE OWNER = :1 AND VIEW_NAME = :2",
schema, viewName,
).Scan(&source)
if fallbackErr == nil && strings.TrimSpace(source) != "" {
return strings.TrimSpace(source), nil
}
if fallbackErr != nil && !errors.Is(fallbackErr, sql.ErrNoRows) {
if metadataErr != nil {
return "", fmt.Errorf(
"failed to load view source for %s.%s: DBMS_METADATA: %v; ALL_VIEWS: %w",
schema, viewName, metadataErr, fallbackErr,
)
}
return "", fmt.Errorf("failed to load view source for %s.%s from ALL_VIEWS: %w", schema, viewName, fallbackErr)
if viewsErr != nil && !errors.Is(viewsErr, sql.ErrNoRows) && metadataErr != nil {
return "", fmt.Errorf(
"failed to load view source for %s.%s: ALL_VIEWS: %v; DBMS_METADATA: %w",
schema, viewName, viewsErr, metadataErr,
)
}
return "", fmt.Errorf("view source not found: %s.%s", schema, viewName)
}
+20 -20
View File
@@ -2757,15 +2757,15 @@ func fakeOracleColumnLoader(columns []oracleColumnMeta) oracleColumnMetaLoader {
}
}
func TestGetObjectSourceUsesOriginalViewNameWithDBMSMetadata(t *testing.T) {
func TestGetObjectSourceUsesOriginalViewNameWithAllViews(t *testing.T) {
for _, viewName := range []string{"vEnginWJZ", "V_ENGINE_WJZ"} {
t.Run(viewName, func(t *testing.T) {
ddl := `CREATE OR REPLACE FORCE VIEW "ZTZS_ERP2"."` + viewName + `" AS SELECT source_id FROM "ZTZS_ERP2"."SOURCE_TABLE"`
source := `SELECT source_id FROM "ZTZS_ERP2"."SOURCE_TABLE"`
db, scripted := openOracleViewSourceTestDB(t, []oracleViewSourceQueryStep{
{
queryContains: "DBMS_METADATA.GET_DDL('VIEW'",
args: []driver.Value{viewName, "ZTZS_ERP2"},
rows: [][]driver.Value{{ddl}},
queryContains: "FROM ALL_VIEWS",
args: []driver.Value{"ZTZS_ERP2", viewName},
rows: [][]driver.Value{{source}},
},
})
s := newServer()
@@ -2775,7 +2775,7 @@ func TestGetObjectSourceUsesOriginalViewNameWithDBMSMetadata(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if result["source"] != ddl {
if result["source"] != source {
t.Fatalf("unexpected view source: %#v", result["source"])
}
if scripted.next != len(scripted.steps) {
@@ -2982,19 +2982,19 @@ func TestGetObjectSourcePreservesQuotedSynonymName(t *testing.T) {
}
}
func TestGetObjectSourceFallsBackToAllViewsWithOriginalName(t *testing.T) {
func TestGetObjectSourceFallsBackToDBMSMetadataWithOriginalName(t *testing.T) {
const viewName = "vEnginWJZ"
const source = `SELECT source_id FROM "ZTZS_ERP2"."SOURCE_TABLE"`
const ddl = `CREATE OR REPLACE FORCE VIEW "ZTZS_ERP2"."vEnginWJZ" AS SELECT source_id FROM "ZTZS_ERP2"."SOURCE_TABLE"`
db, scripted := openOracleViewSourceTestDB(t, []oracleViewSourceQueryStep{
{
queryContains: "DBMS_METADATA.GET_DDL('VIEW'",
args: []driver.Value{viewName, "ZTZS_ERP2"},
err: errors.New("ORA-31603: object not found"),
},
{
queryContains: "FROM ALL_VIEWS",
args: []driver.Value{"ZTZS_ERP2", viewName},
rows: [][]driver.Value{{source}},
err: errors.New("ORA-00942: table or view does not exist"),
},
{
queryContains: "DBMS_METADATA.GET_DDL('VIEW'",
args: []driver.Value{viewName, "ZTZS_ERP2"},
rows: [][]driver.Value{{ddl}},
},
})
s := newServer()
@@ -3004,7 +3004,7 @@ func TestGetObjectSourceFallsBackToAllViewsWithOriginalName(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if result["source"] != source {
if result["source"] != ddl {
t.Fatalf("unexpected fallback source: %#v", result["source"])
}
if scripted.next != len(scripted.steps) {
@@ -3014,16 +3014,16 @@ func TestGetObjectSourceFallsBackToAllViewsWithOriginalName(t *testing.T) {
func TestGetObjectSourceRejectsMissingViewSource(t *testing.T) {
db, scripted := openOracleViewSourceTestDB(t, []oracleViewSourceQueryStep{
{
queryContains: "DBMS_METADATA.GET_DDL('VIEW'",
args: []driver.Value{"vEnginWJZ", "ZTZS_ERP2"},
err: errors.New("ORA-31603: object not found"),
},
{
queryContains: "FROM ALL_VIEWS",
args: []driver.Value{"ZTZS_ERP2", "vEnginWJZ"},
rows: nil,
},
{
queryContains: "DBMS_METADATA.GET_DDL('VIEW'",
args: []driver.Value{"vEnginWJZ", "ZTZS_ERP2"},
err: errors.New("ORA-31603: object not found"),
},
})
s := newServer()
s.db = db
@@ -352,7 +352,7 @@ const settingsStore = useSettingsStore();
const savedSqlStore = useSavedSqlStore();
const { toast } = useToast();
const { toast, message: toastMessage, dismissToast } = useToast();
const installedPlugins = ref<InstalledPlugin[]>([]);
const sidebarPluginRegistry = computed(() => createFrontendPluginRegistry(installedPlugins.value, appLocale.value));
@@ -2528,6 +2528,12 @@ function openObjectSourceDialog(initialEditing: boolean, viewPackageBody = false
if (!sourceTarget) return;
const openMode = settingsStore.editorSettings.routineSourceOpenMode;
if (openMode === "query-tab") {
const loadingMessage = t("common.loading");
const loadingToastTimer = window.setTimeout(() => toast(loadingMessage, 30000), 350);
const finishLoadingToast = () => {
window.clearTimeout(loadingToastTimer);
if (toastMessage.value === loadingMessage) dismissToast();
};
void connectionStore
.ensureConnected(connectionId)
.then(async () => {
@@ -2571,7 +2577,8 @@ function openObjectSourceDialog(initialEditing: boolean, viewPackageBody = false
})
.catch((e: any) => {
toast(e?.message || String(e), 5000);
});
})
.finally(finishLoadingToast);
return;
}
void connectionStore