Skip to content
This repository has been archived by the owner on Apr 15, 2023. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: chotchki/feophant
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.8.0
Choose a base ref
...
head repository: chotchki/feophant
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Aug 15, 2021

  1. Copy the full SHA
    c1ae67c View commit details
  2. Copy the full SHA
    07ddd3e View commit details
  3. Updating todo

    chotchki committed Aug 15, 2021
    Copy the full SHA
    46ba3ba View commit details
  4. Added a non-technical todo

    chotchki committed Aug 15, 2021
    Copy the full SHA
    25cc9b0 View commit details
  5. Copy the full SHA
    ece5a29 View commit details

Commits on Aug 16, 2021

  1. Copy the full SHA
    c700af4 View commit details
  2. Copy the full SHA
    32f7ccf View commit details
  3. Unused import cleanup

    chotchki committed Aug 16, 2021
    Copy the full SHA
    b05b44a View commit details

Commits on Aug 20, 2021

  1. Copy the full SHA
    0edd6b6 View commit details

Commits on Aug 21, 2021

  1. Copy the full SHA
    ebf78e1 View commit details
  2. Copy the full SHA
    12f5690 View commit details

Commits on Aug 22, 2021

  1. Copy the full SHA
    a53cf69 View commit details

Commits on Aug 23, 2021

  1. Implemented #16

    chotchki committed Aug 23, 2021
    Copy the full SHA
    759b978 View commit details
  2. Copy the full SHA
    fcfd6ce View commit details
  3. Copy the full SHA
    0285fcd View commit details

Commits on Aug 25, 2021

  1. Switched the index manager over to the locking system.

    However the index code is NOT working yet.
    chotchki committed Aug 25, 2021
    Copy the full SHA
    ea6ba39 View commit details

Commits on Aug 26, 2021

  1. Upgraded to nom 7

    chotchki committed Aug 26, 2021
    Copy the full SHA
    2baabae View commit details

Commits on Aug 28, 2021

  1. Copy the full SHA
    a67e8f7 View commit details
  2. Copy the full SHA
    05cb708 View commit details
  3. Copy the full SHA
    c44d9ae View commit details
  4. Fixed the shutdown warning

    chotchki committed Aug 28, 2021
    Copy the full SHA
    00d4860 View commit details
  5. Copy the full SHA
    510aaba View commit details
  6. Missed a rustfmt

    chotchki committed Aug 28, 2021
    Copy the full SHA
    6341c39 View commit details

Commits on Aug 30, 2021

  1. Integrated index and constraint definition into the table objects. Ne…

    …ed to continue to implement.
    chotchki committed Aug 30, 2021
    Copy the full SHA
    028fe2e View commit details
  2. Copy the full SHA
    4ff3aee View commit details

Commits on Sep 1, 2021

  1. Update to logo

    chotchki committed Sep 1, 2021
    Copy the full SHA
    795a561 View commit details

Commits on Sep 3, 2021

  1. Copy the full SHA
    81aa29d View commit details
  2. Fixing an incorrect loop

    chotchki committed Sep 3, 2021
    Copy the full SHA
    5cea68e View commit details
  3. Copy the full SHA
    cfc325b View commit details

Commits on Sep 4, 2021

  1. Clippy cleanups

    chotchki committed Sep 4, 2021
    Copy the full SHA
    2370aaa View commit details
  2. Copy the full SHA
    d95965e View commit details
  3. Copy the full SHA
    ca25b2d View commit details
  4. Copy the full SHA
    c65cef8 View commit details

Commits on Sep 12, 2021

  1. Copy the full SHA
    53cda6d View commit details

Commits on Sep 16, 2021

  1. Implementation of a split function.

    Been busy at work so this is an isolated commit the rest of the change is still intermingled
    chotchki committed Sep 16, 2021
    Copy the full SHA
    edcc94b View commit details

Commits on Sep 17, 2021

  1. Copy the full SHA
    558df4b View commit details

