Skip to content

SQL Playground — Java source

Run real SQL on sample datasets - or your own schema - right in the browser. Write queries, see formatted results instantly, and export or share them. Powered by sql.js (SQLite WASM); 100% client-side.

This is the Java implementation — the same logic the interactive tool runs, in a shareable, citable form.

// sql-playground — SQL statement splitting, read-only classification, CSV / Markdown serialization (Java).
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public final class SqlPlayground {

    private static final Pattern READ_ONLY =
            Pattern.compile("^(SELECT|WITH|VALUES|EXPLAIN|PRAGMA)\\b", Pattern.CASE_INSENSITIVE);
    // Split on ';' outside '...' literals; a doubled '' inside a string is an escaped quote.
    public static List<String> splitStatements(String sql) {
        List<String> stmts = new ArrayList<>();
        StringBuilder current = new StringBuilder();
        boolean inString = false;
        for (int i = 0; i < sql.length(); i++) {
            char ch = sql.charAt(i);
            if (inString) {
                current.append(ch);
                if (ch == '\'') {
                    if (i + 1 < sql.length() && sql.charAt(i + 1) == '\'') current.append(sql.charAt(++i)); // '' escape
                    else inString = false;
                }
            } else if (ch == '\'') { inString = true; current.append(ch); }
            else if (ch == ';') {
                String t = current.toString().trim();
                if (!t.isEmpty()) stmts.add(t);
                current.setLength(0);
            } else current.append(ch);
        }
        String t = current.toString().trim();
        if (!t.isEmpty()) stmts.add(t);
        return stmts;
    }

    // A leading SELECT / WITH / VALUES / EXPLAIN / PRAGMA marks the statement read-only.
    public static boolean isReadOnlyStatement(String stmt) { return READ_ONLY.matcher(stmt.trim()).find(); }

    // RFC-4180-ish CSV field: quote on , " CR or LF, doubling embedded quotes; null = SQL NULL.
    static String csvField(String cell) {
        String v = cell == null ? "NULL" : cell;
        return v.matches("[^,\"\\r\\n]*") ? v : '"' + v.replace("\"", "\"\"") + '"';
    }

    // Markdown cell: a null is SQL NULL; pipes are backslash-escaped.
    static String mdCell(String cell) { return (cell == null ? "NULL" : cell).replace("|", "\\|"); }
    public static String rowsToCsv(String[] columns, String[][] rows) {
        StringBuilder out = new StringBuilder();
        appendCsvLine(out, columns);
        for (String[] row : rows) appendCsvLine(out, row);
        return out.toString();
    }

    private static void appendCsvLine(StringBuilder out, String[] cells) {
        for (int c = 0; c < cells.length; c++) out.append(c > 0 ? "," : "").append(csvField(cells[c]));
        out.append('\n');
    }

    public static String rowsToMarkdown(String[] columns, String[][] rows) {
        StringBuilder out = new StringBuilder(mdRow(columns)).append('\n').append('|').append(" --- |".repeat(columns.length)).append('\n');
        for (String[] row : rows) out.append(mdRow(row)).append('\n');
        return out.toString();
    }

    private static String mdRow(String[] cells) {
        StringBuilder row = new StringBuilder("|");
        for (String cell : cells) row.append(' ').append(mdCell(cell)).append(" |");
        return row.toString();
    }

    public static void main(String[] args) {
        String script = "CREATE TABLE t (id INT);  SELECT * FROM t WHERE note = 'a''b;c' ; ;DROP TABLE t";
        for (String s : splitStatements(script))
            System.out.printf("[%s] %s%n", isReadOnlyStatement(s) ? "read-only" : "write", s);
        String[] cols = {"name", "note"};
        String[][] rows = {{"O'Brien", "has, \"quotes\""}, {null, "pipe|inside"}};
        System.out.println("\nCSV:");
        System.out.print(rowsToCsv(cols, rows));
        System.out.print(rowsToMarkdown(cols, rows));
    }
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →