Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
b563ee1
Intial commit for phase 4: Dashboards
cgivre Feb 6, 2026
cdc9109
More Phase 4 work
cgivre Feb 6, 2026
fdf8cc2
Dashboard Improvements
cgivre Feb 6, 2026
da0c734
Fix RAT
cgivre Feb 6, 2026
b6d2d3d
Add Image Upload to Dashboard
cgivre Feb 6, 2026
0506462
Image upload working
cgivre Feb 6, 2026
c5fe2df
Added Frontend Unit tests
cgivre Feb 6, 2026
8a7ad59
Unit test fix
cgivre Feb 6, 2026
e33f613
Fix CodeQL issues
cgivre Feb 8, 2026
9fbb0d9
Fix CodeQL issues
cgivre Feb 8, 2026
0de7247
Try again...
cgivre Feb 8, 2026
64898e7
More CodeQL Fixes
cgivre Feb 8, 2026
45bcbc2
More code fixes
cgivre Feb 8, 2026
1bd0b36
Fix build error
cgivre Feb 8, 2026
1712d6e
Various fixes
cgivre Feb 9, 2026
abdb11a
XML Nav Tree Improvements
cgivre Feb 9, 2026
4254a64
Nav Tree working
cgivre Feb 9, 2026
39ce12e
Add big number
cgivre Feb 9, 2026
4324ff8
Finished File System Config
cgivre Feb 11, 2026
3a4131d
Fix Linting
cgivre Feb 11, 2026
ff0edbd
Fix useEffect dependency order in ProspectorSettingsModal
cgivre Feb 11, 2026
5415136
Improve workspace tab UI with instructions, validation, and security
cgivre Feb 11, 2026
68bd3d8
Fix Add Workspace button and handle classpath plugin special case
cgivre Feb 11, 2026
f5f0329
Hide workspace tab for classpath plugin
cgivre Feb 11, 2026
ca6bdef
Fix Add Workspace button with proper useCallback dependencies
cgivre Feb 11, 2026
1dc7284
Stabilize workspace handlers and table columns with useCallback and u…
cgivre Feb 11, 2026
68dc0f3
Fix Add Workspace button state persistence issue
cgivre Feb 11, 2026
4f279dc
Add validation for duplicate workspace names
cgivre Feb 11, 2026
9a9e214
Fix workspace initialization on first mount
cgivre Feb 11, 2026
aaecbbe
More improvements
cgivre Feb 12, 2026
2fa31e0
Implement column menus for ResultsGrid with comprehensive feature set
cgivre Feb 12, 2026
970686d
Various improvements
cgivre Feb 12, 2026
649f8a1
Dark mode:
cgivre Feb 12, 2026
19a75ba
Minor bug fix
cgivre Feb 12, 2026
87cd148
Fix state
cgivre Feb 13, 2026
6b358c2
Fix Vault Unit Tests
cgivre Feb 13, 2026
840b825
Fix Docker based unit tests
cgivre Feb 13, 2026
a4caf5e
Visualization improvements
cgivre Feb 13, 2026
40c0e70
Link fix
cgivre Feb 13, 2026
74b8d39
Various fixes
cgivre Feb 18, 2026
9648632
Fixing time grain issues
cgivre Feb 18, 2026
5e2ea8b
WIP Time Grain
cgivre Feb 18, 2026
7a13812
Time grain working
cgivre Feb 18, 2026
f16c442
Filter improvements and hardening.
cgivre Feb 19, 2026
7d5f2ec
Refactor SQL generator to use Java port of SQL Glot
cgivre Feb 23, 2026
07fa316
Fix checkstyles
cgivre Feb 23, 2026
6defce2
Add trendlines
cgivre Feb 25, 2026
befbff7
Profile page improvements
cgivre Feb 26, 2026
f3bca5a
Implement Profile Detail Page — Dashboard-style redesign with AI advisor
cgivre Feb 26, 2026
167a951
Improve Profile Detail Page layout: add query display and evenly-spac…
cgivre Feb 26, 2026
7ef5b3a
Fix AI advisor context serialization error
cgivre Feb 26, 2026
12811d2
Add credential redaction to prevent sensitive data exposure to AI
cgivre Feb 26, 2026
231fa53
Improve CSRF token handling for hosted deployments
cgivre Feb 26, 2026
0ff6ebc
Revert "Improve CSRF token handling for hosted deployments"
cgivre Feb 26, 2026
aae0acc
Added new visualizations
cgivre Mar 2, 2026
a033645
Fix streaming UI bug
cgivre Mar 2, 2026
3c90379
WIP
cgivre Mar 6, 2026
759dfd8
Size improvements
cgivre Mar 6, 2026
b6725bf
UI Improvements
cgivre Mar 8, 2026
36af30f
More data sources
cgivre Mar 9, 2026
d6de53a
More data sources
cgivre Mar 9, 2026
97aee7a
Schema tree fixes
cgivre Mar 9, 2026
660d124
Fix Metrics and Profiles Pages
cgivre Mar 10, 2026
768217d
Schema tree fixes
cgivre Mar 11, 2026
0c6c107
Updated gitignore
cgivre Mar 11, 2026
aa23e07
Fix CodeQL issues
cgivre Mar 11, 2026
c4aa404
Add backend result cache service with security hardening
cgivre Mar 12, 2026
165a1c4
Add frontend memory optimization with LRU cache and backend integration
cgivre Mar 12, 2026
1c99d8f
Add server-side pagination for large result sets
cgivre Mar 12, 2026
a2d383b
Remove unused act import from useServerPagination test
cgivre Mar 12, 2026
74a22d8
Fix CodeQL
cgivre Mar 12, 2026
0780c00
Fix build errors
cgivre Mar 12, 2026
45843d6
PDF Fix
cgivre Mar 12, 2026
3ad3c35
Various updates
cgivre Mar 12, 2026
d2c3c4a
Added sys project
cgivre Mar 12, 2026
de2ab02
Fix unit tests
cgivre Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/workflows/sqllab-frontend.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

