Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@
# debug information files
*.dwo
.cache
build/
build*/
25 changes: 25 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch bo-sql (lldb)",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/build/cli/bo-sql",
"args": [],
"cwd": "${workspaceFolder}",
"preLaunchTask": "Meson: Build all targets",
"stopOnEntry": false,
"terminal": "integrated"
},
{
"type": "lldb",
"request": "attach",
"name": "Attach",
"program": "${workspaceFolder}/build/cli/bo-sql"
}
]
}
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"clangd.arguments": [
"--compile-commands-dir=build-dev",
"--background-index",
"--clang-tidy",
"--header-insertion=iwyu",
"--completion-style=detailed"
]
}
17 changes: 17 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "meson",
"mode": "build",
"problemMatcher": [
"$meson-gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"label": "Meson: Build all targets"
}
]
}
3 changes: 3 additions & 0 deletions catalog/catalog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "catalog/catalog.h"

// Catalog implementation - currently header-only, but can be extended
1 change: 0 additions & 1 deletion catalog/meson.build

This file was deleted.

111 changes: 111 additions & 0 deletions cli/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <iostream>
#include <string>
#include <sstream>
#include <utility>
#include <fmt/core.h>
#include <fmt/color.h>
#include "catalog/catalog.h"
#include "storage/csv_loader.h"
#include "types.h"

template<typename... Args>
void print_info(std::string_view fmt, Args&&... args) { fmt::print("{}\n", fmt::vformat(fmt, fmt::make_format_args(std::forward<Args>(args)...))); }

template<typename... Args>
void print_success(std::string_view fmt, Args&&... args) { fmt::print(fg(fmt::color::green), "{}\n", fmt::vformat(fmt, fmt::make_format_args(std::forward<Args>(args)...))); }

template<typename... Args>
void print_warning(std::string_view fmt, Args&&... args) { fmt::print(fg(fmt::color::yellow), "{}\n", fmt::vformat(fmt, fmt::make_format_args(std::forward<Args>(args)...))); }

template<typename... Args>
void print_error(std::string_view fmt, Args&&... args) { fmt::print(fg(fmt::color::red), "{}\n", fmt::vformat(fmt, fmt::make_format_args(std::forward<Args>(args)...))); }

std::string type_name(TypeId type) {
switch (type) {
case TypeId::INT64: return "INT64";
case TypeId::DOUBLE: return "DOUBLE";
case TypeId::STRING: return "STRING";
case TypeId::DATE32: return "DATE32";
default: return "UNKNOWN";
}
}

int main() {
Catalog catalog;
std::string line;

fmt::print("bo-sql CLI\n> ");

while (std::getline(std::cin, line)) {
std::istringstream iss(line);
std::string command;
iss >> command;

if (command == "LOAD") {
std::string table_keyword, table_name, from_keyword, filename;
iss >> table_keyword >> table_name >> from_keyword >> filename;
if (table_keyword != "TABLE" || from_keyword != "FROM") {
print_warning("Syntax: LOAD TABLE <name> FROM 'file.csv'");
} else {
// Remove quotes from filename
if (!filename.empty() && filename.front() == '\'' && filename.back() == '\'') {
filename = filename.substr(1, filename.size() - 2);
}
try {
std::pair<Table, TableMeta> result = load_csv(filename);
result.first.name = table_name;
result.second.name = table_name;
catalog.register_table(std::move(result.second));

print_success("Loaded table '{}' with {} rows", table_name, result.second.row_count);
} catch (const std::exception& e) {
print_error("Error loading CSV: {}", e.what());
}
}
} else if (command == "SHOW") {
std::string tables_keyword;
iss >> tables_keyword;
if (tables_keyword == "TABLES") {
auto tables = catalog.list_tables();
if (tables.empty()) {
print_info("No tables loaded");
} else {
for (const auto& table : tables) {
fmt::print("{}\n", table);
}
}
} else {
print_warning("Unknown command");
}
} else if (command == "DESCRIBE") {
std::string table_name;
iss >> table_name;
const TableMeta* meta = catalog.get_table(table_name);
if (!meta) {
print_error("Table '{}' not found", table_name);
} else {
fmt::print("Table: {} ({} rows)\n", meta->name, meta->row_count);
fmt::print("Columns:\n");
for (const auto& col : meta->columns) {
fmt::print(" {} {} (ndv: {}", col.name, type_name(col.type), col.stats.ndv);
if (col.type == TypeId::INT64) {
fmt::print(", min: {}, max: {}", col.stats.min_i64, col.stats.max_i64);
} else if (col.type == TypeId::DOUBLE) {
fmt::print(", min: {}, max: {}", col.stats.min_f64, col.stats.max_f64);
} else if (col.type == TypeId::DATE32) {
fmt::print(", min: {}, max: {}", col.stats.min_date, col.stats.max_date);
}
fmt::print(")\n");
}
}
} else if (command == "EXIT" || command == "QUIT") {
break;
} else {
print_warning("Unknown command. Available: LOAD TABLE, SHOW TABLES, DESCRIBE <table>, EXIT");
}

fmt::print("> ");
}

return 0;
}
11 changes: 10 additions & 1 deletion cli/meson.build
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
# CLI module meson.build
# CLI module meson.build

