feat: keep EXPLAIN output format traditional, on newer MySQL servers

Refs #2423
This commit is contained in:
Ansgar Becker
2026-03-11 17:09:21 +01:00
parent f5c5f33530
commit 90f9937426
3 changed files with 17 additions and 8 deletions

View File

@@ -3346,6 +3346,11 @@ begin
' WHERE'+
' REFERENCED_TABLE_SCHEMA = :EscapedDatabase AND'+
' REFERENCED_TABLE_NAME = :EscapedName';
qExplain: Result := IfThen(
(FServerVersion >= 80400) and (FServerVersion < 100000), // Not MariaDB
'EXPLAIN FORMAT=TRADITIONAL %s',
'EXPLAIN %s'
);
else Result := inherited;
end;
end;

View File

@@ -46,7 +46,7 @@ type
qLockedTables, qDisableForeignKeyChecks, qEnableForeignKeyChecks,
qOrderAsc, qOrderDesc, qGetRowCountExact, qGetRowCountApprox,
qForeignKeyDrop, qGetTableColumns, qGetCollations, qGetCollationsExtended, qGetCharsets,
qGetReverseForeignKeys);
qGetReverseForeignKeys, qExplain);
TSqlProvider = class
strict protected
FNetType: TNetType;

View File

@@ -3145,6 +3145,7 @@ end;
procedure TMainForm.actExecuteQueryExecute(Sender: TObject);
var
ProfileNode: PVirtualNode;
Conn: TDBConnection;
Batch: TSQLBatch;
Tab: TQueryTab;
BindParam: Integer;
@@ -3154,11 +3155,12 @@ var
ContainsUnsafeQueries, DoExecute: Boolean;
begin
Tab := QueryTabs.ActiveTab;
Conn := ActiveConnection;
OperationRunning(True);
DoExecute := True;
ShowStatusMsg(_('Splitting SQL queries ...'));
Batch := TSQLBatch.Create(ActiveConnection.Parameters.NetTypeGroup);
Batch := TSQLBatch.Create(Conn.Parameters.NetTypeGroup);
if Sender = actExecuteSelection then begin
Batch.SQL := Tab.Memo.SelText;
Tab.LeftOffsetInMemo := Tab.Memo.SelStart;
@@ -3170,7 +3172,7 @@ begin
ErrorDialog(_('Current query is empty'), _('Please move the cursor inside the query you want to use.'));
DoExecute := False;
end else begin
Batch.SQL := 'EXPLAIN ' + CurrentQuery;
Batch.SQL := Conn.SqlProvider.GetSql(qExplain, [CurrentQuery]);
end;
end else begin
Batch.SQL := Tab.Memo.Text;
@@ -3226,7 +3228,7 @@ begin
ProfileNode := FindNode(Tab.treeHelpers, TQueryTab.HelperNodeProfile, nil);
Tab.DoProfile := Assigned(ProfileNode) and (Tab.treeHelpers.CheckState[ProfileNode] in CheckedStates);
if Tab.DoProfile then try
ActiveConnection.Query('SET profiling=1');
Conn.Query('SET profiling=1');
except
on E:EDbError do begin
ErrorDialog(f_('Query profiling requires %s or later, and the server must not be configured with %s.', ['MySQL 5.0.37', '--disable-profiling']), E.Message);
@@ -3236,9 +3238,9 @@ begin
// Start the execution thread
Screen.Cursor := crAppStart;
ActiveConnection.Ping(True); // Prevents SynEdit paint exceptions if connection was killed outside
Conn.Ping(True); // Prevents SynEdit paint exceptions if connection was killed outside
Tab.QueryRunning := True;
Tab.ExecutionThread := TQueryThread.Create(ActiveConnection, Batch, Tab.Number);
Tab.ExecutionThread := TQueryThread.Create(Conn, Batch, Tab.Number);
end;
ValidateQueryControls(Sender);
@@ -13713,15 +13715,17 @@ procedure TMainForm.lblExplainProcessClick(Sender: TObject);
var
Tab: TQueryTab;
UsedDatabase: String;
Conn: TDBConnection;
begin
// Click on "Explain" link label, in process viewer
Conn := ActiveConnection;
actNewQueryTabExecute(Sender);
Tab := QueryTabs[QueryTabs.Count-1];
UsedDatabase := listProcesses.Text[listProcesses.FocusedNode, 3];
if not UsedDatabase.IsEmpty then begin
Tab.Memo.Lines.Add('USE ' + ActiveConnection.QuoteIdent(UsedDatabase) + ';');
Tab.Memo.Lines.Add('USE ' + Conn.QuoteIdent(UsedDatabase) + ';');
end;
Tab.Memo.Lines.Add('EXPLAIN' + sLineBreak + SynMemoProcessView.Text + ';');
Tab.Memo.Lines.Add(Conn.SqlProvider.GetSql(qExplain, [SynMemoProcessView.Text]) + ';');
Tab.TabSheet.Show;
actExecuteQueryExecute(Sender);
end;