Commits on Sep 24, 2021

  1. Starting to push up the new parts of the index functionality as I get…

    … unit tests working on them
    chotchki committed Sep 24, 2021
    Copy the full SHA
    6c55862 View commit details
  2. Adding the new trait mod

    chotchki committed Sep 24, 2021
    Copy the full SHA
    830ac8d View commit details
  3. Copy the full SHA
    1867d1a View commit details
  4. Copy the full SHA
    116ab63 View commit details
  5. More trait implementations

    chotchki committed Sep 24, 2021
    Copy the full SHA
    f20b728 View commit details
  6. Copy the full SHA
    d6cb4f8 View commit details
  7. Cleaned up a warning

    chotchki committed Sep 24, 2021
    Copy the full SHA
    eabe007 View commit details
  8. Copy the full SHA
    36735e6 View commit details

Commits on Oct 7, 2021

  1. This is a mass commit of where I've gotten with the current I/O+Cache…

    …+Locking approach.
    
    I'm about to do some mass changes but I don't want to loose this.
    chotchki committed Oct 7, 2021
    Copy the full SHA
    2837532 View commit details

Commits on Oct 8, 2021

  1. Pushing in progress

    chotchki committed Oct 8, 2021
    Copy the full SHA
    a598c0b View commit details
  2. Another intermediate step

    chotchki committed Oct 8, 2021
    Copy the full SHA
    614673a View commit details

Commits on Oct 9, 2021

  1. Have the revised I/O well coded.

    However have bugs/infinite loops, need more testing.
    chotchki committed Oct 9, 2021
    Copy the full SHA
    cc6a60e View commit details
  2. Fixed an infinite loop

    chotchki committed Oct 9, 2021
    Copy the full SHA
    a4bea6f View commit details
  3. Copy the full SHA
    e18cfd1 View commit details
