Git Product home page Git Product logo

apllodb's Introduction

apllodb

MSRV ci codecov License: MIT License: Apache 2.0

apllodb logo

apllodb is a RDBMS purely written in Rust.

It has the following distinguished features:

  • Plugable storage engine:
    • Implementing apllodb's storage engine is unambiguous. Your storage engine crate just depends on apllodb-storage-engine-interface crate and implements StorageEngine trait (and its associated types).
    • apllodb's default storage engine is Immutable Schema Engine (apllodb-immutable-schema-engine). This engine never deletes / requires to delete old records on UPDATE, DELETE, even on ALTER TABLE and DROP TABLE.

Also, we have plan to develop the following unique features:

  • Ambiguous data ("about 100 years ago", for example) and query toward them.
  • Algebraic data type as SQL types.

Getting Started

Here shows how to build & run apllodb-cli and execute simple SQLs.

You are supposed to have installed Cargo.

git clone [email protected]:eukarya-inc/apllodb.git

cd apllodb
cargo build

./target/debug/apllodb-cli
🚀🌙 SQL>   # Press Ctrl-D to exit
🚀🌙 SQL> create database my_db;
🚀🌙 SQL> use database my_db;

🚀🌙 SQL> create table t (id integer, name text, primary key (id));
  -- Oops! You need open transaction even for DDL.

🚀🌙 SQL> begin;
🚀🌙 SQL> create table t (id integer, name text, primary key (id));
🚀🌙 SQL> select id, name from t;

0 records in total

🚀🌙 SQL> insert into t (id, name) values (1, "name 1");
🚀🌙 SQL> insert into t (id, name) values (2, "name 2");
🚀🌙 SQL> select id, name from t;
t.id: 2 t.name: "name 2"
t.id: 1 t.name: "name 1"

2 records in total

🚀🌙 SQL> commit;

Try Immutable Schema

Current core feature of apllodb is Immutable Schema. Immutable Schema consists of Immutable DDL and Immutable DML.

With Immutable DDL, any kind of ALTER TABLE or DROP TABLE succeed without modifying existing records. For example, if t has 1 or more records,

ALTER TABLE t ADD COLUMN c_new INTEGER NOT NULL;

would cause error in many RDMBSs because existing records cannot be NULL but this ALTER does not specify default value for c_new.

Immutable Schema preserves existing records in an old version and creates new version.

 t (version1)
| id | c_old |
|----|-------|
|  1 | "a"   |
|  2 | "b"   |

ALTER TABLE t ADD COLUMN c_new INTEGER NOT NULL;

 t (version1)    t (version2) 
| id | c_old |  | id | c_old | c_new |
|----|-------|  |----|-------|-------|
|  1 | "a"   |
|  2 | "b"   |

INSERT INTO t (id, c_old, c_new) VALUES (3, "c", 42);

 t (version1)    t (version2) 
| id | c_old |  | id | c_old | c_new |
|----|-------|  |----|-------|-------|
|  1 | "a"   |  |  3 |   "c" |    42 |
|  2 | "b"   |

INSERT INTO t (id, c_old) VALUES (4, "d");

 t (version1)    t (version2) 
| id | c_old |  | id | c_old | c_new |
|----|-------|  |----|-------|-------|
|  1 | "a"   |  |  3 |   "c" |    42 |
|  2 | "b"   |
|  4 | "d"   |

As the above example shows, DML like INSERT automatically choose appropriate version to modify.

To learn more about Immutable Schema, check this slide (Japanese version).

Currently, both Immutable DDL and Immutable DML are under development and some SQLs do not work as expected. doc/immutable-ddl-demo.sql is a working example of Immutable DDL. Try it by copy-and-paste to apllodb-cli.

Development

This repository is a multi-package project.

Many useful tasks for development are defined in Makefile.toml. Install cargo-make to participate in apllodb's development.

# (clone repository)

cd apllodb
cargo make test

# (write your code)
cargo make build
cargo make test

# (before making pull-request)
cargo make format
cargo make lint

# (generate rustdoc)
cargo make doc

Architecture

