提交 900c250d 编写于 作者: S serge-rider

Explain plan UI refactoring

上级 ac2f7e7a
......@@ -64,8 +64,8 @@ import org.jkiss.dbeaver.ui.controls.itemlist.DatabaseObjectListControl;
import org.jkiss.dbeaver.ui.editors.StringEditorInput;
import org.jkiss.dbeaver.ui.editors.SubEditorSite;
import org.jkiss.dbeaver.ui.editors.sql.SQLEditorBase;
import org.jkiss.dbeaver.ui.properties.PropertyTreeViewer;
import org.jkiss.dbeaver.ui.editors.sql.plan.simple.PlanNodesTree;
import org.jkiss.dbeaver.ui.properties.PropertyTreeViewer;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
......@@ -243,8 +243,7 @@ public class SessionManagerViewer<SESSION_TYPE extends DBAServerSession>
String sqlText = curSession == null ? "" : CommonUtils.notEmpty(curSession.getActiveQuery());
if (!CommonUtils.isEmpty(sqlText)) {
DBPDataSource dataSource = sessionManager.getDataSource();
planTree.init(DBUtils.getDefaultContext(dataSource, false), planner, sqlText);
planTree.loadData();
planTree.showPlan(dataSource, null);
}
}
if (detailsFolder.getSelectionIndex() > 0) {
......
......@@ -1455,7 +1455,7 @@ public class SQLEditor extends SQLEditorBase implements
}
if (planView == null) {
planView = new ExplainPlanViewer(this, resultTabs);
planView = new ExplainPlanViewer(this, this, resultTabs);
final CTabItem item = new CTabItem(resultTabs, SWT.CLOSE);
item.setControl(planView.getControl());
......@@ -1469,7 +1469,7 @@ public class SQLEditor extends SQLEditorBase implements
}
try {
planView.explainQueryPlan(getExecutionContext(), sqlQuery);
planView.explainQueryPlan(sqlQuery);
} catch (DBCException e) {
DBWorkbench.getPlatformUI().showError(
SQLEditorMessages.editors_sql_error_execution_plan_title,
......
......@@ -21,6 +21,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPart;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.sql.SQLQuery;
/**
......@@ -30,6 +31,6 @@ public interface SQLPlanViewer {
Viewer createPlanViewer(IWorkbenchPart workbenchPart, Composite parent);
void explainQueryPlan(Viewer viewer, DBCExecutionContext executionContext, SQLQuery query) throws DBCException;
void visualizeQueryPlan(Viewer viewer, SQLQuery query, DBCPlan plan);
}
......@@ -27,8 +27,15 @@ import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IWorkbenchPart;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPContextProvider;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.DBCExecutionPurpose;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlanner;
import org.jkiss.dbeaver.model.sql.SQLQuery;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.DBeaverIcons;
......@@ -41,6 +48,8 @@ import org.jkiss.dbeaver.ui.editors.sql.plan.registry.SQLPlanViewDescriptor;
import org.jkiss.dbeaver.ui.editors.sql.plan.registry.SQLPlanViewRegistry;
import org.jkiss.utils.CommonUtils;
import java.lang.reflect.InvocationTargetException;
/**
* ResultSetViewer
*/
......@@ -49,6 +58,7 @@ public class ExplainPlanViewer extends Viewer
static final Log log = Log.getLog(ExplainPlanViewer.class);
private final IWorkbenchPart workbenchPart;
private final DBPContextProvider contextProvider;
private final Composite planPresentationContainer;
private final VerticalFolder tabViewFolder;
private final Composite planViewComposite;
......@@ -66,9 +76,10 @@ public class ExplainPlanViewer extends Viewer
private PlanViewInfo activeViewInfo;
private SQLQuery lastQuery;
public ExplainPlanViewer(final IWorkbenchPart workbenchPart, Composite parent)
public ExplainPlanViewer(final IWorkbenchPart workbenchPart, DBPContextProvider contextProvider, Composite parent)
{
this.workbenchPart = workbenchPart;
this.contextProvider = contextProvider;
planPresentationContainer = UIUtils.createPlaceholder(parent, 2);
planPresentationContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
......@@ -121,13 +132,10 @@ public class ExplainPlanViewer extends Viewer
return lastQuery;
}
public void explainQueryPlan(DBCExecutionContext executionContext, SQLQuery query) throws DBCException {
public void explainQueryPlan(SQLQuery query) throws DBCException {
this.lastQuery = query;
for (PlanViewInfo viewInfo : getPlanViews()) {
if (viewInfo.viewer != null) {
viewInfo.planViewer.explainQueryPlan(viewInfo.viewer, executionContext, query);
}
}
refresh();
}
private PlanViewInfo[] getPlanViews() {
......@@ -180,8 +188,40 @@ public class ExplainPlanViewer extends Viewer
@Override
public void refresh() {
if (activeViewInfo != null) {
activeViewInfo.viewer.refresh();
DBCQueryPlanner planner;
DBCExecutionContext executionContext = contextProvider.getExecutionContext();
if (executionContext != null) {
DBPDataSource dataSource = executionContext.getDataSource();
planner = DBUtils.getAdapter(DBCQueryPlanner.class, dataSource);
} else {
planner = null;
}
if (planner == null) {
DBWorkbench.getPlatformUI().showError("No SQL Plan","This datasource doesn't support execution plans");
} else {
try {
UIUtils.runInProgressDialog(monitor -> {
try {
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.UTIL, "Explain '" + lastQuery.getText() + "'")) {
DBCPlan plan = planner.planQueryExecution(session, lastQuery.getText());
UIUtils.asyncExec(() -> visualizePlan(plan));
}
} catch (Throwable ex) {
throw new InvocationTargetException(ex);
}
});
} catch (InvocationTargetException e) {
DBWorkbench.getPlatformUI().showError("Explain Plan error","Error explaining SQL execution plan", e.getTargetException());
}
}
}
private void visualizePlan(DBCPlan plan) {
for (PlanViewInfo viewInfo : getPlanViews()) {
if (viewInfo.viewer != null) {
viewInfo.planViewer.visualizeQueryPlan(viewInfo.viewer, lastQuery, plan);
}
}
}
......
......@@ -22,22 +22,17 @@ import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchSite;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.DBCExecutionPurpose;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.exec.plan.DBCPlanNode;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlanner;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.load.DatabaseLoadService;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.ui.LoadingJob;
import org.jkiss.dbeaver.ui.navigator.actions.NavigatorHandlerObjectOpen;
import org.jkiss.dbeaver.ui.controls.ObjectViewerRenderer;
import org.jkiss.dbeaver.ui.controls.itemlist.DatabaseObjectListControl;
import org.jkiss.dbeaver.ui.navigator.actions.NavigatorHandlerObjectOpen;
import org.jkiss.utils.CommonUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
......@@ -46,9 +41,8 @@ import java.util.List;
*/
public class PlanNodesTree extends DatabaseObjectListControl<DBCPlanNode> {
private DBCExecutionContext context;
private DBCQueryPlanner planner;
private String query;
private DBPDataSource dataSource;
public PlanNodesTree(Composite parent, int style, IWorkbenchSite site)
{
......@@ -65,27 +59,29 @@ public class PlanNodesTree extends DatabaseObjectListControl<DBCPlanNode> {
@NotNull
@Override
protected String getListConfigId(List<Class<?>> classList) {
return "ExecutionPlan/" + context.getDataSource().getContainer().getDriver().getId();
return "ExecutionPlan/" + dataSource.getContainer().getDriver().getId();
}
@Override
protected LoadingJob<Collection<DBCPlanNode>> createLoadService()
{
return LoadingJob.createService(
new ExplainPlanService(),
new PlanLoadVisualizer());
return null;
}
public boolean isInitialized()
{
return planner != null;
}
public void showPlan(DBPDataSource dataSource, DBCPlan plan) {
this.dataSource = dataSource;
List<DBCPlanNode> nodes = new ArrayList<>(plan.getPlanNodes());
final TreeViewer itemsViewer = (TreeViewer) PlanNodesTree.this.getItemsViewer();
itemsViewer.getControl().setRedraw(false);
try {
clearListData();
setListData(nodes, false);
itemsViewer.expandToLevel(10);
} finally {
itemsViewer.getControl().setRedraw(true);
}
public void init(DBCExecutionContext context, DBCQueryPlanner planner, String query)
{
this.context = context;
this.planner = planner;
this.query = query;
}
private static ITreeContentProvider CONTENT_PROVIDER = new ITreeContentProvider() {
......@@ -135,11 +131,19 @@ public class PlanNodesTree extends DatabaseObjectListControl<DBCPlanNode> {
};
private class ExplainPlanService extends DatabaseLoadService<Collection<DBCPlanNode>> {
/*
public static class ExplainPlanService extends DatabaseLoadService<Collection<DBCPlanNode>> {
private final DBCQueryPlanner planner;
private final DBCExecutionContext executionContext;
private final String query;
protected ExplainPlanService()
protected ExplainPlanService(DBCQueryPlanner planner, DBCExecutionContext executionContext, String query)
{
super("Explain plan", planner.getDataSource());
this.planner = planner;
this.executionContext = executionContext;
this.query = query;
}
@Override
......@@ -147,7 +151,7 @@ public class PlanNodesTree extends DatabaseObjectListControl<DBCPlanNode> {
throws InvocationTargetException, InterruptedException
{
try {
try (DBCSession session = context.openSession(monitor, DBCExecutionPurpose.UTIL, "Explain '" + query + "'")) {
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.UTIL, "Explain '" + query + "'")) {
DBCPlan plan = planner.planQueryExecution(session, query);
return (Collection<DBCPlanNode>) plan.getPlanNodes();
}
......@@ -172,6 +176,7 @@ public class PlanNodesTree extends DatabaseObjectListControl<DBCPlanNode> {
}
}
}
*/
private class PlanTreeRenderer extends ViewerRenderer {
@Override
......
......@@ -31,11 +31,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPart;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.plan.DBCQueryPlanner;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.sql.SQLQuery;
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
import org.jkiss.dbeaver.ui.ActionUtils;
......@@ -59,7 +55,6 @@ public class SQLPlanTreeViewer extends Viewer
private PropertyTreeViewer planProperties;
private SQLQuery query;
private DBCQueryPlanner planner;
private RefreshPlanAction refreshPlanAction;
private ToggleViewAction toggleViewAction;
private final SashForm leftPanel;
......@@ -113,10 +108,9 @@ public class SQLPlanTreeViewer extends Viewer
planTree.getControl().addPaintListener(e -> {
String message = null;
if (planner == null) {
if (query == null) {
message = "No connection or data source doesn't support execution plan";
} else if (CommonUtils.isEmpty(sqlText.getText())) {
message = "Select a query and run " + ActionUtils.findCommandDescription(
SQLEditorCommands.CMD_EXPLAIN_PLAN,
workbenchPart.getSite(), false);
......@@ -178,6 +172,7 @@ public class SQLPlanTreeViewer extends Viewer
{
return planTree.getItemsViewer();
}
/*
public void explainQueryPlan(DBCExecutionContext executionContext, SQLQuery query) throws DBCException
{
......@@ -209,6 +204,7 @@ public class SQLPlanTreeViewer extends Viewer
refreshPlanAction.setEnabled(true);
toggleViewAction.setEnabled(true);
}
*/
/////////////////////////////////////////////////
// Viewer
......@@ -238,6 +234,12 @@ public class SQLPlanTreeViewer extends Viewer
}
public void showPlan(SQLQuery query, DBCPlan plan) {
this.query = query;
this.sqlText.setText(query.getText());
planTree.showPlan(query.getDataSource(), plan);
}
/////////////////////////////////////////////////
// Actions
......
......@@ -21,6 +21,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPart;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.plan.DBCPlan;
import org.jkiss.dbeaver.model.sql.SQLQuery;
import org.jkiss.dbeaver.ui.editors.sql.SQLPlanViewer;
......@@ -37,8 +38,9 @@ public class SQLPlanViewerSimple implements SQLPlanViewer {
}
@Override
public void explainQueryPlan(Viewer viewer, DBCExecutionContext executionContext, SQLQuery query) throws DBCException {
public void visualizeQueryPlan(Viewer viewer, SQLQuery query, DBCPlan plan) {
SQLPlanTreeViewer treeViewer = (SQLPlanTreeViewer) viewer;
treeViewer.explainQueryPlan(executionContext, query);
treeViewer.showPlan(query, plan);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册