name: SQL Lab Frontend CI

on:
push:
paths:
- 'exec/java-exec/src/main/resources/webapp/**'
pull_request:
paths:
- 'exec/java-exec/src/main/resources/webapp/**'

defaults:
run:
working-directory: exec/java-exec/src/main/resources/webapp

jobs:
build-and-test:
name: Build & Test
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20]
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: exec/java-exec/src/main/resources/webapp/package-lock.json

- name: Install dependencies
run: npm ci

- name: TypeScript type check
run: npx tsc --noEmit

- name: Lint
run: npm run lint

- name: Run tests
run: npx vitest run --passWithNoTests

- name: Build
run: npm run build
19 changes: 18 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,21 @@ target/
tools/venv/
venv/
.vscode/*
exec/java-exec/src/main/resources/webapp/
/exec/java-exec/src/main/resources/python/.venv/
__pycache__/
*.pyc
.pytest_cache/
.coverage

# Frontend (webapp)
node_modules/
.vite/
.env
.env.local
.env.*.local
*.swo
Thumbs.db
coverage/
/exec/java-exec/src/main/resources/webapp/dist/
/exec/java-exec/src/main/resources/webapp/node/
result-cache/
53 changes: 53 additions & 0 deletions build-frontend.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Build the SQL Lab frontend and update the distribution.
# Usage: ./build-frontend.sh

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
WEBAPP_DIR="$SCRIPT_DIR/exec/java-exec/src/main/resources/webapp"
DIST_BASE="$SCRIPT_DIR/distribution/target"

echo "=== Building SQL Lab frontend ==="
cd "$WEBAPP_DIR"
npm run build

echo ""
echo "=== Building java-exec module ==="
cd "$SCRIPT_DIR"
mvn package -pl exec/java-exec -DskipTests -Dcheckstyle.skip=true -q

# Find the distribution directory and copy the jar
DIST_DIR=$(find "$DIST_BASE" -name "jars" -type d 2>/dev/null | head -1)
if [ -n "$DIST_DIR" ]; then
echo ""
echo "=== Copying jar to distribution ==="
cp "$SCRIPT_DIR/exec/java-exec/target/drill-java-exec-"*"-SNAPSHOT.jar" "$DIST_DIR/"
echo "Updated: $DIST_DIR/"
else
echo ""
echo "WARNING: Distribution directory not found under $DIST_BASE"
echo "Run a full 'mvn package' first to create the distribution, or copy the jar manually:"
echo " cp exec/java-exec/target/drill-java-exec-*-SNAPSHOT.jar <drill-distribution>/jars/"
fi

echo ""
echo "=== Done! Restart Drill and hard-refresh your browser (Cmd+Shift+R) ==="
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ public List<String> extensions() {
return this.extensions;
}

/**
* Standard getter for extensions, consistent with other FormatPluginConfig implementations.
*/
public List<String> getExtensions() {
return this.extensions;
}