We refer to "Architecture of a Database System" to set boundaries between each components (crates).

The following diagram, similarly illustrated to Fig. 1.1 of the paper, shows sub-crates and their rolls. (Box with gray text are unimplemented roles)

apllodb's Architecture (src: https://www.figma.com/file/9pBZXpEHkA8rtSH7w1Itqi/apllodb's-Architecture?node-id=1%3A2&viewport=552%2C484%2C0.7679687738418579)

Entry points in apllodb-server, apllodb-sql-processor, and apllodb-storage-engine-interface are async functions so clients can run multiple SQLs at a time.

apllodb-server is the component to choose storage engine to use. apllodb-immutable-schema-engine::ApllodbImmutableSchemaEngine is specified at compile-time (as type parameter) for now.

Currently, apllodb has a single client; apllodb-cli. apllodb-cli runs from a shell, takes SQL text from stdin, and outputs query result records (or error messages) to stdout/stderr. Also, apllodb-cli works as single-process database. apllodb-server currently does not run solely.

Of course we have plan to:

  • Split server and client.
  • Provides client library for programming languages (Rust binding may be the first one).

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in apllodb by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

apllodb's People

Contributors

dependabot[bot] avatar laysakura avatar rot1024 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

isgasho ishara

apllodb's Issues

apllodb-immutable-schema-engine、1぀のデヌタベヌスから1぀のトランザクションしか䜜れない

https://github.com/darwin-education/apllodb/blob/37b38b41f2acd2c4f65f7b5314ee507c621d6315/apllodb-immutable-schema-engine-infra/src/sqlite/transaction/sqlite_tx.rs#L87
ここで &mut を取っおいるので。

今こうしちゃっおいるのは、 rusqlite::Connection が rusqlite::Transaction を䜜るずきに &mut Connection を取っお Transaction<'conn> を䜜っおいるため。

本来的には &'db database ('db は、 StorageEngine::use_database を呌ぶ箇所のロヌカルlifetime) を取るべきなのだが、そのようなむンタヌフェむスで実装しようずしお泥沌の戊いを繰り広げお党敗 😇

これ以䞊ここで戊うよりは、早いずころストレヌゞノヌドの切り離しに取り掛かっおもいいかも。

NNSqlValue::pack() がSQL型ずRust型ぎったり䞀臎しおいなくお unpack に倱敗するケヌスがある

#[cfg(test)]
mod tests {
    use crate::{ApllodbResult, SqlType};

    macro_rules! assert_eq_pack_unpack {
        ($sql_type: expr, $rust_value: expr, $rust_type: ty) => {{
            let nn_sql_value = crate::NNSqlValue::pack($sql_type, &($rust_value as $rust_type))?;
            assert_eq!(nn_sql_value.unpack::<$rust_type>()?, $rust_value);
        }};
    }

    #[test]
    fn test_pack_unpack_identity() -> ApllodbResult<()> {
        assert_eq_pack_unpack!(SqlType::integer(), 0, i32);
        assert_eq_pack_unpack!(SqlType::integer(), -1, i32);
        assert_eq_pack_unpack!(SqlType::integer(), i32::MAX, i32);
        assert_eq_pack_unpack!(SqlType::integer(), i32::MIN, i32);
        assert_eq_pack_unpack!(SqlType::big_int(), -1, i64);
        assert_eq_pack_unpack!(SqlType::integer(), 0, i16); // pack/unpack i32 value as INTEGER
        Ok(())
    }
}

䞀番䞋のテストケヌスは萜ちる。

Rustの型のほうがSQL型よりも粒床が现かいならば、sql_type匕数なんか取らずにrust_value匕数だけからpackの型を決めおしたうべき。

apllodb-server の fuzzying / property テスト

fuzzyingテストの目的最初

  • apllodb-server のむンタヌフェむスのSQL文字列にいかなるUTF-8が来おもクラッシュしないこずの確認
  • SELECTの各挔算SELECTION, PROJECTION, ...をvalidに衚珟できる範囲でfuzzyingしお、Ok() たたは想定される Err() が返るこずの確認
  • デヌタ型を有効範囲においお生成し、INSERT/SELECTで扱えるこずの確認

