Skip to content

Releases: gluesql/gluesql

v0.16.2

27 Aug 11:53
a9cbffb
Compare
Choose a tag to compare

Changes

  • Prepare release v0.16.2 @github-actions (#1566)
  • Update chrono version to 0.4.38 @panarch (#1565)

v0.16.1

25 Aug 08:50
12a0e2b
Compare
Choose a tag to compare

Changes

  • Prepare release v0.16.1 @github-actions (#1563)
  • Fix empty commit, Add command validation on GitStorage @devgony (#1550)
  • Update file based storage to take AsRef<Path> for init @panarch (#1558)
  • Add GitStorage to GlueSQL Rust package @panarch (#1548)
  • Fix GitStorage pull_and_push test not to fail if .tmp/ not exists @panarch (#1546)
  • Fix drop_table to return early if schema not found with IF EXISTS @devgony (#1552)

πŸ› Bug Fixes

  • Fix publish-rust.yml gh action to use token correctly @panarch (#1564)
  • Fix GitStorage GitHub Action to run in forks @panarch (#1557)
  • Fix GitStorage gh-action env uses @panarch (#1556)
  • Fix publish-rust.yml GitHub Action - make publish sequential @panarch (#1549)

v0.16.0 🌈

11 Aug 12:04
a291142
Compare
Choose a tag to compare

πŸš€ Features

Changes

πŸ› Bug Fixes

  • Fix panic in SledStorage tx_timeout calculation by re-arranging terms @JakkuSakura (#1504)

v0.15.0 🌈

18 Nov 08:02
fdb01e3
Compare
Choose a tag to compare

🌊 Breaking Changes

πŸ€ Python Support

Code Samples

from gluesql import Glue, MemoryStorage
from tabulate import tabulate

db = Glue(MemoryStorage())

sql = """
    SELECT
    u.name as user,
    d.name as device
    FROM User u
    JOIN Device d ON u.id = d.userId
""".strip().replace(
    "    ", ""
)

result = db.query(sql)
rows = result[0].get("rows")
print(f"\n[Query]\n{sql}")
print(tabulate(rows, headers="keys", showindex=True, tablefmt="simple_outline"))

πŸ€ Redis Storage

πŸ€ CSV Storage

πŸ€ More operators and functions

πŸš€ Features

  • feat: implement select iterator utility function @ever0de (#1429)

🌟 Improvements

Read more

v0.14.0 🌈

27 May 09:26
43cfd3b
Compare
Choose a tag to compare

We now provide an official documentation website at https://gluesql.org/docs

πŸš€ Features

πŸ€ Schemaless data support

GlueSQL now supports creating tables without a schema, allowing for both structured and unstructured data to be stored in the same table.
To create a schemaless table, simply run CREATE TABLE without specifying any columns. For more information on querying schemaless data, please refer to the following link: querying schemaless data

CREATE TABLE Bar;

To insert values,

INSERT INTO Bar VALUES
    ('{ "name": "ast", "value": 30 }'),
    ('{ "name": "glue", "rate": 3.0, "list": [1, 2, 3] }'),

Then, selecting values from schemaless table is simple.

SELECT name, rate, list[0] FROM Bar WHERE name = 'glue';

e.g.

CREATE TABLE Names (id INTEGER, name TEXT);
INSERT INTO Names VALUES (1, 'glue'), (2, 'sql');

CREATE TABLE Logs;
INSERT INTO Logs VALUES
    ('{ "id": 1, "value": 30 }'),
    ('{ "id": 2, "rate": 3.0, "list": [1, 2, 3] }'),
    ('{ "id": 3, "rate": 5.0, "value": 100 }');

SELECT * FROM Names JOIN Logs ON Names.id = Logs.id;
/*
| id | list    | name | rate | value |
|----|---------|------|------|-------|
| 1  |         | glue |      | 30    |
| 2  |[1, 2, 3]| sql  | 3    |       |
*/

πŸ€ IndexedDB & WebStorage supports in JavaScript package

GlueSQL supports handling in-memory, localStorage, sessionStorage, and even IndexedDB using the same SQL syntax. All you need to know is how to specify the ENGINE when creating a table.

e.g.

CREATE TABLE Mem (mid INTEGER) ENGINE = memory;
CREATE TABLE Loc (lid INTEGER) ENGINE = localStorage;
CREATE TABLE Ses (sid INTEGER) ENGINE = sessionStorage;
CREATE TABLE Idb (iid INTEGER) ENGINE = indexedDB;

SELECT
    mid, lid, sid, iid 
FROM Mem
JOIN Loc
JOIN Ses
JOIN Idb;

πŸ€ Data Types - UINT32, UINT64, UINT128, POINT and FLOAT32

πŸ€ Functions - APPEND, PREPEND, RAND, FIND_IDX, INITCAP and CALC_DISTANCE

πŸ€ Store traits

User-level custom function

By implementing both the CustomFunction and CustomFunctionMut traits, users can create, use, and delete user-level custom functions. Although GlueSQL plans to continuously add various functions, users may still find them insufficient. In such cases, users can create their own user-level custom functions to supplement the built-in functions. Additionally, if there are repetitive business logic codes, they can be stored as custom functions.
e.g.

CREATE FUNCTION ADD_ONE (n INT, x INT DEFAULT 1) RETURN n + x;

SELECT ADD_ONE(10) AS test;

DROP FUNCTION ADD_ONE;

Metadata

The Metadata trait is an optional implementation for providing additional metadata support in GlueSQL. GlueSQL does not enforce any specific metadata implementation, allowing custom storage developers to decide which type of metadata, such as create time, modify time, etc., they want to provide.

πŸ€ Storages

JSON Storage

Composite Storage

  • Add CompositeStorage which bundles multiple storages @panarch (#1068)

IndexedDB Storage

Web Storage

  • Add WebStorage - support localStorage & sessionStorage for web browsers @panarch (#1050)

πŸ€ Other new features

🌊 Interface Changes

  • Remove Store trait related cfg features, @panarch (#1091)
  • Refactor CreateTable.columns from Vec<ColumnDef> to Option<Vec<ColumnDef>> @devgony (#1086)
  • Remove MutResult @panarch (#1073)
  • Update all store mut trait methods to take &mut self @panarch (#1072)
  • Change StoreMut interface to use &mut self, not to take ownership @panarch (#1071)
  • Modify default ColumnOption from NOT NULL to NULL @devgony (#997)

🌟 Improvements

Read more

v0.13.1

08 Nov 08:19
af908dc
Compare
Choose a tag to compare

🌟 CLI - Data migration support

Dump whole schemas and data by generating SQL using --dump {PATH} option

$ gluesql --path ~/glue_data --dump ./dump.sql
-- dump.sql
CREATE TABLE Item (id INT, name TEXT);
CREATE INDEX item_id ON Item (id);
..
INSERT INTO Item VALUES (1, 'Foo'), (2, 'Bar') ..
..

Import database

$ gluesql --path ~/new_data --execute ./dump.sql

What's Changed

  • Support the way to migrate whole databse with --dump {PATH} argument (+to_ddl()) by @devgony in #977
  • Replace double quote to single quote by @devgony in #988
  • Replace TryFrom for AstLiteral => TryFrom for Expr, add more test to dump by @devgony in #990
  • Bump cli, core, pkg/rust and test-suite versions to v0.13.1 by @panarch in #991

Full Changelog: v0.13.0...v0.13.1

v0.13.0 🌈

19 Oct 04:31
Compare
Choose a tag to compare

🌊 Breaking Changes

🌟 AST Builder

AST Builder is now ready to be used!
GlueSQL AST builder provides iterator chaining experience to manipulate data which is similar to array chaining methods or DataFrame syntax.
For someone who is already familiar with SQL, then there would be almost no extra learning cost to use GlueSQL AST builder.
AST builder accepts various sets of params - not only the expression built by its own expr builder, but also it even accepts raw SQL text and prebuilt ASTs.

e.g.

table("Item")
    .select()
    .join("Category")
    .on(col("Category.id").eq("Item.category_id"))
    .group_by("Item.category_id")
    .having("SUM(Item.price) > 80")
    .project("Category.name AS category")
    .project("SUM(Item.price) AS sum_price")
    .execute(glue)
    .await;
category sum_price
Meat 90
Drink 85

Usage code examples

SELECT queries
INSERT queries
UPDATE queries
DELETE queries

Related PRs (features)

Related PRs (improvements)

  • Add AST builder integration tests of SELECT, UPDATE, INSERT and DELET… @panarch (#955)
  • Update AST builder cast function unit test @zmrdltl (#957)
  • Expose AST builder unary_op methods to public, @panarch (#956)
  • Rename AST builder ExprNode::not to ExprNode::negate @sa1 (#953)
  • Add missing select nodes to ExprNode::InList and QueryNode in AST builder @panarch (#934)
  • Simplify ast_builder/ QueryNode codes using decl macro @panarch (#932)
  • Add from ProjectNode & QueryNode for InListNode in AST builder, @panarch (#925)
  • Update ast-builder function expr params to use Into<..Node> @panarch (#926)
  • Update AST builder between & hash_executor to accept different param … @panarch (#923)
  • Add ExprNode::subquery, @panarch (#922)
  • Add AST builder join nodes to query node conversion support @panarch (#921)
  • Add setting table_alias support to AST builder table init function @panarch (#920)
  • [AST Builder] Combine in_list and in_subquery into in_list @CEOJINSUNG (#808)
  • [AST-Builder] change error message in test functions @ding-young (#800)
  • Reformat : change ast builder function format @seonghun-dev (#796)

πŸš€ Features

πŸ“š New metadata tables - GLUE_TABLES, GLUE_TABLE_COLUMNS and GLUE_INDEXES

gluesql> SELECT * FROM GLUE_TABLES;
TABLE_NAME
Bar
Foo
gluesql> SELECT * FROM GLUE_TABLE_COLUMNS;
TABLE_NAME COLUMN_NAME COLUMN_ID
Bar id 1
Bar name 2
Bar type 3
Foo id 1
Foo name 2
gluesql> SELECT * FROM GLUE_INDEXES;
TABLE_NAME INDEX_NAME ORDER EXPRESSION UNIQUENESS
Foo PRIMARY BOTH id TRUE
Foo Foo_id_1 BOTH id + 1 FALSE
Foo Foo_name_concat BOTH name + "_" FALSE
  • Add support GLUE_INDEXES reserved table which provides all index info @devgony (#935)
  • Support Dictionary(Schema) view @devgony (#869)

🧭 ORDER BY enhancements

Support ORDER BY ALIAS clause like below

SELECT column_name AS alias_name FROM Table ORDER BY alias_name DESC
  • Currently, it throws [error] value not found: alias_name

Original column_name is still available at ORDER BY clause though SELECT clause uses alias_name

SELECT column_name AS alias_name FROM Table ORDER BY column_name DESC

Support ORDER BY COLUMN_INDEX

SELECT alpha, beta FROM Table ORDER BY 1 DESC
  • 1 means the column_index which is first column alpha

Support ORDER BY clause in VALUES list

gluesql> VALUES (1, 'a'), (2, 'b') ORDER BY column1 DESC;
 column1 | column2
---------+---------
       2 | b
       1 | a

Related PRs

πŸ“‹ ToSql trait for AST which provides AST to SQL text conversion for easier debugging

e.g.
ToSql::to_sql from the below AST returns this simple SQL text.

  • Generated SQL text
CREATE TABLE Foo (id INT, num INT NULL, name TEXT);
  • Input AST
Statement::CreateTable {
    if_not_exists: false,
    name: "Foo".into(),
    columns: vec![
        ColumnDef {
            name: "id".to_owned(),
            data_type: DataType::Int,
            options: vec![]
        },
        ColumnDef {
            name: "num".to_owned(),
            data_type: DataType::Int,
            options: vec![ColumnOptionDef {
                name: None,
                option: ColumnOption::Null
            }]
        },
        ColumnDef {
            name: "name".to_owned(),
            data_type: DataType::Text,
            options: vec![]
        }
    ],
    source: None
}
.to_sql()

Related PRs

🌳 New datatype and functions

New datatype - UINT8

New functions - ASCII, CHR, POSITION, TO_DATE, TO_TIMESTAMP and FORMAT

πŸ“ˆ CLI enhancements

Support .edit {fileName|None} in CLI @devgony (#871)

  1. Open temporary editor with last SQL
$> cargo run
gluesql> .run
[error] Nothing in SQL history to run.
gluesql> SELECT 1, 'a', true
1 'a' true
1 a TRUE
gluesql> .edit

=> open Editor with last command on temporary file like /tmp/Glue_****.sql

-- modify in editor
SELECT 1, 'a', true, 2, 'b'

If you want to fix editor type, run below command on OS

# (optional)
$> export EDITOR=vi
gluesql> .run
1 'a' true 2 'b'
1 a TRUE 2 b
  1. Open editor with physical file
gluesql> .edit foo.sql
-- modify in editor
SELECT 1 AS no, 'In physical file' AS name
gluesql> .execute foo.sql
no name
1 In physical file

New CLI print options

gluesql> .set tabular OFF
gluesql> .set colsep ,
gluesql> .set colwrap '
gluesql> .set heading OFF
gluesql> VALUES (1, 'a', true), (2, 'b', false)
'1','a','true'
'2','b','false'

Change default print style to markdown

Set markdown as default print style like below

gluesql> SELECT * FROM (VALUES (1, 'a', true), (2, 'b', false)) AS Sub;
column1 column2 column3
1 a TRUE
2 b FALSE
(pasted from gluesql directly)

πŸ’‘ Improvements

Aggregation

sqlparser-rs upgrades

Tests

  • [FIx] add omitted uint8 integration test @ChobobDev (#951)
  • Rename showcolumns to show_columns @sa1 (#936)
  • Replace plan/join.rs unit tests to use AST builder! @panarch (#929)
  • Update test-suite...
Read more

v0.12.0 🌈

22 Aug 15:07
0c703c7
Compare
Choose a tag to compare

🌊 Breaking Changes

⚑ Store trait changes

  1. Store traits no longer require generic T
// v0.11
pub trait Store<T: Debug> { .. }
pub trait StoreMut<T: Debug> where Self: Sized { .. }
pub trait Index<T: Debug> { .. }
pub trait IndexMut<T: Debug> where Self: Sized { .. }

// v0.12
pub trait Store { .. }
pub trait StoreMut where Self: Sized { .. }
pub trait Index { .. }
pub trait IndexMut where Self: Sized { .. }

Related PRs

  • Remove generic T from Store, StoreMut and Index traits, @panarch (#589)
  • Replace SledStorage generic key T from IVec to data::Key @panarch (#588)
  • Replace MemoryStorage Key to core::data::Key, @panarch (#577)
  1. Store::fetch_data is newly added, Store trait now requires three methods to implement
pub trait Store {
    async fn fetch_schema(&self, table_name: &str) -> Result<Option<Schema>>;
    async fn fetch_data(&self, table_name: &str, key: &Key) -> Result<Option<Row>>;
    async fn scan_data(&self, table_name: &str) -> Result<RowIter>;
}

Related PR

  1. StoreMut trait method renamings - insert_data -> append_data and update_data -> insert_data
pub trait StoreMut where Self: Sized {
    ...
    async fn append_data(..) -> ..;
    async fn insert_data(..) -> ..;
}

Related PR

  • Rename StoreMut insert_data & update_data methods, @panarch (#774)

🌐 PRIMARY KEY support

GlueSQL now supports PRIMARY KEY!

CREATE TABLE Allegro (
    id INTEGER PRIMARY KEY,
    name TEXT,
);

more info - test-suite/primary_key

  • Implement primary key support, @panarch (#687)
  • Update Expr::CompoundIdentifier to have more accurate data format @devgony (#770)
  • Update SledStorage key.rs to use IVec::from_iter, not IVec::from @panarch (#765)
  • Update SledStorage scan_(indexed)_data key not to contain table prefix, @panarch (#762)
  • Update sled-storage::update_data not to return error on not-existing … @panarch (#717)

βš“ New queries support

Select query without table & support SERIES(N)

SELECT 1;
SELECT N FROM SERIES(10);

more info - test-suite/series

  • Support SELECT * FROM Series(N) and SELECT 1(without table) @devgony (#733)

VALUES support

VALUES (1, 'a'), (2, 'b');
VALUES (1, 'a'), (2, 'b') LIMIT 1;
VALUES (1, 'a'), (2, 'b') LIMIT 1 OFFSET 1;
SELECT * FROM (VALUES (1, 'a'), (2, 'b')) AS Derived;
SELECT * FROM (VALUES (1, 'a'), (2, 'b')) AS Derived(id, name);
CREATE TABLE TableFromValues AS VALUES (1, 'a', True, Null, Null), (2, 'b', False, 3, Null)

more info - test-suite/values

Inline view

SELECT * FROM (SELECT COUNT(*) FROM InnerTable) AS InlineView

more info - test-suite/inline_view

  • Support Inline view (FROM clause subquery) @devgony (#523)

πŸ’’ New storage - SharedMemoryStorage

Non-persistent storage engine which works in multi-threaded environment

🌟 [Alpha Phase] AST Builder

Now, SQL is not the only language supported by GlueSQL!
AST Builder generates GlueSQL AST directly from Rust codes.

e.g.

let actual = table("Bar")
    .select()
    .filter(col("id").is_null())
    .group_by("id, (a + name)")
    .build();
let expected = "
    SELECT * FROM Bar
    WHERE id IS NULL
    GROUP BY id, (a + name)
";  
let actual = table("Bar")
    .select()
    .group_by("city")
    .project("city, COUNT(name) as num")
    .build();
let expected = "
    SELECT
      city, COUNT(name) as num
    FROM Bar
    GROUP BY city
";
let actual = table("Person")
    .delete()
    .filter(col("name").is_null())
    .build();
let expected = "DELETE FROM Person WHERE name IS NULL";

more info - core/ AST Builder

Related PRs

πŸš€ Features

CLI updates

New data types

New aggregate function - STDEV & VARIANCE

New function - IFNULL

New statement - SHOW INDEXES FROM {table}

ToSql

  • Implement ToSql trait which displays AST as SQL text format @bearney74 (#554)

πŸ’‘ Improvements

GitHub Action related

  • Update rust.yml GitHub Action to handle sled_transaction_timeout_* te… @panarch (#772)
  • Remove clippy warning in mac os @24seconds (#715)
  • Run github action job parallel @24seconds (#699)
  • Update coverage action to use grcov & Coveralls @panarch (#647)
  • Simplify github rust action - Run tests & Run examples, @panarch (#594)

Test Suite refactoring

rust-toolchain & sqlparser-rs migration

Other improvements

Read more

v0.11.0 🌈

14 May 04:03
5bfd458
Compare
Choose a tag to compare

🌊 Breaking Changes

🌈 GlueSQL.js

JavaScript interface for both web browsers and Node.js
GlueSQL works again in web browsers!

e.g.

import { gluesql } from 'gluesql';

const db = await gluesql();

db.query(`
  CREATE TABLE User (id INTEGER, name TEXT);
  INSERT INTO User VALUES (1, "Hello"), (2, "World");
`);

const [{ rows }] = await db.query('SELECT * FROM User;');
console.log(rows);

More Info

Related PRs

  • Implement TryFrom between Value and serde_json::Value @panarch (#501)
  • GlueSQL.js - support both web browsers and Node.js @panarch (#512)
  • Fix gluesql-js/package.json to publish files correctly, @panarch (#543)

πŸš€ Features

New functions - ABS, SIGN and CONCAT

SHOW COLUMNS

SledStorage export and import

  • Implement SledStorage export & import features @panarch (#547)

CLI - SQL file read-and-execute

Other new features

  • Implement cast to decimal @Earney (#529)
  • More numeric binary operations with Decimal @Earney (#530)
  • Implement hash join executor support @panarch (#494)
  • Feature implementation - Unary Factorial operation for (unsigned) INT8 type @MRGRAVITY817 (#477)
  • Support limit, offset clause in Insert into values ~ @devgony (#484)
  • Update evaluate_stateless to support all existing SQL functions, @panarch (#471)

πŸ’‘ Improvements

sqlparser-rs migration

Unit test

Error handling

  • Scalar subquery should throw Error when more than one row returned @devgony (#537)
  • Apply better names to numeric binary operation error names #424 @Earney (#534)
  • cast 255 as int8, should return an error, but returns 127 instead (resolves issue #545) @Earney (#546)

Other improvements

πŸ› Bug Fixes

  • Fix CLI --execute {file}.sql option to support CRLF line break, @panarch (#519)
  • Fix value/ big_endian module to handle negative integers correctly, @panarch (#505)

πŸ‘ New Contributors

Full Changelog: v0.10.2...v0.11.0

v0.10.2

11 Jan 11:45
a23e957
Compare
Choose a tag to compare

πŸ› Bug Fixes

# Cargo.toml

[dependencies.gluesql]
version = "0.10.2"
default-features = false
features = ["memory-storage"]
# or features = ["sled-storage"]

Configuration above now works.
memory-storage or sled-storage features were not working in v0.10.1 and it is fixed in v0.10.2.

πŸ’‘ Improvements

  • Add --all-targets to cargo test in github rust action @panarch (#467)
  • Support limit, offset clause in Insert into Table Select ~ @devgony (#466)

Full Changelog: v0.10.1...v0.10.2