public boolean combinePages() {
return this.combinePages;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ public void close() {

/**
* This function processes the XML elements. This function stops reading when the
* limit (if any) which came from the query has been reached or the Iterator runs out of
* elements.
* limit (if any) which came from the query has been reached, a complete row has been
* read, or the Iterator runs out of elements.
* @return True if there are more elements to parse, false if not
*/
private boolean processElements() {
Expand Down Expand Up @@ -197,6 +197,13 @@ private boolean processElements() {

// Process the event
processEvent(currentEvent, lastEvent, reader.peek());

// After completing a row, return to let next() check batch capacity.
// This prevents batch overflow errors that occur when rows accumulate
// beyond what the batch can hold without the isFull() check running.
if (currentState == xmlState.ROW_ENDED) {
return true;
}
} catch (XMLStreamException e) {
throw UserException
.dataReadError(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.CassandraContainer;

@Category(SlowTest.class)
Expand All @@ -42,6 +43,10 @@ public class TestCassandraSuite extends BaseTest {

@BeforeClass
public static void initCassandra() {
org.junit.Assume.assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
synchronized (TestCassandraSuite.class) {
if (initCount.get() == 0) {
startCassandra();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.elasticsearch.ElasticsearchContainer;

import com.google.api.client.util.SslUtils;
Expand All @@ -54,6 +55,8 @@
import java.time.Duration;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.Assume.assumeTrue;


@Category(SlowTest.class)
@RunWith(Suite.class)
Expand All @@ -76,6 +79,10 @@ public class TestElasticsearchSuite extends BaseTest {

@BeforeClass
public static void initElasticsearch() throws IOException, GeneralSecurityException {
assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
synchronized (TestElasticsearchSuite.class) {
if (initCount.get() == 0) {
startElasticsearch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Table;
Expand Down Expand Up @@ -112,6 +113,16 @@ public Table getTable(String name) {
}
}

@Override
public Set<String> getTableNames() {
return tables.keySet();
}

@Override
public Set<String> getSubSchemaNames() {
return subSchemas.keySet();
}

@Override
public String getTypeName() {
return HttpStoragePluginConfig.NAME;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.ext.ScriptUtils;
Expand All @@ -41,6 +42,7 @@
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

@Category(JdbcStorageTest.class)
public class TestJdbcInsertWithMySQL extends ClusterTest {
Expand All @@ -51,6 +53,10 @@ public class TestJdbcInsertWithMySQL extends ClusterTest {

@BeforeClass
public static void initMysql() throws Exception {
assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
startCluster(ClusterFixture.builder(dirTestWatcher));
dirTestWatcher.copyResourceToRoot(Paths.get(""));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
Expand All @@ -37,6 +38,7 @@
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

@Category(JdbcStorageTest.class)
public class TestJdbcInsertWithPostgres extends ClusterTest {
Expand All @@ -46,6 +48,10 @@ public class TestJdbcInsertWithPostgres extends ClusterTest {

@BeforeClass
public static void initPostgres() throws Exception {
assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
startCluster(ClusterFixture.builder(dirTestWatcher));
dirTestWatcher.copyResourceToRoot(Paths.get(""));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.ClickHouseContainer;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.utility.DockerImageName;
Expand All @@ -42,6 +43,7 @@
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

/**
* JDBC storage plugin tests against Clickhouse.
Expand All @@ -56,6 +58,10 @@ public class TestJdbcPluginWithClickhouse extends ClusterTest {

@BeforeClass
public static void initClickhouse() throws Exception {
assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
startCluster(ClusterFixture.builder(dirTestWatcher));
String osName = System.getProperty("os.name").toLowerCase();
DockerImageName imageName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.utility.DockerImageName;

Expand All @@ -55,6 +56,10 @@ public class TestJdbcPluginWithMSSQL extends ClusterTest {

@BeforeClass
public static void initMSSQL() throws Exception {
Assume.assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
Assume.assumeTrue(System.getProperty("os.arch").matches("(amd64|x86_64)"));

startCluster(ClusterFixture.builder(dirTestWatcher));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.ext.ScriptUtils;
Expand All @@ -58,6 +59,10 @@ public class TestJdbcPluginWithMySQLIT extends ClusterTest {

@BeforeClass
public static void initMysql() throws Exception {
Assume.assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
startCluster(ClusterFixture.builder(dirTestWatcher));
String osName = System.getProperty("os.name").toLowerCase();
String mysqlDBName = "drill_mysql_test";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.utility.DockerImageName;
Expand All @@ -43,6 +44,7 @@
import java.util.TimeZone;

import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

/**
* JDBC storage plugin tests against Postgres.
Expand All @@ -56,6 +58,10 @@ public class TestJdbcPluginWithPostgres extends ClusterTest {

@BeforeClass
public static void initPostgres() throws Exception {
assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
startCluster(ClusterFixture.builder(dirTestWatcher));
String postgresDBName = "drill_postgres_test";
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
Expand Down
Loading
Loading