gluesql / gluesql

GlueSQL is quite sticky. It attaches to anywhere.

Home Page:https://gluesql.org/docs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[AST Builder] Implement Index by Expression in Select

seonghun-dev opened this issue · comments

Description

Implements ast builders for index_by Expression

They take a similar form to index hints in traditional SQL,
but while in SQL these index hints can be ignored at the option of the optimizer,
in GlueSQL Query Builder they are generated rather than ignored
because they are part of the actual query generation.

What is Index hint in SQL

MySQL

Oracle

  • Write a hint comment on the first line of the SELECT clause to give it the proper index
SELECT /*+ INDEX(a EMP_IDX02) */ a.empno , a.ename , a.hiredate FROM emp a

FSM Chart

Current FSM Chart (Exclude Detail)

image

New FSM Chart (Exclude Detail)

image

In index Node FSM

The interior of the node in the index consists of another FSM.
Prevent chaining from becoming too long.

image

Task

Index Hint Works With Update Expression, But in this Issue will be limit to Select Expression

  • Add Index Node to Select FSM
  • Add Use Index Node
  • Add Primary Key Node
  • Add Non clustered Node

The following tests should be passed:

Index By

    #[test]
    fn test_index() {
        let sql = "
        SELECT * FROM Player
        WHERE name IN (
            SELECT * FROM Player WHERE id = 1
        )";

        let index_node = use_index().primary_key("id");
        let query_node = table("Player")
            .select()
            .index_by(index_node)
            .filter("id".eq(1));
        let query_builder = table("Player")
            .select()
            .filter("name".in_list(subquery))
            .build();

        let actual = plan(&storage, query_builder);
        let expected = {
            let subquery = Query {
                body: SetExpr::Select(Box::new(Select {
                    projection: vec![SelectItem::Wildcard],
                    from: TableWithJoins {
                        relation: TableFactor::Table {
                            name: "Player".to_owned(),
                            alias: None,
                            index: Some(IndexItem::PrimaryKey(expr("1"))),
                        },
                        joins: Vec::new(),
                    },
                    selection: None,
                    group_by: Vec::new(),
                    having: None,
                })),
                limit: None,
                offset: None,
                order_by: Vec::new(),
            };
        };
    }

which storage types do actually support the index?

which storage types do actually support the index?

Currently the only storage which supports non clustered index is SledStorage.

Thanks @panarch , I also found that is mentioned in the README 👍. I am compiling to WASM so I wonder which storage is being used under the hood to persist the data when using Sled (if SledStorage compiles to WASM)?