cli_sources = files('main.cpp')

cli_exe = executable('bo-sql',
sources: cli_sources,
include_directories: inc,
link_with: libcore,
dependencies: [dependency('fmt')]
)
1 change: 0 additions & 1 deletion engine/meson.build

This file was deleted.

1 change: 0 additions & 1 deletion exec/meson.build

This file was deleted.

67 changes: 67 additions & 0 deletions include/catalog/catalog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma once

#include <string>
#include <vector>
#include <variant>
#include <unordered_map>
#include <vector>
#include <string>
#include "types.h"

// Column statistics
struct ColumnStats {
i64 min_i64 = 0, max_i64 = 0;
f64 min_f64 = 0.0, max_f64 = 0.0;
Date32 min_date = 0, max_date = 0;
size_t ndv = 0;
};

// Column metadata with statistics
struct ColumnMeta {
std::string name;
TypeId type;
ColumnStats stats;

ColumnMeta(std::string n, TypeId t, size_t ndv = 0)
: name(std::move(n)), type(t) { stats.ndv = ndv; }
};

// Table metadata
struct TableMeta {
std::string name;
std::vector<ColumnMeta> columns;
size_t row_count;
// Additional stats could go here if needed

TableMeta() = default;
TableMeta(std::string n, std::vector<ColumnMeta> cols, size_t rows)
: name(std::move(n)), columns(std::move(cols)), row_count(rows) {}
};

// Catalog for managing table metadata
class Catalog {
private:
std::unordered_map<std::string, TableMeta> tables_;

public:
// Register a table in the catalog
void register_table(TableMeta table_meta) {
tables_[table_meta.name] = std::move(table_meta);
}

// Get table metadata by name
const TableMeta* get_table(const std::string& name) const {
auto it = tables_.find(name);
return it != tables_.end() ? &it->second : nullptr;
}

// List all table names
std::vector<std::string> list_tables() const {
std::vector<std::string> names;
names.reserve(tables_.size());
for (std::unordered_map<std::string, TableMeta>::const_iterator it = tables_.begin(); it != tables_.end(); ++it) {
names.push_back(it->first);
}
return names;
}
};
15 changes: 13 additions & 2 deletions parser/ast.h → include/parser/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
#include <vector>
#include <variant>
#include <memory>
#include "../include/types.h"
#include "types.h"

// Types of expressions in the AST
enum class ExprType {
COLUMN_REF,
LITERAL_INT,
Expand All @@ -14,36 +15,46 @@ enum class ExprType {
BINARY_OP
};

// Binary operators
enum class BinaryOp {
EQ, NE, LT, LE, GT, GE,
ADD, SUB, MUL, DIV
};

// Base expression node
struct Expr {
ExprType type;
std::variant<std::string, i64, f64, std::string> value; // for literals
// For literals: use separate fields since no variant
std::string str_val;
i64 i64_val;
f64 f64_val;
BinaryOp op; // for binary
std::unique_ptr<Expr> left, right; // for binary
};

// Item in SELECT list with optional alias
struct SelectItem {
std::string alias;
std::unique_ptr<Expr> expr;
};

// Aggregate functions
enum class AggFunc {
NONE, SUM, COUNT, AVG
};

// GROUP BY clause
struct GroupByClause {
std::vector<std::unique_ptr<Expr> > columns;
};

// Item in ORDER BY clause
struct OrderByItem {
std::unique_ptr<Expr> expr;
bool asc = true;
};

// SELECT statement AST node
struct SelectStmt {
std::vector<SelectItem> select_list;
std::string from_table;
Expand Down
Loading