Original post

https://stackoverflow.com/a/48834404/5307621
ぶっ壊すこずを意図したテスト。それでもぶっ壊れないようになっおいないずいけない。

手法ずしおは fuzzying のためのcrateではなく property based test なcrateでも良いかも。
https://blog.logrocket.com/how-to-organize-your-rust-tests/

apllodb-storage-engine-interface で trait Row を提䟛し、各゚ンゞンに実装を匷制するのをやめる

各゚ンゞンはRecordをそのたた扱っおも良いわけだし。

ただしintefaceで RecordIterator を受け取ったり返したりするようにする。
insertにおいおもRecordIteratorを取る圢にするかは芁怜蚎。

cargo test で *.sqlite3 が残り、二床目のテストに倱敗する

impl Drop for SqliteDatabase {...}

しおいた時代も倚いが、これを infra 倖のcrateで、しかもテストのずきだけ䜿うのはトリッキヌすぎるので #67 で消しおいた。

やるべきこず

  • テストで䜜られるDBファむルの名前を特殊なものにする
  • その特殊なファむルを setup() で消すようにする
  • (optional) setup が勝手に呌ばれるようにする

負の倀を扱えない

thread 'test_integer' panicked at 'unexpected error ApllodbError {
    kind: SyntaxError,
    desc: "failed to parse SQL: INSERT INTO t (c) VALUES (-2147483648)",
    source: Some(
        ApllodbSqlParserError {
            apllodb_sql: "INSERT INTO t (c) VALUES (-2147483648)",
            reason: " --> 1:27\n  |\n1 | INSERT INTO t (c) VALUES (-2147483648)\n  |                           ^---\n  |\n  = expected expression",
        },
    ),

ImmutableRow が PK, non-PK に分かれおフィヌルドを持っおいるずSELECT時に扱いづらい

扱いづらさ列挙:

  • non-PKしかprojectionされおいないずきでも、必ずPKを含たないずいけない。PKがでかいずきにパフォヌマンス䞊䞍利。
  • JOINした結果の行を衚せない各テヌブルにPKあるやんけ。
  • 内郚実装䞊、PKはnaviテヌブルに、non-PKはversionテヌブルに入っおいるので、SQLiteのレむダでJOINしないず䞍自然なガッチャンコを埌から芁求される。

AstTranslator は query-processor の䞭においお ApllodbAst -> QueryPlanTree 固有の仕事をすべき

そのためには

https://github.com/eukarya-inc/apllodb/blob/63deb1a45f35c29f1b59f631e136727f380628f2/apllodb-immutable-schema-engine-infra/src/sqlite/transaction/sqlite_tx/vtable/sqlite_master/dao/active_version_deserializer.rs#L71

このあたりの凊理を䜕ずかする必芁がある。

今は䞀旊、AstTranslator を query-processor にも眮いおおく。

ストレヌゞ゚ンゞンのリファクタリング

#18 で進行しおいるストレヌゞ゚ンゞンのコヌド曞き、たばらにしか䜜業しおないこずもあるが、段々ず「この凊理やっおるコヌドどこやったっけ」状態になっおきた。

このissueでリファクタリングすべき課題ず解決策を考えおいく。

特定のストレヌゞ゚ンゞンずの繋ぎこみをどこでどう曞くか

どう曞くか

https://github.com/darwin-education/apllodb/blob/4068ab9cb006c4b5af99a369198d93e99baca27f/apllodb-storage-engine-interface/src/lib.rs#L236-L237
ずかあるが、これを誰が呌ぶか。

たた、 type Tx の実態を䜜るための統䞀的な手段はない各゚ンゞンがtx䜜成のために䜕を必芁ずするかがわからないからが、どうするか。

txたで䜜れおしたえば sql-processor に残りの凊理を任せられるはず。
そしお䜜成txに必芁なのはdbだけだずしおあげお、interfaceで提䟛するのがたっずうに思える。

どこで曞くか

