mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-20 00:17:44 +00:00
feat(completion): suggest sequences in OceanBase-Oracle SQL
This commit is contained in:
Vendored
+30
@@ -106,3 +106,33 @@ it("does not convert two failed interpretations into successful completion", asy
|
||||
api.completionAssistantSearch.mockRejectedValue(new Error("Network connection lost"));
|
||||
expect(await createEditor()()).toBeNull();
|
||||
});
|
||||
|
||||
it("suggests sequence pseudo-columns for schema-qualified OceanBase sequences when package probe reports not visible", async () => {
|
||||
api.completionAssistantSearch.mockImplementation(async (request: CompletionAssistantRequest) => {
|
||||
if (request.parent_name) throw new Error("Package is not visible: APP.ORDER_SEQ");
|
||||
return {
|
||||
candidates: [{ name: "ORDER_SEQ", schema: "APP", kind: "sequence" }],
|
||||
incomplete: false,
|
||||
fallback_used: false,
|
||||
};
|
||||
});
|
||||
const provide = createEditor("SELECT APP.ORDER_SEQ.");
|
||||
const result = await provide();
|
||||
expect(result?.options.some((option) => option.label === "NEXTVAL")).toBe(true);
|
||||
expect(result?.options.some((option) => option.label === "CURRVAL")).toBe(true);
|
||||
});
|
||||
|
||||
it("suggests sequence pseudo-columns for unqualified sequence in current schema", async () => {
|
||||
api.completionAssistantSearch.mockImplementation(async (request: CompletionAssistantRequest) => {
|
||||
if (request.parent_name) throw new Error("Package is not visible: CURRENT.ORDER_SEQ");
|
||||
return {
|
||||
candidates: [{ name: "ORDER_SEQ", schema: "CURRENT", kind: "sequence" }],
|
||||
incomplete: false,
|
||||
fallback_used: false,
|
||||
};
|
||||
});
|
||||
const provide = createEditor("SELECT ORDER_SEQ.");
|
||||
const result = await provide();
|
||||
expect(result?.options.some((option) => option.label === "NEXTVAL")).toBe(true);
|
||||
expect(result?.options.some((option) => option.label === "CURRVAL")).toBe(true);
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
getSqlCompletionContext,
|
||||
getSqlCompletionResultValidFor,
|
||||
isSqlLikeCompletionStatement,
|
||||
normalizeIdentifierPart,
|
||||
prepareSqlCompletionReplacement,
|
||||
recordCompletionSelection,
|
||||
shouldAutoOpenSqlCompletion,
|
||||
@@ -1420,11 +1421,28 @@ export function useQueryEditorCompletion(options: QueryEditorCompletionOptions)
|
||||
const list = (schema: string | undefined, parentName?: string, globalSearch = false) =>
|
||||
connectionStore.listCompletionObjects(props.connectionId!, scope.database, completionContext.prefix, MAX_COMPLETION_TABLES, schema, parentName, globalSearch, scope.schema, objectKinds, !!completionContext.prefixQuoted);
|
||||
if (parts.length === 0) return list(scope.schema, undefined, true);
|
||||
if (parts.length === 2) return list(parts[0], parts[1]);
|
||||
if (parts.length === 2) {
|
||||
let packageMembers: SqlCompletionObject[] = [];
|
||||
try {
|
||||
packageMembers = await list(parts[0], parts[1]);
|
||||
} catch (error) {
|
||||
if (/Package is not visible:/i.test(String(error)) && objectKinds.includes("sequence")) {
|
||||
const schemaObjects = await list(parts[0]);
|
||||
return schemaObjects.filter((obj) => obj.type === "sequence");
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (packageMembers.length > 0) return packageMembers;
|
||||
if (objectKinds.includes("sequence")) {
|
||||
const schemaObjects = await list(parts[0]);
|
||||
return schemaObjects.filter((obj) => obj.type === "sequence");
|
||||
}
|
||||
return [];
|
||||
}
|
||||
if (parts.length > 2) return [];
|
||||
// One qualifier can name a schema or a package in the current schema.
|
||||
const groups = await Promise.allSettled([list(parts[0]), list(scope.schema, parts[0])]);
|
||||
if (groups[0].status === "rejected" && groups[1].status === "rejected") throw groups[0].reason;
|
||||
const groups = await Promise.allSettled([list(parts[0]), list(scope.schema, parts[0]), ...(objectKinds.includes("sequence") && scope.schema && normalizeIdentifierPart(scope.schema) !== normalizeIdentifierPart(parts[0]) ? [list(scope.schema)] : [])]);
|
||||
if (groups.every((g) => g.status === "rejected")) throw groups[0].status === "rejected" ? groups[0].reason : undefined;
|
||||
let objects: SqlCompletionObject[] = [];
|
||||
for (const group of groups) {
|
||||
if (group.status === "fulfilled") objects = mergeCompletionObjects(objects, group.value);
|
||||
|
||||
@@ -675,6 +675,163 @@ describe("PostgreSQL sequence literal completion", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests OceanBase-Oracle sequences in SQL expressions and select lists", () => {
|
||||
const sql = "SELECT ord";
|
||||
const unqualifiedItems = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
currentSchema: "APP",
|
||||
});
|
||||
|
||||
expect(unqualifiedItems).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "ORDER_SEQ",
|
||||
type: "variable",
|
||||
detail: "sequence in APP",
|
||||
apply: "ORDER_SEQ",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
const qualifiedItems = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(qualifiedItems).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "ORDER_SEQ",
|
||||
type: "variable",
|
||||
detail: "sequence in APP",
|
||||
apply: "APP.ORDER_SEQ",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests OceanBase-Oracle sequences under schema qualifier", () => {
|
||||
const sql = "SELECT app.ord";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "ORDER_SEQ",
|
||||
type: "variable",
|
||||
apply: "ORDER_SEQ",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests NEXTVAL and CURRVAL pseudo-columns for OceanBase-Oracle sequences", () => {
|
||||
const sql = "SELECT ORDER_SEQ.";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "NEXTVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
label: "CURRVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests NEXTVAL and CURRVAL pseudo-columns for schema-qualified OceanBase-Oracle sequences", () => {
|
||||
const sql = "SELECT APP.ORDER_SEQ.";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "NEXTVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
label: "CURRVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("respects keyword case for OceanBase-Oracle sequence pseudo-columns", () => {
|
||||
const sql = "SELECT ORDER_SEQ.n";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
keywordCase: "lower",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "nextval",
|
||||
apply: "nextval",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests OceanBase-Oracle sequence pseudo-columns in INSERT VALUES clause", () => {
|
||||
const sql = "INSERT INTO orders (id, name) VALUES (ORDER_SEQ.";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [{ name: "orders", schema: "APP" }],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map([["APP.orders", [{ name: "id" }, { name: "name" }]]]),
|
||||
databaseType: "oceanbase-oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "NEXTVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["SELECT 'order_", "postgres"],
|
||||
["SELECT nextval('order_", "mysql"],
|
||||
|
||||
@@ -4837,11 +4837,11 @@ function buildObjectItems(context: SqlCompletionContext, objects: SqlCompletionO
|
||||
})
|
||||
.map((object) => {
|
||||
const qualifiedByContext = objectIsQualifiedByContext(object, context, databaseType, currentSchema);
|
||||
const objectInCurrentSchema = !!currentSchema && !!object.schema && (databaseType === "oceanbase-oracle" ? object.schema === currentSchema : normalizeIdentifierPart(object.schema) === normalizeIdentifierPart(currentSchema));
|
||||
const objectInCurrentSchema = !!currentSchema && !!object.schema && normalizeIdentifierPart(object.schema) === normalizeIdentifierPart(currentSchema);
|
||||
const suppliedApplyName = object.applyName ? quoteCompletionRoutineName(object.applyName, dialect) : undefined;
|
||||
const oceanBaseApplyName = databaseType === "oceanbase-oracle" ? [...(object.schema && !objectInCurrentSchema ? [object.schema] : []), ...(object.parentName ? [object.parentName] : []), object.name].map((part) => quoteCompletionRoutineIdentifier(part, dialect)).join(".") : undefined;
|
||||
const applyName =
|
||||
qualifiedByContext || (context.qualifier && (databaseType === "oceanbase-oracle" ? object.schema === oceanBaseRoutineQualifierParts(context)[0] : object.schema?.toLowerCase() === context.qualifier.toLowerCase()))
|
||||
qualifiedByContext || (context.qualifier && (databaseType === "oceanbase-oracle" ? normalizeIdentifierPart(object.schema ?? "") === normalizeIdentifierPart(oceanBaseRoutineQualifierParts(context)[0] ?? "") : object.schema?.toLowerCase() === context.qualifier.toLowerCase()))
|
||||
? quoteCompletionRoutineIdentifier(object.name, dialect)
|
||||
: (oceanBaseApplyName ?? suppliedApplyName ?? (object.schema && !objectInCurrentSchema ? `${quoteCompletionRoutineIdentifier(object.schema, dialect)}.${quoteCompletionRoutineIdentifier(object.name, dialect)}` : quoteCompletionRoutineIdentifier(object.name, dialect)));
|
||||
const locationDetail = object.type === "trigger" && object.parentName ? `trigger on ${object.parentName}` : object.parentName ? `${object.type} in ${object.parentName}` : object.schema ? `${object.type} in ${object.schema}` : object.type;
|
||||
@@ -5006,7 +5006,7 @@ function objectMatchesCompletionContext(object: SqlCompletionObject, context: Sq
|
||||
const prefixMatches = context.prefixQuoted ? object.name.startsWith(context.prefix) : matchesPrefix(object.name, context.prefix);
|
||||
if (!context.qualifier) return prefixMatches;
|
||||
const parts = oceanBaseRoutineQualifierParts(context);
|
||||
return prefixMatches && (object.parentName ? objectIsQualifiedByContext(object, context, databaseType, currentSchema) : parts.length === 1 && object.schema === parts[0]);
|
||||
return prefixMatches && (object.parentName ? objectIsQualifiedByContext(object, context, databaseType, currentSchema) : parts.length === 1 && normalizeIdentifierPart(object.schema ?? "") === normalizeIdentifierPart(parts[0] ?? ""));
|
||||
}
|
||||
if (object.type === "sequence") {
|
||||
if (context.qualifier) {
|
||||
@@ -5942,7 +5942,7 @@ function normalizeTableName(name: string): string {
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
function normalizeIdentifierPart(name: string): string {
|
||||
export function normalizeIdentifierPart(name: string): string {
|
||||
return name.replace(/^["`[]|["`\]]$/g, "").toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
@@ -1893,9 +1893,9 @@ describe("connectionStore completion assistant", () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
["empty", vi.fn().mockResolvedValue({ candidates: [], incomplete: false, fallback_used: false })],
|
||||
["permission error", vi.fn().mockRejectedValue(new Error("permission denied for sequence"))],
|
||||
])("returns an empty sequence fallback for %s metadata", async (_caseName, completionAssistantSearch) => {
|
||||
["empty", vi.fn().mockResolvedValue({ candidates: [], incomplete: false, fallback_used: false }), false],
|
||||
["permission error", vi.fn().mockRejectedValue(new Error("permission denied for sequence")), true],
|
||||
])("returns an empty sequence fallback for %s metadata", async (_caseName, completionAssistantSearch, expectMetadataCall) => {
|
||||
const listCompletionObjects = vi.fn().mockResolvedValue([{ name: "not_a_sequence", object_type: "FUNCTION" }]);
|
||||
|
||||
vi.doMock("@/lib/backend/tauriRuntime", () => ({ isTauriRuntime: () => false }));
|
||||
@@ -1903,6 +1903,7 @@ describe("connectionStore completion assistant", () => {
|
||||
checkConnectionHealth: vi.fn().mockResolvedValue(undefined),
|
||||
completionAssistantSearch,
|
||||
listCompletionObjects,
|
||||
listSchemas: vi.fn().mockResolvedValue(["public"]),
|
||||
}));
|
||||
|
||||
const { useConnectionStore } = await import("@/stores/connectionStore");
|
||||
@@ -1911,7 +1912,11 @@ describe("connectionStore completion assistant", () => {
|
||||
store.connectedIds.add("pg-1");
|
||||
|
||||
await expect(store.listCompletionObjects("pg-1", "app", "missing", 20, undefined, undefined, false, undefined, ["sequence"])).resolves.toEqual([]);
|
||||
expect(listCompletionObjects).not.toHaveBeenCalled();
|
||||
// The sequence-only error fallback loads schema-level objects (filtered to
|
||||
// sequences), so the metadata call goes through on permission errors; the
|
||||
// empty-metadata case returns [] without touching the metadata API.
|
||||
if (expectMetadataCall) expect(listCompletionObjects).toHaveBeenCalled();
|
||||
else expect(listCompletionObjects).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("searches the server-reported SQL Server default schema without treating the username as a schema", async () => {
|
||||
|
||||
@@ -9256,6 +9256,15 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
return deduped;
|
||||
}
|
||||
|
||||
function normalizeCompletionIdentifier(name?: string | null): string {
|
||||
if (!name) return "";
|
||||
const trimmed = name.trim();
|
||||
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("`") && trimmed.endsWith("`")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
|
||||
return trimmed.slice(1, -1);
|
||||
}
|
||||
return trimmed.toLowerCase();
|
||||
}
|
||||
|
||||
async function listCompletionObjects(
|
||||
connectionId: string,
|
||||
database: string,
|
||||
@@ -9302,7 +9311,8 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
if (databaseType === "oceanbase-oracle" && parentName) throw error;
|
||||
if (databaseType === "oceanbase-oracle" && !/does not support filtered routine completion|unknown method|method not found|not supported/i.test(String(error))) throw error;
|
||||
if (objectKinds.length === 1 && objectKinds[0] === "sequence") {
|
||||
loadedObjects = [];
|
||||
const objects = isSchemaAwareDatabase(connectionId) ? await listSchemaAwareCompletionObjects(connectionId, database, schema) : await api.listCompletionObjects(connectionId, database, connectionDatabaseMetadataSchema(getConfig(connectionId), database, schema));
|
||||
loadedObjects = dedupeCompletionObjects(objects.map(toSqlCompletionObject).filter((object): object is SqlCompletionObject => object?.type === "sequence"));
|
||||
} else {
|
||||
const objects = isSchemaAwareDatabase(connectionId) ? await listSchemaAwareCompletionObjects(connectionId, database, schema) : await api.listCompletionObjects(connectionId, database, connectionDatabaseMetadataSchema(getConfig(connectionId), database, schema));
|
||||
loadedObjects = dedupeCompletionObjects(objects.map(toSqlCompletionObject).filter((object): object is SqlCompletionObject => object != null));
|
||||
@@ -9328,8 +9338,8 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
if (!objectKinds.includes("sequence")) return false;
|
||||
} else if (object.type !== "procedure" && object.type !== "function") return false;
|
||||
else if (!objectKinds.includes("routine") && !objectKinds.includes(object.type)) return false;
|
||||
if (schema && !globalSearch && object.schema !== schema) return false;
|
||||
if (parentName && object.parentName !== parentName) return false;
|
||||
if (schema && !globalSearch && (!object.schema || normalizeCompletionIdentifier(object.schema) !== normalizeCompletionIdentifier(schema))) return false;
|
||||
if (parentName && (!object.parentName || normalizeCompletionIdentifier(object.parentName) !== normalizeCompletionIdentifier(parentName))) return false;
|
||||
if (caseSensitive) return object.name.includes(filter.trim());
|
||||
}
|
||||
return !normalizedFilter || fuzzyCompletionObjectMatch(object, normalizedFilter);
|
||||
|
||||
@@ -7659,22 +7659,17 @@ fn filter_completion_objects(objects: Vec<db::ObjectInfo>) -> Vec<db::ObjectInfo
|
||||
.into_iter()
|
||||
.filter(|object| {
|
||||
let object_type = object.object_type.to_ascii_uppercase();
|
||||
object_type.contains("PROCEDURE") || object_type.contains("FUNCTION") || object_type.contains("TRIGGER")
|
||||
object_type.contains("PROCEDURE")
|
||||
|| object_type.contains("FUNCTION")
|
||||
|| object_type.contains("TRIGGER")
|
||||
|| object_type.contains("PACKAGE")
|
||||
|| object_type.contains("SEQUENCE")
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn filter_completion_objects_with_packages(objects: Vec<db::ObjectInfo>) -> Vec<db::ObjectInfo> {
|
||||
objects
|
||||
.into_iter()
|
||||
.filter(|object| {
|
||||
let object_type = object.object_type.to_ascii_uppercase();
|
||||
object_type.contains("PROCEDURE")
|
||||
|| object_type.contains("FUNCTION")
|
||||
|| object_type.contains("TRIGGER")
|
||||
|| object_type == "PACKAGE"
|
||||
})
|
||||
.collect()
|
||||
filter_completion_objects(objects)
|
||||
}
|
||||
|
||||
fn is_agent_postgres_metadata_fallback_config(config: &ConnectionConfig) -> bool {
|
||||
|
||||
@@ -102,8 +102,11 @@ fn list_objects_sql(schema: &str) -> String {
|
||||
FROM ALL_PROCEDURES \
|
||||
WHERE OWNER = {s} AND OBJECT_TYPE IN ('PROCEDURE', 'FUNCTION') AND PROCEDURE_NAME IS NULL \
|
||||
UNION ALL \
|
||||
SELECT SEQUENCE_NAME AS OBJECT_NAME, 'SEQUENCE' AS OBJECT_TYPE, SEQUENCE_OWNER AS OBJECT_SCHEMA, 4 AS SORT_ORDER \
|
||||
FROM ALL_SEQUENCES WHERE SEQUENCE_OWNER = {s} \
|
||||
UNION ALL \
|
||||
SELECT OBJECT_NAME, CASE OBJECT_TYPE WHEN 'PACKAGE BODY' THEN 'PACKAGE_BODY' ELSE OBJECT_TYPE END AS OBJECT_TYPE, \
|
||||
OWNER AS OBJECT_SCHEMA, CASE WHEN OBJECT_TYPE = 'PACKAGE' THEN 4 ELSE 5 END AS SORT_ORDER \
|
||||
OWNER AS OBJECT_SCHEMA, CASE WHEN OBJECT_TYPE = 'PACKAGE' THEN 5 ELSE 6 END AS SORT_ORDER \
|
||||
FROM ALL_OBJECTS \
|
||||
WHERE OWNER = {s} AND OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY') \
|
||||
ORDER BY SORT_ORDER, OBJECT_NAME",
|
||||
@@ -349,6 +352,8 @@ mod tests {
|
||||
assert!(sql.contains("ALL_PROCEDURES"));
|
||||
assert!(sql.contains("'PROCEDURE'"));
|
||||
assert!(sql.contains("'FUNCTION'"));
|
||||
assert!(sql.contains("ALL_SEQUENCES"));
|
||||
assert!(sql.contains("'SEQUENCE'"));
|
||||
assert!(sql.contains("ALL_OBJECTS"));
|
||||
assert!(sql.contains("'PACKAGE'"));
|
||||
assert!(sql.contains("'PACKAGE BODY'"));
|
||||
|
||||
@@ -159,6 +159,9 @@ metadata_queries:
|
||||
list_triggers:
|
||||
sql: "SELECT TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT FROM ALL_TRIGGERS WHERE OWNER = '{schema}' AND TABLE_NAME = '{table}'"
|
||||
performance_profile: "MEDIUM"
|
||||
list_sequences:
|
||||
sql: "SELECT SEQUENCE_NAME FROM ALL_SEQUENCES WHERE SEQUENCE_OWNER = '{schema}'"
|
||||
performance_profile: "LIGHT"
|
||||
dependencies:
|
||||
sql: "SELECT a.TABLE_NAME, c_pk.TABLE_NAME AS R_TABLE_NAME FROM ALL_CONS_COLUMNS a JOIN ALL_CONSTRAINTS c ON a.CONSTRAINT_NAME = c.CONSTRAINT_NAME JOIN ALL_CONSTRAINTS c_pk ON c.R_CONSTRAINT_NAME = c_pk.CONSTRAINT_NAME WHERE c.CONSTRAINT_TYPE = 'R' AND a.OWNER = '{schema}'"
|
||||
depth_support: 2
|
||||
|
||||
Reference in New Issue
Block a user