Кейс · CLI-утилита · Go

sqlcsv: SQL-запросы к CSV из командной строки

CLI на Go: SQL-запросы к CSV и TSV. Один статический бинарник, только стандартная библиотека: собственный лексер, парсер и интерпретатор. Потоковая обработка: SELECT, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, JOIN двух файлов (hash join), подсказки «did you mean» в ошибках, --explain и защита вывода от CSV-injection (--csv-safe).

  • Go
  • stdlib only
  • SQL
  • CSV
  • fuzzing
  • SQLite (oracle)
  • GitHub Actions

01 · Как выглядит

Скриншоты

Скриншот проекта «sqlcsv: SQL-запросы к CSV из командной строки» на экране 1280 пикселей
Десктоп, 1280 px
Скриншот проекта «sqlcsv: SQL-запросы к CSV из командной строки» на экране телефона, 390 пикселей
Телефон, 390 px

02 · О проекте

Что это и зачем

CLI на Go: SQL-запросы к CSV и TSV. Один статический бинарник, только стандартная библиотека: собственный лексер, парсер и интерпретатор. Потоковая обработка: SELECT, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, JOIN двух файлов (hash join), подсказки «did you mean» в ошибках, --explain и защита вывода от CSV-injection (--csv-safe).

Ограничения

Только SELECT по одному или двум файлам; подзапросов, UNION, оконных функций, CASE нет.

Правый файл JOIN целиком в памяти; полная сортировка 1 млн строк: 1,27 с и 255 МБ.

Сравнение с другими утилитами не проводилось; проверялось на Windows, Linux и macOS собирает CI.

Что внутри

  • Демо-CSV на 1 000 000 строк (39 МБ): агрегат с GROUP BY за 0,23 с и 13 МБ памяти; ранняя остановка по LIMIT за 0,03 с
  • Oracle-тест: 600 случайных запросов сверяются с SQLite (отдельный модуль), числа с точностью 1e-9
  • Fuzz парсера и движка: любая строка как запрос не вызывает панику
  • Ошибки с позицией и подсказкой имени колонки

03 · Как запустить

Запуск одной командой

git clone <репозиторий по запросу> sqlcsv
cd sqlcsv
go build -o sqlcsv .
./sqlcsv "SELECT city, COUNT(*) FROM testdata/demo-sales.csv GROUP BY city"

04 · Код

Репозиторий приватный

Исходники лежат в приватном репозитории. Напишите в Telegram, открою доступ.

Запросить код