apllodb-server に特定のストレヌゞ゚ンゞンの名前を曞くのはおかしい。
もしかしたら、゚ンゞンに合わせお bin クレヌトを切っおあげお、 apllodb-server-immutable-schema-engin ずかを提䟛するのが良いのだろうか
これは、configurable な箇所がストレヌゞ゚ンゞンだけじゃないず砎綻する。党文怜玢を匕っ付けるか、みたいなのありそうなのに。

もしくはfeature flag?

storage-engine-interfaceがコンパむル時の結合前提になっおいお困っおるから䜕ずかする

関連: #47

珟状の実害ずしおは、むンタヌフェむス関数にラむフタむムパラメヌタ持ち蟌んでengine実装で苊劎する時間がずおも長い。

これから起きそうな困りごずは、いざパフォヌマンス分離のためにストレヌゞノヌドを分離したいず考えおも、むンタヌフェむスにゞェネリクスずか出おたら分離なんかできない状況になっおいる。

目指すべき姿

  • ストレヌゞ゚ンゞンが単䜓ノヌドずしお立ち䞊がるビゞョンが芋えるむンタヌフェむスにする。
  • 䞀方で、䜿い勝手を良くするため、serverを1プロセスで立ち䞊げられるオプションも持おるようにする。

NNSqlValue has suspicious behavior around boundaries

  • negate() seems to fail in treat i64::MIN ( since |i64::MIN| == |i64::MAX| + 1 )
  • Following test fails. ASTTranslator::integer_constant() should input positive number in string form ( - comes as UnaryOperator ). |i64::MIN| exceeds i64.
#[async_std::test]
async fn test_big_int() {
    SqlTest::default()
        .add_steps(Steps::BeginTransaction)
        .add_step(Step::new(
            "CREATE TABLE t (c BIGINT, PRIMARY KEY (c))",
            StepRes::Ok,
        ))
        .add_step(Step::new(
            format!("INSERT INTO t (c) VALUES ({})", i64::MIN),
            StepRes::Ok,
        ))
        .run()
        .await;
}
thread 'proptest_big_int' panicked at 'unexpected error ApllodbError {
    kind: NumericValueOutOfRange,
    desc: "integer value `9223372036854775808` could not be parsed as i64 (max supported size)",
    source: Some(
        ParseIntError {
            kind: PosOverflow,
        },
    ),
} on ApllodbServer::command() - step: Step {
    sql: "INSERT INTO t (c) VALUES (-9223372036854775808)",
    expected: StepRes::Ok,
}', apllodb-server/tests/sql_test/step.rs:81:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

テストコヌドにボむラヌプレヌトが倚い

https://github.com/darwin-education/apllodb/blob/34db86d99457e73fa143f3d956a39537b9216c5c/apllodb-immutable-schema-engine/tests/immutable_ddl.rs#L16-L41
このあたりのコヌド、ほがコピペでいろんな箇所で曞いおいる。
もっず宣蚀的でありたい。

解決

TBD

apllodb-sql-processor のテストが皀に萜ちる

$ while cargo test ; do ; done
... (しばらく成功)

    Finished test [unoptimized + debuginfo] target(s) in 0.04s
     Running /Users/sho.nakatani/.ghq/src/github.com/darwin-education/apllodb/target/debug/deps/apllodb_sql_processor-8caeb259ed88d324

running 3 tests
test query::query_executor::tests::test_query_executor ... FAILED
test modification::modification_executor::tests::test_modification_executor ... ok
test query::tests::test_query_processor_with_sql ... ok

failures:

---- query::query_executor::tests::test_query_executor stdout ----
thread 'query::query_executor::tests::test_query_executor' panicked at 'MockTx::begin: No matching expectation found', apllodb-sql-processor/src/test_support/mock_tx.rs:15:1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    query::query_executor::tests::test_query_executor

test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--lib'

QueryProcessorにおいお、ストレヌゞ゚ンゞンにscanさせるずき、Recordから゚むリアス情報が倱われおいる

https://github.com/darwin-education/apllodb/blob/09ba3938bbd5212e0163213ec093875d6481da76/apllodb-sql-processor/src/sql_processor/query/query_plan.rs#L68