Showing with 3,968 additions and 2,326 deletions.
  1. +6 −4 Cargo.toml
  2. +10 −126 README.md
  3. +1 −1 SECURITY.md
  4. +22 −56 benches/feophant_benchmark.rs
  5. +1 −1 docs/_config.yml
  6. +51 −0 docs/feophant_logo_v2.svg
  7. +2 −4 src/codec/network_frame.rs
  8. +4 −2 src/constants.rs
  9. +7 −0 src/constants/page_settings.rs
  10. +35 −0 src/constants/system_tables.rs
  11. +76 −0 src/constants/system_tables/pg_attribute.rs
  12. +55 −0 src/constants/system_tables/pg_class.rs
  13. +76 −0 src/constants/system_tables/pg_constraint.rs
  14. +76 −0 src/constants/system_tables/pg_index.rs
  15. +0 −78 src/constants/table_definitions.rs
  16. +17 −6 src/engine.rs
  17. +2 −2 src/engine/analyzer.rs
  18. +172 −41 src/engine/analyzer/definition_lookup.rs
  19. +57 −14 src/engine/executor.rs
  20. +3 −8 src/engine/io.rs
  21. +40 −0 src/engine/io/block_layer.rs
  22. +401 −0 src/engine/io/block_layer/file_manager2.rs
  23. +44 −24 src/engine/io/{file_manager → block_layer}/file_operations.rs
  24. +236 −0 src/engine/io/block_layer/free_space_manager.rs
  25. +77 −0 src/engine/io/block_layer/lock_manager.rs
  26. 0 src/engine/io/{file_manager → block_layer}/resource_formatter.rs
  27. +80 −16 src/engine/io/constraint_manager.rs
  28. +0 −255 src/engine/io/file_manager.rs
  29. +0 −704 src/engine/io/file_manager/file_executor.rs
  30. +0 −12 src/engine/io/file_manager/request_type.rs
  31. +6 −0 src/engine/io/format_traits.rs
  32. +9 −0 src/engine/io/format_traits/parseable.rs
  33. +51 −0 src/engine/io/format_traits/serializable.rs
  34. +12 −0 src/engine/io/index_formats.rs
  35. +153 −45 src/engine/io/index_formats/btree_branch.rs
  36. +106 −0 src/engine/io/index_formats/btree_first_page.rs
  37. +226 −63 src/engine/io/index_formats/btree_leaf.rs
  38. +28 −30 src/engine/io/index_formats/btree_node.rs
  39. +79 −0 src/engine/io/index_formats/index_search.rs
  40. +90 −0 src/engine/io/index_formats/split_branch.rs
  41. +278 −158 src/engine/io/index_manager.rs
  42. +176 −0 src/engine/io/index_manager/find_leaf.rs
  43. +142 −0 src/engine/io/index_manager/split_leaf.rs
  44. +0 −214 src/engine/io/lock_manager.rs
  45. +0 −1 src/engine/io/page_cache_manager.rs
  46. +4 −0 src/engine/io/page_formats.rs
  47. +39 −7 src/engine/io/page_formats/item_id_data.rs
  48. +32 −65 src/engine/io/page_formats/page_data.rs
  49. +28 −7 src/engine/io/page_formats/page_header.rs
  50. +76 −0 src/engine/io/page_formats/page_id.rs
  51. +87 −22 src/engine/io/page_formats/page_offset.rs
  52. +39 −31 src/engine/io/row_formats/item_pointer.rs
  53. +18 −8 src/engine/io/row_formats/null_mask.rs
  54. +49 −26 src/engine/io/row_formats/row_data.rs
  55. +163 −119 src/engine/io/row_manager.rs
  56. +37 −21 src/engine/io/visible_row_manager.rs
  57. +5 −0 src/engine/objects.rs
  58. +2 −5 src/engine/objects/attribute.rs
  59. +32 −0 src/engine/objects/constraints.rs
  60. +21 −0 src/engine/objects/constraints/parse_constraint.rs
  61. +3 −5 src/engine/objects/index.rs
  62. +1 −0 src/engine/objects/parse_tree.rs
  63. +1 −1 src/engine/objects/planned_statement.rs
  64. +15 −0 src/engine/objects/sql_tuple.rs
  65. +16 −12 src/engine/objects/table.rs
  66. +44 −2 src/engine/objects/types/base_sql_types.rs
  67. +2 −1 src/engine/objects/types/parse_type.rs
  68. +13 −0 src/engine/objects/types/sql_type_definition.rs
  69. +18 −6 src/engine/sql_parser.rs
  70. +3 −0 src/engine/sql_parser/commands.rs
  71. +2 −2 src/engine/sql_parser/{ → commands}/create.rs
  72. +27 −4 src/engine/sql_parser/{ → commands}/create/create_table.rs
  73. +3 −3 src/engine/sql_parser/{ → commands}/insert.rs
  74. +2 −2 src/engine/sql_parser/{ → commands}/select.rs
  75. +3 −33 src/engine/sql_parser/common.rs
  76. +137 −0 src/engine/sql_parser/constants.rs
  77. +48 −0 src/engine/test_objects.rs
  78. +4 −11 src/feophant.rs
  79. +3 −6 src/processor/ssl_and_gssapi_parser.rs
  80. +2 −4 src/processor/startup_parser.rs
  81. +9 −1 tests/common/mod.rs
  82. +4 −2 tests/sql_create_table.rs
  83. +11 −0 tests/sql_garbage.rs
  84. +41 −0 tests/sql_primary_key_insert.rs
  85. +1 −1 tests/sql_simple_select.rs
  86. +16 −54 tests/visibility_tests.rs
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ repository = "https://github.com/chotchki/feophant"
keywords = ["sql", "database", "feophant"]
categories = ["database-implementations"]
license = "AGPL-3.0-or-later"
version = "0.8.0"
version = "0.9.0"
edition = "2018"
exclude = [
"docs/*",
@@ -45,11 +45,13 @@ bitflags = "1.2.1"
bytes = "1"
futures = "0.3"
hex-literal = "0.3.1"
lru = "0.6.6"
nom = "6"
moka = { version = "0.6", features = ["future"] }
#nom = "7"
nom = { path = "/Users/chotchki/workspace/nom"}
nom-supreme = "0.6.0"
log = "0.4"
simplelog = "^0.10.0"
tokio = { version = "1", features = ["full"] }
tokio = { version = "^1.12", features = ["full"] }
tokio-stream = "0.1"
tokio-util = { version = "0.6.6", features = ["codec"] }
thiserror = "1.0"
136 changes: 10 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,15 +2,18 @@

A SQL database server written in Rust and inspired by PostreSQL.

Just a toy for the moment, but I'm actively working to fix that!
We now have support for persistent storage! Not crash safe but I'm getting there!

[![Latest Build][build-badge]][build-url]
[![codecov][codecov-badge]][codecov-url]
[![dependency status][dep-badge]][dep-url]

[build-badge]: https://github.com/chotchki/feophant/actions/workflows/test_source_coverage.yaml/badge.svg
[build-url]: https://github.com/chotchki/feophant/actions/workflows/test_source_coverage.yaml
[codecov-badge]: https://codecov.io/gh/chotchki/feophant/branch/main/graph/badge.svg?token=6JV9391LY0
[codecov-url]: https://codecov.io/gh/chotchki/feophant
[dep-badge]: https://deps.rs/repo/github/chotchki/feophant/status.svg
[dep-url]: https://deps.rs/repo/github/chotchki/feophant

[Website](https://feophant.com)

@@ -20,137 +23,17 @@ Launch the server
`./feophant`

Lauch a postgres client application to test
`./pgbench -i -h 127.0.0.1 -p 50000`
`./pgbench -h 127.0.0.1 -p 50000`
`./psql -h 127.0.0.1 -p 50000`

Benchmark to aid in profiling
`cargo instruments --bench feophant_benchmark -t time`

## What works user facing
You can currently start the server, connect to it and have it throw tons of errors. To support more there is a ton of infrastructure required to wire up next steps.

## Current TODO List - Subject to constant change!

**TODO**

Add support for defining a primary key on a table. This implies the following functionality:
* Index support through the stack down to the page level.
* The concept of unique indexes.
* Transactional support for indexes.
* Failure of a statement on constraint violation. Unsure if I'll end up with a general constraint system from this.

Based on reading this really means implementing Btree indexes. They don't seem to be that bad to understand/implement.

First and most important question, how should the index layers work?
Are they transactional? (I don't think so until I implement a visability map)
How should the low level layer function?
Should I have an Index config struct I pass around or just a table + columns + unique or not + type
Index Config it is

Index Manager -> for a given table
IO Manager -> Handle Page Load / Store / Update

Implemented the formats but I think I need to add locking to the I/O manager.
At a minimum I need to support a get for update, update and release lock.
I'm not sure I understand how this should work :(. I think need to commit to another layer.

Implemented stronger page checking to make sure we don't store something that won't work on the file system.

Back to indexes for now. I need to make a decision on how to handle them hitting the file system.
Postgres uses a series of OIDs to map onto disk.

I've been using uuids, I think I'm going to continue that. That would also solve the postgres fork approach.

I'll have to switch IOManager to use uuid instead of Table as a key. Upside, I'm basically already doing that. (done)

Next up implementing the index manager to add entries to the index.

I'm having a hard time figuring this out, I might work to do the operations on the tree before I keep messing with the serialization protocols. I'm just worries they are directly linked.

Got further into the index manager. Unfortunately I need a lock manager to let it even pass the smell test. Time to go on a wild goose chase again! (This project is great for someone with ADHD to have fun on!)

The lock manager design/code is done but I'm not happy with using a rwlock to protect a tag. I really want to have the lock protect the content but that needs a way for me to support writeback. I think I need to build out two more things, a WAL mechanism and a buffer manager.

I guess I need to commit to doing this for reals. However I am worried about reaching a point of partially working for a while like when I did the type fixing. We'll see how this goes.

For now, the index implementation is now on hold until I get an integrated I/O subsystem and a stubbed out WAL.

The real I/O subsystem has been written and tested. About to integrate it.
Real integration tests using a non feophant postgres rust driver are also working.

I/O subsystem integrated but I'm not happy with the performance. I'm debating a caching layer above the file_manager. I need to get some benchmarks together so I know if I'm actually helping.

**TODO**


Implement where clauses, will likely need to have to start tracing columns from analyizing through to later stages.

**TODO**

Implement support for running a fuzzer against the code base to ensure we are keeping the code at a high quality.



**TODO**

Implement delete for tuples

**TODO**

pgbench setup can run successfully, in memory

**TODO**

Ensure data about table structures is thread safe in the face of excessive Arc usage.

See where I can pass read only data by reference instead of uisng Arc everywhere

**TODO**

Support a row with more than 4kb of text in it.

**TODO**

Implement sorting.

**TODO**

Implement column aliasing

**TODO**

Implement subselect.

**TODO**

Implement Updates.

**TODO**

Did some reading on how the buffer manager works and my implementation seems to be firmly in the right direction. Take that knowledge and implement persistence

**1.0 Release Criteria**

* pgbench can run successfully
* ~~Pick a new distinct name, rename everything~~ Done
* Pick a license
* Setup fuzz testing
* Persist to disk with moderate crash safety
* Be prepared to actually use it


### Longer Term TODO

This is stuff that I should get to but aren't vital to getting to a minimal viable product.
* Right now the main function runs the server from primitives. The Tokio Tower layer will probably do it better.
* The codec that parses the network traffic is pretty naive. You could make the server allocate 2GB of data for a DDOS easily.
* * We should either add state to the codec or change how it parses to produce chunked requests. That means that when the 2GB offer is reached the server can react and terminate before we accept too much data. Its a little more nuanced than that, 2GB input might be okay but we should make decisions based on users and roles.
* There is an extension that removes the need to lock tables to repack / vaccum. Figure out how it works!
* * https://github.com/reorg/pg_repack
* Investigate if the zheap table format would be better to implement.
** Until I get past a WAL implementation and planner costs I don't think its worth it.
** Since I extended the size of transaction IDs, I probably have a larger issue on my hands than normal postgres.
*** Reading into the zheap approach I'm thinking that I might have some space saving options availible for me. In particular if a tuple is frozen so its always availible I could remove the xmin/xmax and pack more into the page. Need more thinking however my approach of questioning the storage efficency of each part of data seems to be worth it.
* Connecting unauthenticated using a postgres client/driver.
* You can create tables, insert data and query single tables.
* Data is persisted to disk, not crash safe and the on disk format is NOT stable.

## Postgres Divergance

@@ -174,7 +57,8 @@ Reasonable application error type creation: https://github.com/dtolnay/anyhow

Library Errors: https://github.com/dtolnay/thiserror

Rust's inability to treat enum variants as a type is a HUGE pain. I cheated and separated serialization from deserialization.
Rust's inability to treat enum variants as a type is a HUGE pain. I end up having an enum to hold data and another enum to validate and match the sub type. The [RFC](https://github.com/rust-lang/rfcs/pull/2593) to fix this was postponed indefinately.


## Legal Stuff (Note I'm not a lawyer!)

2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
@@ -10,4 +10,4 @@ No support is provided at this time. I am working directly off of main until I a

## Reporting a Vulnerability

Since this project is still in toy status please open an issue or pull request for any security fixes.
Since this project is still pre-alpha please open an issue or pull request for any security fixes.
78 changes: 22 additions & 56 deletions benches/feophant_benchmark.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,62 @@
use std::sync::Arc;
use std::time::Duration;

use criterion::BenchmarkId;
use criterion::Criterion;
use criterion::{criterion_group, criterion_main};

use feophantlib::constants::Nullable;
use feophantlib::engine::get_row;
use feophantlib::engine::get_table;
use feophantlib::engine::io::block_layer::file_manager2::FileManager2;
use feophantlib::engine::io::block_layer::free_space_manager::FreeSpaceManager;
use feophantlib::engine::io::row_formats::RowData;
use feophantlib::engine::io::FileManager;
use feophantlib::engine::io::RowManager;
use feophantlib::engine::objects::types::BaseSqlTypes;
use feophantlib::engine::objects::types::BaseSqlTypesMapper;
use feophantlib::engine::objects::Attribute;
use feophantlib::engine::objects::SqlTuple;
use feophantlib::engine::objects::Table;
use feophantlib::engine::transactions::TransactionId;
use futures::pin_mut;
use std::sync::Arc;
use tempfile::TempDir;
use tokio::runtime::Builder;
use tokio_stream::StreamExt;

fn get_table() -> Arc<Table> {
Arc::new(Table::new(
uuid::Uuid::new_v4(),
"test_table".to_string(),
vec![
Attribute::new(
"header".to_string(),
BaseSqlTypesMapper::Text,
Nullable::NotNull,
None,
),
Attribute::new(
"id".to_string(),
BaseSqlTypesMapper::Uuid,
Nullable::Null,
None,
),
Attribute::new(
"header3".to_string(),
BaseSqlTypesMapper::Text,
Nullable::NotNull,
None,
),
],
))
}

fn get_row(input: String) -> SqlTuple {
SqlTuple(vec![
Some(BaseSqlTypes::Text(input)),
None,
Some(BaseSqlTypes::Text("blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah".to_string())),
])
}

// Here we have an async function to benchmark
async fn row_manager_mass_insert(row_count: usize) -> Result<(), Box<dyn std::error::Error>> {
let tmp = TempDir::new()?;
let tmp_dir = tmp.path().as_os_str().to_os_string();

let table = get_table();
let fm = Arc::new(FileManager::new(tmp_dir.clone())?);
let rm = RowManager::new(fm);
let fm = Arc::new(FileManager2::new(tmp_dir.clone())?);
let fsm = FreeSpaceManager::new(fm.clone());
let rm = RowManager::new(fm, fsm);

let tran_id = TransactionId::new(1);

for i in 0..row_count {
rm.clone()
.insert_row(tran_id, table.clone(), get_row(i.to_string()))
.insert_row(tran_id, &table, get_row(i.to_string()))
.await?;
}

drop(rm);

//Now let's make sure they're really in the table, persisting across restarts
let fm = Arc::new(FileManager::new(tmp_dir)?);
let rm = RowManager::new(fm);
let fm = Arc::new(FileManager2::new(tmp_dir.clone())?);
let fsm = FreeSpaceManager::new(fm.clone());
let rm = RowManager::new(fm, fsm);

pin_mut!(rm);
let result_rows: Vec<RowData> = rm
.clone()
.get_stream(table.clone())
.get_stream(&table)
.map(Result::unwrap)
.collect()
.await;

assert_eq!(result_rows.len(), row_count);
for i in 0..row_count {
let sample_row = get_row(i.to_string());
assert_eq!(result_rows[i].user_data, sample_row);
}
result_rows
.iter()
.enumerate()
.take(row_count)
.map(|(i, row)| {
let sample_row = get_row(i.to_string());
assert_eq!(row.user_data, sample_row);
})
.for_each(drop);

Ok(())
}
2 changes: 1 addition & 1 deletion docs/_config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
theme: jekyll-theme-minimal
title: FeOphant
description: A database server written in Rust and inspired by PostreSQL
logo: /feophant_logo.svg
logo: /feophant_logo_v2.svg
show_downloads: false
google_analytics: G-GBPHN9NF6R
51 changes: 51 additions & 0 deletions docs/feophant_logo_v2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading