Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fc0fceb
feat: 3/5 queries (1, 2, 5)
sayymeoww May 2, 2026
bb0fb8c
fix: 5/5 queries done
sayymeoww May 2, 2026
a8786c7
feat: added job for github workflow
sayymeoww May 4, 2026
555dcf1
fix: f*ck this columnar shit...
sayymeoww May 4, 2026
132b289
fix: cosmetic stuff
sayymeoww May 4, 2026
2ff40ec
feat: all 43 queries
sayymeoww May 4, 2026
7e32fed
feat: 7/10 queries done
sayymeoww May 4, 2026
48c15a1
feat: +1 query + dashboard
sayymeoww May 4, 2026
cd9e507
feat: 8/10 queries done
sayymeoww May 4, 2026
ff6c620
fix: add missed queries runners
sayymeoww May 4, 2026
18f9608
feat: dashboard for all queries
sayymeoww May 4, 2026
aa4e625
feat: 17/43 queries done
sayymeoww May 4, 2026
45afb41
chore: restore task-7 snapshot for review
sayymeoww May 5, 2026
8ba8412
chore: create trivial review baseline
sayymeoww May 5, 2026
af2524e
fix: exit 0 breaks German
sayymeoww May 12, 2026
b6a7e98
fix: exit 0 again...
sayymeoww May 12, 2026
4b715f8
fix: scheme forgot
sayymeoww May 12, 2026
2db82cd
fix: watafa
sayymeoww May 12, 2026
225225f
review: executor module done
sayymeoww May 15, 2026
5536540
review: io module done
sayymeoww May 15, 2026
7d19ded
review: io module done (finally)
sayymeoww May 15, 2026
463b614
review: executor edits
sayymeoww May 15, 2026
ad44f58
review: -io suffix
sayymeoww May 15, 2026
9ffaa70
review: goddamn.....
sayymeoww May 16, 2026
3ad4b48
review: 99% done
sayymeoww May 17, 2026
3b02d52
review: finally done <3
sayymeoww May 17, 2026
ba3f578
Merge pull request #24 from ik4rd/to-review
ik4rd May 17, 2026
e939dd3
Merge branch 'reviewed' into task-7/queries_main
sayymeoww May 17, 2026
8d4070f
upd: update dashboard
sayymeoww May 17, 2026
eaee82c
fix: added test to test job
sayymeoww May 17, 2026
107d65a
fix: std::chrono::sys_time issue
sayymeoww May 17, 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
8 changes: 1 addition & 7 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
Checks: '-*,cppcoreguidelines-avoid-goto,cppcoreguidelines-pro-type-const-cast, google-readability-casting, modernize-replace-random-shuffle, readability-braces-around-statements, readability-container-size-empty, readability-redundant-control-flow, readability-redundant-string-init, modernize-use-nullptr, readability-identifier-naming, google-build-using-namespace'
Checks: '-*,cppcoreguidelines-avoid-goto,cppcoreguidelines-pro-type-const-cast, google-readability-casting, modernize-replace-random-shuffle, readability-braces-around-statements, readability-container-size-empty, readability-redundant-control-flow, readability-redundant-string-init, modernize-use-nullptr, readability-identifier-naming, google-build-using-namespace'
HeaderFilterRegex: '\.h$'
WarningsAsErrors: '*'
CheckOptions:
Expand All @@ -25,17 +25,11 @@ CheckOptions:
value: lower_case
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.GlobalConstantPrefix
value: k
- key: readability-identifier-naming.GlobalConstantCase
value: CamelCase
- key: readability-identifier-naming.StaticConstantPrefix
value: k
- key: readability-identifier-naming.StaticConstantCase
value: CamelCase
- key: readability-identifier-naming.ConstexprVariableCase
value: CamelCase
- key: readability-identifier-naming.ConstexprVariablePrefix
value: k
- key: google-runtime-int.TypeSuffix
value: _t
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
14 changes: 14 additions & 0 deletions .github/workflows/cmake-single-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,16 @@ jobs:
./tests/test_columnar
./tests/test_columns
./tests/test_csv
./tests/test_executor
./tests/test_fileio
./tests/test_stream
./tests/test_tokenizer

