The current state of creating expressions is deeply limiting and unidiomatic. It is composed of:
Functions: An enum that handles all "operation" types
Mappings: A trait that implements how to build all expressions using functions
Expr: A tree-like structure for arbitrary expressions. Can be either Literal, Boolean or Functional
Fallbacks:
Having Mappings be an all or nothing trait removes a lot of type safety. As it allows illegal type constructions that internally error, which are only brought up when sealing the builder. Ideally all type safety is enforced, and the checker only validates correctness with respect to the schema.
Having all expressions be variants of Expr and its inner types is also very restrictive. Types like FuncExpr are too generic to handle type safety and how to store variables. For example it is really awkward to define a CASE expression using FuncExpr.
Functions as an enum is simply a bad way to keep track of things, and should just not exist.
Proposal:
Each operation should be encapsulated into its own struct, e.g. LenExpr.
Expressions are correct upto the type level (enforced by construction) and as part of some trait (Expr) validate any database data, such as the existance and types of tables/columns.
In order to keep the functional nature of the API, there will then need to be traits associated with each operation, e.g. IntoLenExpr which expose the public method (.len()) used to create the type.
In order to ease the implementation of traits like IntoLenExpr, we can define more generic traits such as Textual, and have IntoLenExpr extend these traits. This way we can generate a LENGTH() expression from a column, string, or "StrConcatExpr".
Challenges:
An initial implementation of LenExpr for example would wrap a Box<dyn Textual>, however the type errasure in the trait object would make it unfeasable to then apply the checking operation.
The current state of creating expressions is deeply limiting and unidiomatic. It is composed of:
Functions
: An enum that handles all "operation" typesMappings
: A trait that implements how to build all expressions using functionsExpr
: A tree-like structure for arbitrary expressions. Can be either Literal, Boolean or FunctionalFallbacks:
Mappings
be an all or nothing trait removes a lot of type safety. As it allows illegal type constructions that internally error, which are only brought up when sealing the builder. Ideally all type safety is enforced, and the checker only validates correctness with respect to the schema.Expr
and its inner types is also very restrictive. Types likeFuncExpr
are too generic to handle type safety and how to store variables. For example it is really awkward to define aCASE
expression usingFuncExpr
.Functions
as an enum is simply a bad way to keep track of things, and should just not exist.Proposal:
LenExpr
.Expr
) validate any database data, such as the existance and types of tables/columns.IntoLenExpr
which expose the public method (.len()
) used to create the type.IntoLenExpr
, we can define more generic traits such asTextual
, and haveIntoLenExpr
extend these traits. This way we can generate aLENGTH()
expression from a column, string, or "StrConcatExpr
".Challenges:
LenExpr
for example would wrap aBox<dyn Textual>
, however the type errasure in the trait object would make it unfeasable to then apply the checking operation.