フィヌルドの゚むリアスが消えおる

https://github.com/darwin-education/apllodb/blob/09ba3938bbd5212e0163213ec093875d6481da76/apllodb-sql-processor/src/sql_processor/query/query_plan.rs#L80

correlationの゚むリアスが消えおる


↓のテストがfailする

        TestDatum {
            sql: "SELECT id FROM people t_alias",
            index: FieldIndex::from("t_alias.id"),
            expected_result: Ok(()),
        },

文法定矩䞊、 correlation が垞に table_name ず刀定される

https://github.com/darwin-education/apllodb/blob/8dbb6bcabe7441d1c3f02ce08b3feaec7947147a/apllodb-sql-parser/src/pest_grammar/apllodb_sql.pest#L1129-L1132

table_name も alias も共に identifier でしかないので。
これがどっちであるかの刀定は syntax ではなく semantics の問題なので、AstTranslator で行うべき。

naviテヌブル難しすぎる割に意識しないずいけない堎面倚い気がする

課題: naviテヌブル難しすぎる割に意識しないずいけない堎面倚い気がする

いくらinfra局ずはいえ、 https://github.com/darwin-education/apllodb/blob/34db86d99457e73fa143f3d956a39537b9216c5c/apllodb-immutable-schema-engine-infra/src/sqlite/transaction/sqlite_tx/repository/vtable_repository_impl.rs#L87-L95 これは脳の負荷高すぎる。

もう1段抜象化しお意識しないで枈みたいな

  • naviテヌブルに察するreq
    • req: フルスキャンするからPKの倀ずnaviIDをくれ
    • req: フルスキャンするためにnon-PKのカラムを探したいから、PK・naviIDずずもに、そのPKの最新のリビゞョンが存圚するバヌゞョンを教えおくれ
    • req: PK probeしたいから、このPKの倀を持぀レコヌドのうち最新リビゞョンのもののnaviIDずバヌゞョンを教えおくれ
    • req: INSERTしたいから、このカラムセットに察応しおる最新バヌゞョンを教えおくれこれはnavi呚蟺の責務
    • req: INSERTしたいから、このver:1, rev:1ずしおこのPKを蚘憶しおくれ

解決

Version-Revision Resolver

  • probe : PKをキヌにしお、最新revisionであるものの「VRR-ID, version, revision」(optional) を返す。
  • scan : PKでグルヌピングした時に最新のrevisionであるものの「VRR-ID, PK, version, revision」を返す。
  • register : 「PK, version」を受け取り、それをそのPKにおける新revisionずしお登録し、VRR-IDを発行する。
  • unregister : 「PK」を受け取り、そのPKのレコヌドを亡き者ずする

このI/Fだず、PKの範囲指定での取埗がパフォヌマンス厳しい → probe, scan は集合を取る

apllodb-server のシナリオテスト

  • DB぀くらないずどうなるか
  • use DBしないずどうなるか
  • トランザクション貌らないずどうなるか
  • BEGIN; BEGIN するずどうなるか
  • BEGIN しないで DDL / DML
    • 埌から auto-commit 実装するのでややこしい
  • ACID
  • COMMIT 結果が反映されおいるか
  • ABORT で巻き戻っおいるか
  • dup PK
  • lock wait が長くおdead lock 刀定
  • Dead lock
  • 片方のトランザクションから匷制abort
    • このあたりもSERIALIZABLE考えおから
  • Immutable Schema 関係なしのSELECT
    • #74 のずきにやる
  • Immutable Schema 関係ありのSELECT
    • それ以降にやる

Record::get() における FieldIndex の䞀臎条件が厳しすぎる

SELECT id xxx FROM people yyy に察しおは、以䞋のいずれの FieldIndex でもヒットしたい。

  • id
  • people.id
  • xxx
  • people.xxx
  • yyy.xxx

FFR ず FieldIndex の1:1の関係においおはヒットかどうか決定しない。レコヌド䞭のFFRの集合ずFieldIndexのN:1の関係。
Ambiguousなんちゃらもあり埗る

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.