Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
20517b4
Intial commit for phase 4: Dashboards
cgivre Feb 6, 2026
2825e3a
More Phase 4 work
cgivre Feb 6, 2026
367fa23
Dashboard Improvements
cgivre Feb 6, 2026
1321cc2
Fix RAT
cgivre Feb 6, 2026
11c3f23
Add Image Upload to Dashboard
cgivre Feb 6, 2026
3a68908
Image upload working
cgivre Feb 6, 2026
5266921
Added Frontend Unit tests
cgivre Feb 6, 2026
b47360a
Unit test fix
cgivre Feb 6, 2026
97bcaa4
Fix CodeQL issues
cgivre Feb 8, 2026
6b7d2b9
Fix CodeQL issues
cgivre Feb 8, 2026
5d24f9d
Try again...
cgivre Feb 8, 2026
ee49d3b
More CodeQL Fixes
cgivre Feb 8, 2026
be9dee8
More code fixes
cgivre Feb 8, 2026
b8b68b2
Fix build error
cgivre Feb 8, 2026
f9f2a9d
Various fixes
cgivre Feb 9, 2026
e196c07
XML Nav Tree Improvements
cgivre Feb 9, 2026
9b175b3
Nav Tree working
cgivre Feb 9, 2026
68c8660
Add big number
cgivre Feb 9, 2026
d75aa74
Finished File System Config
cgivre Feb 11, 2026
c3c0dce
Fix Linting
cgivre Feb 11, 2026
f39db70
Fix useEffect dependency order in ProspectorSettingsModal
cgivre Feb 11, 2026
e07b7cf
Improve workspace tab UI with instructions, validation, and security
cgivre Feb 11, 2026
6ca4257
Fix Add Workspace button and handle classpath plugin special case
cgivre Feb 11, 2026
14fd3cd
Hide workspace tab for classpath plugin
cgivre Feb 11, 2026
33bc843
Fix Add Workspace button with proper useCallback dependencies
cgivre Feb 11, 2026
beb3e3b
Stabilize workspace handlers and table columns with useCallback and u…
cgivre Feb 11, 2026
0048957
Fix Add Workspace button state persistence issue
cgivre Feb 11, 2026
fe9dbc8
Add validation for duplicate workspace names
cgivre Feb 11, 2026
e535b3d
Fix workspace initialization on first mount
cgivre Feb 11, 2026
a208f70
More improvements
cgivre Feb 12, 2026
b7dca32
Implement column menus for ResultsGrid with comprehensive feature set
cgivre Feb 12, 2026
b02d231
Various improvements
cgivre Feb 12, 2026
b24e435
Dark mode:
cgivre Feb 12, 2026
efc2d12
Minor bug fix
cgivre Feb 12, 2026
9acd002
Fix state
cgivre Feb 13, 2026
9720fa8
Fix Vault Unit Tests
cgivre Feb 13, 2026
788c9a6
Fix Docker based unit tests
cgivre Feb 13, 2026
91e57dd
Visualization improvements
cgivre Feb 13, 2026
51d1db2
Link fix
cgivre Feb 13, 2026
8c954d7
Various fixes
cgivre Feb 18, 2026
b74dbe7
Fixing time grain issues
cgivre Feb 18, 2026
d236f8a
WIP Time Grain
cgivre Feb 18, 2026
28fc2ef
Time grain working
cgivre Feb 18, 2026
5396bde
Filter improvements and hardening.
cgivre Feb 19, 2026
d00ad0a
Refactor SQL generator to use Java port of SQL Glot
cgivre Feb 23, 2026
09c26ee
Fix checkstyles
cgivre Feb 23, 2026
8e53e30
Add trendlines
cgivre Feb 25, 2026
16f7f4d
Profile page improvements
cgivre Feb 26, 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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ target/
tools/venv/
venv/
.vscode/*
/exec/java-exec/src/main/resources/python/.venv/
__pycache__/
*.pyc
.pytest_cache/
.coverage
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 @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,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 @@ -54,6 +55,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;

@Category(JdbcStorageTest.class)
public class TestJdbcUserTranslation extends ClusterTest {
Expand All @@ -65,6 +67,10 @@ public class TestJdbcUserTranslation extends ClusterTest {

@BeforeClass
public static void initMysql() throws Exception {
assumeTrue(
"Docker is not available, skipping container tests",
DockerClientFactory.instance().isDockerAvailable()
);
ClusterFixtureBuilder builder = new ClusterFixtureBuilder(dirTestWatcher)
.configProperty(ExecConstants.HTTP_ENABLE, true)
.configProperty(ExecConstants.HTTP_PORT_HUNT, true)
Expand Down
Loading
Loading