qraft-core 0.1.2

Core type system, query model, decoding, and SQL lowering primitives for qraft.
Documentation
use crate::{
    expression::{Operator, PostfixOperator, UnaryOperator},
    lower::SubqueryBase,
    query::{JoinKind, SortKind},
    span::TextSpan,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TemporalKind {
    Date,
    Time,
    Year,
    Month,
    Day,
}

#[derive(Debug, Clone, Copy)]
pub enum RpnInstr {
    // stack
    Column {
        span: TextSpan,
        table: Option<TextSpan>,
    },
    Table {
        span: TextSpan,
    },
    Param {
        id: u32,
    },
    Null,
    Raw {
        span: TextSpan,
        params: usize,
    },
    Star,
    // operator
    // [project] [from] [filters];
    Subquery(SubqueryBase),

    // [lhs] as [alias];
    Alias {
        span: TextSpan,
        inner: usize,
    },
    // [lhs] [op] [rhs];
    Binary {
        op: Operator,
        lhs: usize,
        rhs: usize,
    },
    // [lhs] between [low] and [high];
    Between {
        negated: bool,
        lhs: usize,
        low: usize,
        high: usize,
    },
    // [op] [lhs];
    Unary {
        op: UnaryOperator,
        rhs: usize,
    },
    // [lhs] [op]
    Postfix {
        op: PostfixOperator,
        lhs: usize,
    },

    // [lhs]*, ;
    Seperated {
        count: usize,
    },
    // [lhs]* cross join ;
    CrossJoin {
        count: usize,
    },

    Join {
        kind: JoinKind,
        lhs: usize,
        rhs: usize,
    },
    OrderBy {
        sort: SortKind,
        inner: usize,
    },
    Exists {
        negated: bool,
        inner: usize,
    },
    LitInt {
        value: i64,
    },
    Fn {
        name: &'static str,
        args: usize,
    },
    JsonExtractText {
        inner: usize,
        path: TextSpan,
    },
    JsonContains {
        inner: usize,
        rhs: usize,
        path: TextSpan,
        negated: bool,
        compound: bool,
    },
    JsonContainsKey {
        inner: usize,
        path: TextSpan,
        negated: bool,
    },
    JsonLength {
        inner: usize,
        path: TextSpan,
    },
    Temporal {
        inner: usize,
        kind: TemporalKind,
    },
    In {
        negated: bool,
        lhs: usize,
        rhs: usize,
    },
    Nop,
    Assignement {
        lhs: usize,
        rhs: usize,
    },
}

impl RpnInstr {
    pub fn len(&self) -> usize {
        match self {
            RpnInstr::Column { .. }
            | RpnInstr::Table { .. }
            | RpnInstr::Param { .. }
            | RpnInstr::Null
            | RpnInstr::Star
            | RpnInstr::LitInt { .. }
            | RpnInstr::Nop => 0,
            RpnInstr::Raw { params, .. } => *params,
            RpnInstr::Subquery(base) => base.total(),
            RpnInstr::Alias { inner, .. } => *inner,
            RpnInstr::Binary { lhs, rhs, .. } => lhs + rhs,
            RpnInstr::Between { lhs, low, high, .. } => lhs + low + high,
            RpnInstr::Unary { rhs, .. } => *rhs,
            RpnInstr::Postfix { lhs, .. } => *lhs,
            RpnInstr::Seperated { .. } => 0,
            RpnInstr::CrossJoin { .. } => 0,
            RpnInstr::Join { lhs, rhs, .. } => lhs + rhs,
            RpnInstr::OrderBy { inner, .. } => *inner,
            RpnInstr::Exists { inner, .. } => *inner,
            RpnInstr::Fn { args, .. } => *args,
            RpnInstr::JsonExtractText { inner, .. } => *inner,
            RpnInstr::JsonContains { inner, rhs, .. } => inner + rhs,
            RpnInstr::JsonContainsKey { inner, .. } => *inner,
            RpnInstr::JsonLength { inner, .. } => *inner,
            RpnInstr::Temporal { inner, .. } => *inner,
            RpnInstr::In { lhs, rhs, .. } => lhs + rhs,
            RpnInstr::Assignement { lhs, rhs } => lhs + rhs,
        }
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}