fix(mysql): allow connection-level queries without database

This commit is contained in:
Freedom authored and GitHub committed 2026-07-16 15:38:06 +08:00
1 parent 79c682679d
commit eb4abba713
5 files changed
+59 -10

No files matched your search

@@ -66,6 +66,14 @@ describe("requiresDatabaseSelection", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db")).toBe(false);
});
it("allows MySQL SHOW DATABASES to run without a selected database", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "SHOW DATABASES")).toBe(false);
});
it("allows MySQL SHOW VARIABLES without a selected database", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "SHOW VARIABLES LIKE 'version%'")).toBe(false);
});
it("allows MySQL CREATE SCHEMA with options to run without a selected database", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE SCHEMA `app-db` DEFAULT CHARACTER SET utf8mb4")).toBe(false);
});
@@ -78,16 +86,20 @@ describe("requiresDatabaseSelection", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "SET NAMES utf8mb4; DROP DATABASE IF EXISTS app_db; CREATE DATABASE app_db; USE app_db; INSERT INTO users VALUES (1)")).toBe(false);
});
it("requires a database when MySQL batch statements never establish database context", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; CREATE TABLE users(id INT)")).toBe(true);
it("lets MySQL report statement-specific database requirements", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; CREATE TABLE users(id INT)")).toBe(false);
});
it("requires a database when a USE statement is not a standalone database switch", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; USE app_db SELECT 1; CREATE TABLE users(id INT)")).toBe(true);
it("lets MySQL reject malformed database switches", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; USE app_db SELECT 1; CREATE TABLE users(id INT)")).toBe(false);
});
it("still requires a database for ordinary MySQL queries", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "SELECT * FROM users")).toBe(true);
it.each(["SELECT 1", "SELECT VERSION()", "SELECT * FROM mysql.user", "SELECT * FROM users"])("allows connection-level MySQL query: %s", (sql) => {
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), sql)).toBe(false);
});
it("still requires a database for non-MySQL multi-database connections", () => {
expect(requiresDatabaseSelection(queryTab(), connection("mssql"), "SELECT * FROM dbo.users")).toBe(true);
});
it("allows HANA with default database (empty string) to execute queries", () => {
@@ -6,7 +6,7 @@ import { useConnectionStore } from "@/stores/connectionStore";
import { useSettingsStore } from "@/stores/settingsStore";
import { useToast } from "@/composables/useToast";
import { isSingleDatabase, usesTreeSchemaMode } from "@/lib/database/databaseCapabilities";
import { canExecuteWithoutSelectedDatabase } from "@/lib/connection/connectionLevelDatabaseBootstrap";
import { supportsConnectionLevelSqlExecution } from "@/lib/connection/connectionLevelDatabaseBootstrap";
import { classifySqlActivityKind } from "@/lib/history/historyActivityKind";
import { sqlMetadataRefreshTarget } from "@/lib/sql/sqlMetadataRefresh";
import { isMysqlExecutionErrorResult, usesMysqlProtocolDatabaseType } from "@/lib/query/queryResultError";
@@ -294,12 +294,14 @@ function supportsSqlTemplateParameters(connection: ConnectionConfig | undefined)
return connection.db_type !== "redis" && connection.db_type !== "mongodb";
}
export function requiresDatabaseSelection(tab: QueryTab, connection: ConnectionConfig | undefined, sql = ""): boolean {
export function requiresDatabaseSelection(tab: QueryTab, connection: ConnectionConfig | undefined, _sql = ""): boolean {
if (tab.mode !== "query") return false;
if (!connection) return false;
if (tab.database) return false;
if (tab.database === "" && usesTreeSchemaMode(connection.db_type)) return false;
if (isSingleDatabase(connection.db_type)) return false;
if (canExecuteWithoutSelectedDatabase(connection, sql)) return false;
// MySQL-compatible servers decide per statement whether a default database is required.
// Keep interactive execution connection-scoped instead of rejecting valid qualified or constant queries.
if (supportsConnectionLevelSqlExecution(connection)) return false;
return !["elasticsearch", "qdrant", "milvus", "weaviate", "chromadb", "zookeeper"].includes(connection.db_type);
}