- name: Benchmark Queries
run: |
cd benchmarks
../build/benchmarks/benchmark_queries

sanitizers:
runs-on: ubuntu-latest

Expand Down Expand Up @@ -70,3 +76,11 @@ jobs:
run: |
cd build-sanitizers
ctest --output-on-failure

- name: Benchmark Queries With Sanitizers
env:
ASAN_OPTIONS: detect_leaks=1:strict_string_checks=1:check_initialization_order=1
UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1
run: |
cd benchmarks
../build-sanitizers/benchmarks/benchmark_queries
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ examples/out_columnar
# benchmarks
benchmarks/hits_sample.csv
benchmarks/hits_sample_new.csv
benchmarks/schema_sample.csv
benchmarks/schema_sample_new.csv
benchmarks/hits_sample.columnar
benchmarks/benchmark_csv_to_columnar
Expand Down
12 changes: 2 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@ include(cmake/dependencies_package.cmake)
include(cmake/sanitizers.cmake)

set(COLUMNAR_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/include/convert
${PROJECT_SOURCE_DIR}/include/io
${PROJECT_SOURCE_DIR}/include/model
${PROJECT_SOURCE_DIR}/include/support
${PROJECT_SOURCE_DIR}/include/testing
${PROJECT_SOURCE_DIR}/include/executor
${PROJECT_SOURCE_DIR}/include/sql_parser
${PROJECT_SOURCE_DIR}/include/tl
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/third-party
)

include_directories(${COLUMNAR_INCLUDE_DIRS})

add_compile_options(-Wall -Wextra -Werror -Wpedantic -O2)

set(COLUMNAR_SANITIZERS "" CACHE STRING "Comma or semicolon separated list of sanitizers: address,undefined,leak,thread,memory")
Expand Down
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
# columnar-engine

Колононый движок с нуля (in progress)
Колононый движок с нуля (in progress)

<!-- benchmark-table:start -->
## Dashboard


