Skip to main content
Version: Next

SQL Lab Extension Points

SQL Lab provides 5 extension points where extensions can contribute custom UI components. Each area serves a specific purpose and can be customized to add new functionality.

Layout Overview

┌──────────┬─────────────────────────────────────────┬─────────────┐
│ │ │ │
│ │ │ │
│ │ Editor │ │
│ │ │ │
│ Left │ │ Right │
│ Sidebar ├─────────────────────────────────────────┤ Sidebar │
│ │ │ │
│ │ Panels │ │
│ │ │ │
│ │ │ │
│ │ │ │
├──────────┴─────────────────────────────────────────┴─────────────┤
│ Status Bar │
└──────────────────────────────────────────────────────────────────┘
Extension PointIDDescription
Left Sidebarsqllab.leftSidebarNavigation and browsing (database explorer, saved queries)
Editorsqllab.editorSQL query editor workspace
Right Sidebarsqllab.rightSidebarContextual tools (AI assistants, query analysis)
Panelssqllab.panelsResults and related views (visualizations, data profiling)
Status Barsqllab.statusBarConnection status and query metrics

Area Customizations

Each extension point area supports three types of action customizations:

┌───────────────────────────────────────────────────────────────┐
│ Area Title [Button] [Button] [•••] │
├───────────────────────────────────────────────────────────────┤
│ │
│ │
│ Area Content │
│ │
│ (right-click for context menu) │
│ │
│ │
└───────────────────────────────────────────────────────────────┘
Action TypeLocationUse Case
Primary ActionsTop-right buttonsFrequently used actions (e.g., run, refresh, add new)
Secondary Actions3-dot menu (•••)Less common actions (e.g., export, settings)
Context ActionsRight-click menuContext-sensitive actions on content

Examples

Adding a Panel

This example adds a "Data Profiler" panel to SQL Lab:

{
"name": "data_profiler",
"version": "1.0.0",
"frontend": {
"contributions": {
"views": {
"sqllab.panels": [
{
"id": "data_profiler.main",
"name": "Data Profiler"
}
]
}
}
}
}
import { core } from '@apache-superset/core';
import DataProfilerPanel from './DataProfilerPanel';

export function activate(context) {
// Register the panel view with the ID declared in extension.json
const disposable = core.registerView('data_profiler.main', <DataProfilerPanel />);
context.subscriptions.push(disposable);
}

Adding Actions to the Editor

This example adds primary, secondary, and context actions to the editor:

{
"name": "query_tools",
"version": "1.0.0",
"frontend": {
"contributions": {
"commands": [
{
"command": "query_tools.format",
"title": "Format Query",
"icon": "FormatPainterOutlined"
},
{
"command": "query_tools.explain",
"title": "Explain Query"
},
{
"command": "query_tools.copy_as_cte",
"title": "Copy as CTE"
}
],
"menus": {
"sqllab.editor": {
"primary": [
{
"view": "builtin.editor",
"command": "query_tools.format"
}
],
"secondary": [
{
"view": "builtin.editor",
"command": "query_tools.explain"
}
],
"context": [
{
"view": "builtin.editor",
"command": "query_tools.copy_as_cte"
}
]
}
}
}
}
}
import { commands, sqlLab } from '@apache-superset/core';

export function activate(context) {
// Register the commands declared in extension.json
const formatCommand = commands.registerCommand('query_tools.format', {
execute: () => {
const tab = sqlLab.getCurrentTab();
if (tab?.editor) {
// Format the SQL query
}
},
});

const explainCommand = commands.registerCommand('query_tools.explain', {
execute: () => {
const tab = sqlLab.getCurrentTab();
if (tab?.editor) {
// Show query explanation
}
},
});

const copyAsCteCommand = commands.registerCommand('query_tools.copy_as_cte', {
execute: () => {
const tab = sqlLab.getCurrentTab();
if (tab?.editor) {
// Copy selected text as CTE
}
},
});

context.subscriptions.push(formatCommand, explainCommand, copyAsCteCommand);
}

Next Steps