fix(query): use execution database for result metadata
This commit is contained in:
1 parent
abac9a7596
commit
d221e0dee7
2 files changed
+112
-16
No files matched your search
@@ -123,6 +123,95 @@ describe("queryStore hidden primary key editing", () => {
|
|||||||
expect(tab.queryEditabilityReason).toBeUndefined();
|
expect(tab.queryEditabilityReason).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("loads metadata from the connection default database when the query tab database is empty", async () => {
|
||||||
|
const { useQueryStore } = await import("@/stores/queryStore");
|
||||||
|
const store = useQueryStore();
|
||||||
|
const tabId = store.createTab("mysql-1", "", "Query");
|
||||||
|
|
||||||
|
await store.executeTabSql(tabId, "SELECT name FROM users");
|
||||||
|
|
||||||
|
expect(getColumns).toHaveBeenCalledWith("mysql-1", "app", "app", "users", undefined);
|
||||||
|
expect(executeMulti).toHaveBeenCalledWith("mysql-1", "", "SELECT name, `id` AS `__DBX_PK_0` FROM users", undefined, expect.any(String), expect.objectContaining({ timeoutSecs: 30 }));
|
||||||
|
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||||
|
await vi.waitFor(() => expect(tab.querySourceColumns).toEqual(["name", "id"]));
|
||||||
|
expect(tab.tableMeta?.database).toBe("app");
|
||||||
|
expect(tab.queryEditabilityReason).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses the connection default database for SQL library tabs without a saved database", async () => {
|
||||||
|
const { useQueryStore } = await import("@/stores/queryStore");
|
||||||
|
const store = useQueryStore();
|
||||||
|
const tabId = store.openSavedSql({
|
||||||
|
id: "saved-1",
|
||||||
|
connectionId: "mysql-1",
|
||||||
|
name: "users.sql",
|
||||||
|
database: "",
|
||||||
|
sql: "SELECT name FROM users",
|
||||||
|
createdAt: "2026-07-21T00:00:00.000Z",
|
||||||
|
updatedAt: "2026-07-21T00:00:00.000Z",
|
||||||
|
});
|
||||||
|
|
||||||
|
await store.executeTabSql(tabId, "SELECT name FROM users");
|
||||||
|
|
||||||
|
expect(getColumns).toHaveBeenCalledWith("mysql-1", "app", "app", "users", undefined);
|
||||||
|
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||||
|
await vi.waitFor(() => expect(tab.querySourceColumns).toEqual(["name", "id"]));
|
||||||
|
expect(tab.queryEditabilityReason).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("preserves JDBC catalog metadata lookup when the tab uses the connection default database", async () => {
|
||||||
|
getConnectionConfig.mockReturnValue({ id: "jdbc-1", name: "JDBC MySQL", db_type: "jdbc", connection_string: "jdbc:mysql://localhost:3306/app", database: "app", query_timeout_secs: 30 });
|
||||||
|
const { useQueryStore } = await import("@/stores/queryStore");
|
||||||
|
const store = useQueryStore();
|
||||||
|
const tabId = store.createTab("jdbc-1", "", "Query");
|
||||||
|
|
||||||
|
await store.executeTabSql(tabId, "SELECT name FROM users");
|
||||||
|
|
||||||
|
expect(getColumns).toHaveBeenCalledWith("jdbc-1", "app", "", "users", undefined);
|
||||||
|
expect(executeMulti).toHaveBeenCalledWith("jdbc-1", "", "SELECT name, `id` AS `__DBX_PK_0` FROM users", undefined, expect.any(String), expect.objectContaining({ timeoutSecs: 30 }));
|
||||||
|
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||||
|
await vi.waitFor(() => expect(tab.querySourceColumns).toEqual(["name", "id"]));
|
||||||
|
expect(tab.queryEditabilityReason).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps an explicitly selected database instead of falling back to the connection default", async () => {
|
||||||
|
const { useQueryStore } = await import("@/stores/queryStore");
|
||||||
|
const store = useQueryStore();
|
||||||
|
const tabId = store.createTab("mysql-1", "analytics", "Query");
|
||||||
|
|
||||||
|
await store.executeTabSql(tabId, "SELECT name FROM users");
|
||||||
|
|
||||||
|
expect(getColumns).toHaveBeenCalledWith("mysql-1", "analytics", "analytics", "users", undefined);
|
||||||
|
expect(executeMulti).toHaveBeenCalledWith("mysql-1", "analytics", "SELECT name, `id` AS `__DBX_PK_0` FROM users", undefined, expect.any(String), expect.objectContaining({ timeoutSecs: 30 }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("loads metadata from a MySQL cross-database qualified source", async () => {
|
||||||
|
analyzeEditableQueryEditability.mockImplementation(async (sql: string) => {
|
||||||
|
const hidden = sql.includes("__DBX_PK_0");
|
||||||
|
return {
|
||||||
|
editable: true,
|
||||||
|
analysis: {
|
||||||
|
schema: "reporting",
|
||||||
|
tableName: "users",
|
||||||
|
selectStar: false,
|
||||||
|
columns: [{ sourceName: "name", resultName: "name", expression: "name" }, ...(hidden ? [{ sourceName: "id", resultName: "__DBX_PK_0", expression: "`id`" }] : [])],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const { useQueryStore } = await import("@/stores/queryStore");
|
||||||
|
const store = useQueryStore();
|
||||||
|
const tabId = store.createTab("mysql-1", "app", "Query");
|
||||||
|
|
||||||
|
await store.executeTabSql(tabId, "SELECT name FROM reporting.users");
|
||||||
|
|
||||||
|
expect(getColumns).toHaveBeenCalledWith("mysql-1", "app", "reporting", "users", undefined);
|
||||||
|
expect(executeMulti).toHaveBeenCalledWith("mysql-1", "app", "SELECT name, `id` AS `__DBX_PK_0` FROM reporting.users", undefined, expect.any(String), expect.objectContaining({ timeoutSecs: 30 }));
|
||||||
|
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||||
|
await vi.waitFor(() => expect(tab.querySourceColumns).toEqual(["name", "id"]));
|
||||||
|
expect(tab.tableMeta?.database).toBe("app");
|
||||||
|
expect(tab.tableMeta?.schema).toBe("reporting");
|
||||||
|
});
|
||||||
|
|
||||||
it("uses a hidden Oracle ROWID to keep keyless base-table query results editable", async () => {
|
it("uses a hidden Oracle ROWID to keep keyless base-table query results editable", async () => {
|
||||||
getConnectionConfig.mockReturnValue({ id: "oracle-1", name: "Oracle", db_type: "oracle", database: "ORCL", query_timeout_secs: 30 });
|
getConnectionConfig.mockReturnValue({ id: "oracle-1", name: "Oracle", db_type: "oracle", database: "ORCL", query_timeout_secs: 30 });
|
||||||
getColumns.mockResolvedValue([
|
getColumns.mockResolvedValue([
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import { dataTabExecutionDatabase } from "@/lib/table/dataTabExecutionDatabase";
|
|||||||
import { tableOpenPageLimit } from "@/lib/table/tableOpenPageLimit";
|
import { tableOpenPageLimit } from "@/lib/table/tableOpenPageLimit";
|
||||||
import { loadTableMetadata } from "@/lib/metadata/tableMetadataCache";
|
import { loadTableMetadata } from "@/lib/metadata/tableMetadataCache";
|
||||||
import { buildTableSelectSql, quoteTableDataIdentifier } from "@/lib/table/tableSelectSql";
|
import { buildTableSelectSql, quoteTableDataIdentifier } from "@/lib/table/tableSelectSql";
|
||||||
import { connectionQueryExecutionSchema, effectiveDatabaseTypeForConnection, metadataSchemaForConnection } from "@/lib/database/jdbcDialect";
|
import { connectionQueryExecutionSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, metadataSchemaForConnection } from "@/lib/database/jdbcDialect";
|
||||||
import { frontendQueryTimeoutSecsForSql, queryTimeoutSecsForConnection } from "@/lib/sql/queryTimeout";
|
import { frontendQueryTimeoutSecsForSql, queryTimeoutSecsForConnection } from "@/lib/sql/queryTimeout";
|
||||||
import { queryResultNameFromPreamble, queryResultSourceLabel } from "@/lib/sql/queryResultSource";
|
import { queryResultNameFromPreamble, queryResultSourceLabel } from "@/lib/sql/queryResultSource";
|
||||||
import { sortDataGridRowIndexes, type DataGridSortDirection } from "@/lib/dataGrid/dataGridSort";
|
import { sortDataGridRowIndexes, type DataGridSortDirection } from "@/lib/dataGrid/dataGridSort";
|
||||||
@@ -2390,7 +2390,11 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
tab.tableMeta = patch.tableMeta;
|
tab.tableMeta = patch.tableMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadEditableQuerySource(tab: QueryTab, analysis: EditableQueryInfo, source: EditableQuerySource, conn: ConnectionConfig | undefined, dbType: string, traceId?: string, elapsed?: () => string): Promise<LoadedEditableSource> {
|
async function loadEditableQuerySource(tab: QueryTab, analysis: EditableQueryInfo, source: EditableQuerySource, conn: ConnectionConfig | undefined, dbType: string, executionDatabase: string, traceId?: string, elapsed?: () => string): Promise<LoadedEditableSource> {
|
||||||
|
// Metadata must resolve in the same namespace as the query execution. An
|
||||||
|
// empty query-tab database still executes in the connection's default DB,
|
||||||
|
// while database-tree dialects may override it with a qualified source.
|
||||||
|
const metadataDatabase = (connectionUsesDatabaseObjectTreeMode(conn) ? source.schema : undefined) || executionDatabase || conn?.database || tab.database;
|
||||||
let schema = source.schema || tab.schema;
|
let schema = source.schema || tab.schema;
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
if (dbType === "postgres" || dbType === "kwdb") schema = "public";
|
if (dbType === "postgres" || dbType === "kwdb") schema = "public";
|
||||||
@@ -2399,7 +2403,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
// Oracle-family connection databases are service names, not schemas. When
|
// Oracle-family connection databases are service names, not schemas. When
|
||||||
// the query does not qualify a schema, let the driver resolve the current
|
// the query does not qualify a schema, let the driver resolve the current
|
||||||
// login user's schema instead of looking up metadata under the service name.
|
// login user's schema instead of looking up metadata under the service name.
|
||||||
const resolvedSchema = ORACLE_LIKE_METADATA_TYPES.has(dbType) && !schema ? "" : metadataSchemaForConnection(conn, tab.database, schema || undefined);
|
const resolvedSchema = ORACLE_LIKE_METADATA_TYPES.has(dbType) && !schema ? "" : metadataSchemaForConnection(conn, metadataDatabase, schema || undefined);
|
||||||
const metadataSchema = normalizeOracleLikeMetadataIdentifier(dbType, resolvedSchema || undefined, source.schema ? source.schemaQuoted : false) || "";
|
const metadataSchema = normalizeOracleLikeMetadataIdentifier(dbType, resolvedSchema || undefined, source.schema ? source.schemaQuoted : false) || "";
|
||||||
const metadataTableName = normalizeOracleLikeMetadataIdentifier(dbType, source.tableName, source.tableNameQuoted)!;
|
const metadataTableName = normalizeOracleLikeMetadataIdentifier(dbType, source.tableName, source.tableNameQuoted)!;
|
||||||
const metadataCatalog = normalizeOracleLikeMetadataIdentifier(dbType, source.catalog, source.catalogQuoted);
|
const metadataCatalog = normalizeOracleLikeMetadataIdentifier(dbType, source.catalog, source.catalogQuoted);
|
||||||
@@ -2419,7 +2423,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
});
|
});
|
||||||
const loadedMetadata = await loadTableMetadata({
|
const loadedMetadata = await loadTableMetadata({
|
||||||
connectionId: tab.connectionId,
|
connectionId: tab.connectionId,
|
||||||
database: tab.database,
|
database: metadataDatabase,
|
||||||
schema: metadataSchema,
|
schema: metadataSchema,
|
||||||
tableName: metadataTableName,
|
tableName: metadataTableName,
|
||||||
tableType: knownTableType,
|
tableType: knownTableType,
|
||||||
@@ -2443,6 +2447,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
analysis: normalizeOracleLikeQueryAnalysis(dbType, cloneAnalysisForSource(analysis, metadataSource), metadataSchema || undefined, metadataTableName),
|
analysis: normalizeOracleLikeQueryAnalysis(dbType, cloneAnalysisForSource(analysis, metadataSource), metadataSchema || undefined, metadataTableName),
|
||||||
tableMeta: {
|
tableMeta: {
|
||||||
catalog: metadataCatalog,
|
catalog: metadataCatalog,
|
||||||
|
database: metadataDatabase,
|
||||||
schema: metadataSchema || undefined,
|
schema: metadataSchema || undefined,
|
||||||
tableName: metadataTableName,
|
tableName: metadataTableName,
|
||||||
tableType: loadedMetadata.metadata.tableType,
|
tableType: loadedMetadata.metadata.tableType,
|
||||||
@@ -2461,14 +2466,14 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
async function oracleRowIdIsSafeForQuery(tab: QueryTab, loaded: LoadedEditableSource): Promise<boolean> {
|
async function oracleRowIdIsSafeForQuery(tab: QueryTab, loaded: LoadedEditableSource): Promise<boolean> {
|
||||||
const knownType = loaded.tableMeta.tableType?.trim().toUpperCase();
|
const knownType = loaded.tableMeta.tableType?.trim().toUpperCase();
|
||||||
if (knownType) return knownType === "TABLE";
|
if (knownType) return knownType === "TABLE";
|
||||||
const objects = await api.listObjects(tab.connectionId!, tab.database, loaded.tableMeta.schema ?? "", ["TABLE", "VIEW", "MATERIALIZED_VIEW"], loaded.tableMeta.tableName, 20, 0, loaded.tableMeta.catalog);
|
const objects = await api.listObjects(tab.connectionId!, loaded.tableMeta.database ?? tab.database, loaded.tableMeta.schema ?? "", ["TABLE", "VIEW", "MATERIALIZED_VIEW"], loaded.tableMeta.tableName, 20, 0, loaded.tableMeta.catalog);
|
||||||
const matching = objects.find((object) => object.name.toLowerCase() === loaded.tableMeta.tableName.toLowerCase());
|
const matching = objects.find((object) => object.name.toLowerCase() === loaded.tableMeta.tableName.toLowerCase());
|
||||||
return matching?.object_type.trim().toUpperCase() === "TABLE";
|
return matching?.object_type.trim().toUpperCase() === "TABLE";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function prepareEditableQueryExecution(tab: QueryTab, sql: string, conn: ConnectionConfig | undefined, databaseType: DatabaseType | undefined, traceId: string, elapsed: () => string): Promise<EditableQueryExecutionPreparation> {
|
async function prepareEditableQueryExecution(tab: QueryTab, sql: string, conn: ConnectionConfig | undefined, databaseType: DatabaseType | undefined, executionDatabase: string, traceId: string, elapsed: () => string): Promise<EditableQueryExecutionPreparation> {
|
||||||
const unchanged = { sql, metadataSql: sql, hiddenPrimaryKeys: [] };
|
const unchanged = { sql, metadataSql: sql, hiddenPrimaryKeys: [] };
|
||||||
if (!databaseType || !HIDDEN_QUERY_KEY_DATABASE_TYPES.has(databaseType) || !tab.connectionId || !tab.database) return unchanged;
|
if (!databaseType || !HIDDEN_QUERY_KEY_DATABASE_TYPES.has(databaseType) || !tab.connectionId) return unchanged;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const editability = analyzeEditableQueryEditability(sql);
|
const editability = analyzeEditableQueryEditability(sql);
|
||||||
@@ -2477,7 +2482,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
const sources = editableQuerySources(analysis);
|
const sources = editableQuerySources(analysis);
|
||||||
if (sources.length !== 1 || analysis.distinct) return unchanged;
|
if (sources.length !== 1 || analysis.distinct) return unchanged;
|
||||||
|
|
||||||
const loaded = await loadEditableQuerySource(tab, analysis, sources[0]!, conn, databaseType, traceId, elapsed);
|
const loaded = await loadEditableQuerySource(tab, analysis, sources[0]!, conn, databaseType, executionDatabase, traceId, elapsed);
|
||||||
if (loaded.tableMeta.columns.length === 0) return unchanged;
|
if (loaded.tableMeta.columns.length === 0) return unchanged;
|
||||||
if (loaded.tableMeta.tableType?.toUpperCase().includes("VIEW")) return unchanged;
|
if (loaded.tableMeta.tableType?.toUpperCase().includes("VIEW")) return unchanged;
|
||||||
const metadataAnalysis = expandStarProjectionColumnsForSource(bindColumnsForSource(databaseType, loaded.analysis, loaded.source, loaded.tableMeta.columns), loaded.source, loaded.tableMeta.columns);
|
const metadataAnalysis = expandStarProjectionColumnsForSource(bindColumnsForSource(databaseType, loaded.analysis, loaded.source, loaded.tableMeta.columns), loaded.source, loaded.tableMeta.columns);
|
||||||
@@ -2517,7 +2522,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildQueryMetadataPatch(tab: QueryTab, sql: string, traceId?: string, elapsed?: () => string, hiddenPrimaryKeys: HiddenPrimaryKeyProjection[] = []): Promise<QueryMetadataPatch | undefined> {
|
async function buildQueryMetadataPatch(tab: QueryTab, sql: string, executionDatabase: string, traceId?: string, elapsed?: () => string, hiddenPrimaryKeys: HiddenPrimaryKeyProjection[] = []): Promise<QueryMetadataPatch | undefined> {
|
||||||
if (tab.mode !== "query") return;
|
if (tab.mode !== "query") return;
|
||||||
if (!tab.result || !tab.result.columns.length) {
|
if (!tab.result || !tab.result.columns.length) {
|
||||||
return {
|
return {
|
||||||
@@ -2546,7 +2551,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
}
|
}
|
||||||
const analysis = editability.analysis;
|
const analysis = editability.analysis;
|
||||||
|
|
||||||
if (!tab.connectionId || !tab.database) {
|
if (!tab.connectionId) {
|
||||||
return {
|
return {
|
||||||
queryAnalysis: undefined,
|
queryAnalysis: undefined,
|
||||||
querySourceColumns: undefined,
|
querySourceColumns: undefined,
|
||||||
@@ -2562,7 +2567,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
const loadedSources: LoadedEditableSource[] = [];
|
const loadedSources: LoadedEditableSource[] = [];
|
||||||
try {
|
try {
|
||||||
for (const source of sources) {
|
for (const source of sources) {
|
||||||
loadedSources.push(await loadEditableQuerySource(tab, analysis, source, conn, dbType, traceId, elapsed));
|
loadedSources.push(await loadEditableQuerySource(tab, analysis, source, conn, dbType, executionDatabase, traceId, elapsed));
|
||||||
}
|
}
|
||||||
|
|
||||||
const allSourceColumns = loadedSources.map((source) => ({ source: source.source, columns: source.tableMeta.columns }));
|
const allSourceColumns = loadedSources.map((source) => ({ source: source.source, columns: source.tableMeta.columns }));
|
||||||
@@ -2675,12 +2680,12 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function analyzeQueryMetadataInBackground(tabId: string, sql: string, result: QueryResult, traceId: string, elapsed: () => string, hiddenPrimaryKeys: HiddenPrimaryKeyProjection[] = []) {
|
function analyzeQueryMetadataInBackground(tabId: string, sql: string, result: QueryResult, executionDatabase: string, traceId: string, elapsed: () => string, hiddenPrimaryKeys: HiddenPrimaryKeyProjection[] = []) {
|
||||||
void (async () => {
|
void (async () => {
|
||||||
const tab = tabs.value.find((t) => t.id === tabId);
|
const tab = tabs.value.find((t) => t.id === tabId);
|
||||||
if (!tab || tab.result !== result) return;
|
if (!tab || tab.result !== result) return;
|
||||||
queryExecutionLog("info", "metadata:start", { traceId, elapsed: elapsed() });
|
queryExecutionLog("info", "metadata:start", { traceId, elapsed: elapsed() });
|
||||||
const patch = await buildQueryMetadataPatch(tab, sql, traceId, elapsed, hiddenPrimaryKeys);
|
const patch = await buildQueryMetadataPatch(tab, sql, executionDatabase, traceId, elapsed, hiddenPrimaryKeys);
|
||||||
if (patch?.queryAnalysis && hiddenPrimaryKeys.length > 0) {
|
if (patch?.queryAnalysis && hiddenPrimaryKeys.length > 0) {
|
||||||
patch.queryAnalysis = { ...patch.queryAnalysis, allowInsert: false };
|
patch.queryAnalysis = { ...patch.queryAnalysis, allowInsert: false };
|
||||||
}
|
}
|
||||||
@@ -3303,7 +3308,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tab.mode === "query") {
|
if (tab.mode === "query") {
|
||||||
const prepared = await prepareEditableQueryExecution(tab, sqlToExecute, conn, effectiveDbType, traceId, elapsed);
|
const prepared = await prepareEditableQueryExecution(tab, sqlToExecute, conn, effectiveDbType, executionDatabase, traceId, elapsed);
|
||||||
sqlToExecute = prepared.sql;
|
sqlToExecute = prepared.sql;
|
||||||
queryMetadataSql = prepared.metadataSql;
|
queryMetadataSql = prepared.metadataSql;
|
||||||
hiddenPrimaryKeys = prepared.hiddenPrimaryKeys;
|
hiddenPrimaryKeys = prepared.hiddenPrimaryKeys;
|
||||||
@@ -3491,7 +3496,7 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
elapsed: elapsed(),
|
elapsed: elapsed(),
|
||||||
});
|
});
|
||||||
if (current.mode === "query" && current.result) {
|
if (current.mode === "query" && current.result) {
|
||||||
analyzeQueryMetadataInBackground(id, displayedQueryMetadataSql(current, queryMetadataSql), current.result, traceId, elapsed, hiddenPrimaryKeys);
|
analyzeQueryMetadataInBackground(id, displayedQueryMetadataSql(current, queryMetadataSql), current.result, executionDatabase, traceId, elapsed, hiddenPrimaryKeys);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
queryExecutionLog("warn", "stale-result", {
|
queryExecutionLog("warn", "stale-result", {
|
||||||
@@ -3933,7 +3938,9 @@ export const useQueryStore = defineStore("query", () => {
|
|||||||
const sourceStatement = tab.result?.sourceStatement;
|
const sourceStatement = tab.result?.sourceStatement;
|
||||||
if (tab.mode === "query" && sourceStatement && splitMongoCommandRanges(sourceStatement).length === 0) {
|
if (tab.mode === "query" && sourceStatement && splitMongoCommandRanges(sourceStatement).length === 0) {
|
||||||
const metadataStartedAt = performance.now();
|
const metadataStartedAt = performance.now();
|
||||||
analyzeQueryMetadataInBackground(id, sourceStatement, tab.result, uuid().slice(0, 8), () => `${Math.round(performance.now() - metadataStartedAt)}ms`);
|
const connection = useConnectionStore().getConfig(tab.connectionId);
|
||||||
|
const executionDatabase = dataTabExecutionDatabase(connection, tab.database, tab.catalog);
|
||||||
|
analyzeQueryMetadataInBackground(id, sourceStatement, tab.result, executionDatabase, uuid().slice(0, 8), () => `${Math.round(performance.now() - metadataStartedAt)}ms`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user