| Query | First run, ms | Warm avg, ms | Warm median, ms | Warm min, ms | Warm max, ms | Status |
| --- | ---: | ---: | ---: | ---: | ---: | --- |
| [0](benchmarks/queries/query_0.sql) | 1076.34 | 11.43 | 11.67 | 9.57 | 12.81 | ok |
| [1](benchmarks/queries/query_1.sql) | 41.93 | 27.20 | 27.21 | 27.19 | 27.22 | ok |
| [2](benchmarks/queries/query_2.sql) | 64.18 | 51.76 | 51.70 | 51.57 | 52.08 | ok |
| [3](benchmarks/queries/query_3.sql) | 69.35 | 51.94 | 52.19 | 51.02 | 52.38 | ok |
| [4](benchmarks/queries/query_4.sql) | 44.52 | 43.83 | 43.77 | 43.72 | 44.07 | ok |
| [5](benchmarks/queries/query_5.sql) | 59.39 | 48.10 | 45.38 | 44.72 | 56.93 | ok |
| [6](benchmarks/queries/query_6.sql) | 757.49 | 679.54 | 678.98 | 676.05 | 684.13 | ok |
| [7](benchmarks/queries/query_7.sql) | 28.79 | 28.27 | 28.27 | 28.13 | 28.44 | ok |
| [8](benchmarks/queries/query_8.sql) | 126.09 | 112.90 | 112.57 | 111.87 | 114.58 | ok |
| [9](benchmarks/queries/query_9.sql) | 164.71 | 166.90 | 166.97 | 164.56 | 169.11 | ok |
| [10](benchmarks/queries/query_10.sql) | 51.34 | 37.20 | 37.17 | 37.06 | 37.38 | ok |
| [11](benchmarks/queries/query_11.sql) | 50.58 | 38.50 | 38.49 | 38.39 | 38.65 | ok |
| [12](benchmarks/queries/query_12.sql) | 63.54 | 64.18 | 64.19 | 63.69 | 64.67 | ok |
| [13](benchmarks/queries/query_13.sql) | 96.63 | 83.26 | 76.40 | 76.12 | 104.12 | ok |
| [14](benchmarks/queries/query_14.sql) | 83.27 | 113.13 | 87.14 | 72.80 | 205.45 | ok |
| [15](benchmarks/queries/query_15.sql) | 105.19 | 108.28 | 108.08 | 104.50 | 112.46 | ok |
| [16](benchmarks/queries/query_16.sql) | 204.87 | 201.82 | 200.27 | 199.42 | 207.34 | ok |
<!-- benchmark-table:end -->
5 changes: 4 additions & 1 deletion benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ target_link_libraries(benchmark_csv_to_columnar

add_executable(benchmark_queries
benchmark_queries.cpp
support/query_result_checks.cpp
support/query_result_checks.h
support/query_runners.h
)

target_link_libraries(benchmark_queries
Expand All @@ -19,7 +22,7 @@ target_link_libraries(benchmark_queries
target_compile_definitions(benchmark_csv_to_columnar
PRIVATE
COLUMNAR_BENCHMARK_DEFAULT_DATA="${PROJECT_SOURCE_DIR}/benchmarks/hits_sample.csv"
COLUMNAR_BENCHMARK_DEFAULT_SCHEMA="${PROJECT_SOURCE_DIR}/benchmarks/schema_sample.csv"
COLUMNAR_BENCHMARK_DEFAULT_SCHEMA="${PROJECT_SOURCE_DIR}/benchmarks/scheme.csv"
COLUMNAR_BENCHMARK_DEFAULT_OUTPUT="${PROJECT_SOURCE_DIR}/benchmarks/hits_sample.columnar"
COLUMNAR_BENCHMARK_DEFAULT_ROUNDTRIP_DATA="${PROJECT_SOURCE_DIR}/benchmarks/hits_sample_new.csv"
COLUMNAR_BENCHMARK_DEFAULT_ROUNDTRIP_SCHEMA="${PROJECT_SOURCE_DIR}/benchmarks/schema_sample_new.csv"
Expand Down
10 changes: 5 additions & 5 deletions benchmarks/benchmark_csv_to_columnar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include <iostream>
#include <vector>

#include "csv.h"
#include "csv_columnar.h"
#include "error.h"
#include "io/csv.h"
#include "convert/csv_columnar.h"
#include "common/error.h"

#ifndef COLUMNAR_BENCHMARK_DEFAULT_DATA
#define COLUMNAR_BENCHMARK_DEFAULT_DATA "benchmarks/hits_sample.csv"
Expand All @@ -28,7 +28,7 @@
#define COLUMNAR_BENCHMARK_DEFAULT_ROUNDTRIP_SCHEMA "benchmarks/schema_sample_new.csv"
#endif

static constexpr size_t kRowsPerGroup = 50000;
static constexpr size_t RowsPerGroup = 50000;

struct CsvCompareResult {
bool equal = true;
Expand Down Expand Up @@ -64,7 +64,7 @@ static CsvCompareResult CompareCsvFiles(const std::filesystem::path& lhs_path, c

int main(const int argc, char** argv) {
try {
size_t rows_per_group = kRowsPerGroup;
size_t rows_per_group = RowsPerGroup;
if (argc == 2) {
rows_per_group = std::stoull(argv[1]);
}
Expand Down
104 changes: 85 additions & 19 deletions benchmarks/benchmark_queries.cpp
Original file line number Diff line number Diff line change
@@ -1,46 +1,112 @@
#include <algorithm>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>

#include "fileio.h"
#include "executor/executor.h"
#include "io/file.h"
#include "support/query_result_checks.h"
#include "support/query_runners.h"

#ifndef COLUMNAR_BENCHMARK_QUERIES_DIR
#define COLUMNAR_BENCHMARK_QUERIES_DIR "benchmarks/queries"
#endif

static constexpr int kFirstQueryId = 0;
static constexpr int kLastQueryId = 42;
static constexpr int FirstQueryId = 0;
static constexpr int LastQueryId = 16;

void RunQuerySkeleton(const std::filesystem::path& path, const int query_id) {
const std::string sql = ReadTextFile(path);
std::cout << "query_" << query_id << ": found, bytes=" << sql.size() << ", status=skeleton_only" << std::endl;
void RunQuery(const Executor& executor, const std::filesystem::path& path, const int query_id, bool record = false) {
const auto& runners = GetQueryRunners();
const auto it = runners.find(query_id);
const std::string query_sql = std::filesystem::exists(path) ? ReadTextFile(path) : "";
const bool compare_unordered = QueryUsesGroupBy(query_sql);

ExecuteExpected result;
const auto start = std::chrono::steady_clock::now();

if (it != runners.end()) {
result = it->second(executor);
} else if (std::filesystem::exists(path)) {
result = executor.Execute(query_sql);
} else {
std::cout << "query_" << query_id << ": missing, status=skipped" << std::endl;
return;
}

const auto end = std::chrono::steady_clock::now();
const auto duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

if (!result.has_value()) {
std::cout << "query_" << query_id << ": error=\"" << result.error().GetMessage() << "\", status=failed"
<< std::endl;
return;
}

const std::string actual_result = BatchToString(*result);
const std::filesystem::path ref_path =
std::filesystem::path(COLUMNAR_BENCHMARK_QUERIES_DIR) / ("query_" + std::to_string(query_id) + ".csv");

std::string status;

if (record) {
std::ofstream ref_file(ref_path);
ref_file << actual_result;
status = "recorded";
} else if (std::filesystem::exists(ref_path)) {
const std::string expected_result = ReadTextFile(ref_path);
if (compare_unordered ? EqualAsRowMultisets(actual_result, expected_result)
: actual_result == expected_result) {
status = "passed";
} else {
status = "failed";
std::cout << "query_" << query_id << ": expected:\n" << expected_result;
if (!expected_result.empty() && expected_result.back() != '\n') {
std::cout << std::endl;
}
std::cout << "query_" << query_id << ": actual:\n" << actual_result;
if (!actual_result.empty() && actual_result.back() != '\n') {
std::cout << std::endl;
}
}
} else {
status = "no_reference";
}

std::cout << "query_" << query_id << ": rows=" << result->RowsCount() << ", time=" << duration_ms
<< "ms, status=" << status << std::endl;
}

int main() {
int main(const int argc, char** argv) {
try {
bool record = false;
for (int i = 1; i < argc; ++i) {
if (std::string(argv[i]) == "--record") {
record = true;
}
}

const std::filesystem::path queries_dir = COLUMNAR_BENCHMARK_QUERIES_DIR;
const std::filesystem::path data_path = queries_dir.parent_path() / "hits_sample.columnar";

Executor executor;
executor.RegisterTable("hits", data_path);

size_t found_queries = 0;
size_t missing_queries = 0;

std::cout << "queries_dir=" << queries_dir << std::endl;

for (int query_id = kFirstQueryId; query_id <= kLastQueryId; ++query_id) {
for (int query_id = FirstQueryId; query_id <= LastQueryId; ++query_id) {
const std::filesystem::path query_path = queries_dir / ("query_" + std::to_string(query_id) + ".sql");

if (!std::filesystem::exists(query_path)) {
++missing_queries;
std::cout << "query_" << query_id << ": missing, status=skipped" << std::endl;
continue;
if (GetQueryRunners().contains(query_id) || std::filesystem::exists(query_path)) {
++found_queries;
RunQuery(executor, query_path, query_id, record);
}

++found_queries;

RunQuerySkeleton(query_path, query_id);
}

std::cout << "found_queries=" << found_queries << std::endl;
std::cout << "missing_queries=" << missing_queries << std::endl;
std::cout << "total_executed=" << found_queries << std::endl;
} catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;
return 1;
Expand Down
Loading
Loading