Skip to main content

rustdb/
expr.rs

1use crate::alloc::{LBox, LHashMap, LRc, LVec, TBox, TVec, lbox, lboxstr, lhashmap, lvec};
2use crate::*;
3use Instruction::{DataOp, ForNext, ForSortNext, Jump, JumpIfFalse};
4
5/// Holds function name, line, column and message.
6#[derive(Clone)]
7pub(crate) struct SqlError {
8    pub rname: String,
9    pub line: usize,
10    pub column: usize,
11    pub msg: String,
12}
13/// Table Expression ( not yet type-checked or compiled against database ).
14pub enum TableExpression {
15    /// Base table.
16    Base(ObjRef),
17    /// VALUEs.
18    Values(TVec<TVec<Expr>>),
19}
20/// Assign operation.
21#[derive(Clone, Copy)]
22#[non_exhaustive]
23pub enum AssignOp {
24    /// Assign.
25    Assign,
26    /// append.
27    Append,
28    /// Increment.
29    Inc,
30    /// Decrement.
31    Dec,
32}
33/// Vector of local variable numbers and AssignOp.
34pub type Assigns = LVec<(usize, AssignOp)>;
35
36/// From Expression ( not yet compiled ).
37#[non_exhaustive]
38pub struct FromExpression {
39    /// Column names.
40    pub colnames: LVec<LBox<str>>,
41    /// Assigns.
42    pub assigns: Assigns,
43    /// Expressions.
44    pub exps: TVec<Expr>,
45    /// FROM clause.
46    pub from: Option<TBox<TableExpression>>,
47    /// WHERE expression.
48    pub wher: Option<Expr>,
49    /// ORDER BY clause.
50    pub orderby: TVec<(Expr, bool)>,
51}
52
53/// Parsing token.
54#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
55pub enum Token {
56    /* Note: order is significant */
57    /// Less.
58    Less,
59    /// Less or Equal.
60    LessEqual,
61    /// Greater or Equal.
62    GreaterEqual,
63    /// Greater.
64    Greater,
65    /// Equal.
66    Equal,
67    /// Not Equal.
68    NotEqual,
69    /// In.
70    In,
71    /// +
72    Plus,
73    /// -
74    Minus,
75    /// *
76    Times,
77    /// /
78    Divide,
79    /// %
80    Percent,
81    /// |
82    VBar,
83    /// AND
84    And,
85    /// OR
86    Or,
87    /// |=
88    VBarEqual,
89    /// +=
90    PlusEqual,
91    /// -=
92    MinusEqual,
93    /// Identifier.
94    Id,
95    /// Number.
96    Number,
97    /// Hex number.
98    Hex,
99    /// String literal.
100    String,
101    /// (
102    LBra,
103    /// )
104    RBra,
105    /// ,
106    Comma,
107    /// :
108    Colon,
109    /// .
110    Dot,
111    /// !
112    Exclamation,
113    /// Unknown.
114    Unknown,
115    /// End of file.
116    EndOfFile,
117}
118
119impl Token {
120    /// Get precedence of operator.
121    pub fn precedence(self) -> i8 {
122        const PA: [i8; 15] = [10, 10, 10, 10, 10, 10, 10, 20, 20, 30, 30, 30, 15, 8, 5];
123        PA[self as usize]
124    }
125}
126
127/// Scalar Expression (uncompiled).
128#[non_exhaustive]
129pub struct Expr {
130    /// Expression kind.
131    pub exp: ExprIs,
132    /// Data type.
133    pub data_type: DataType,
134    /// Doesn't depend on FROM clause.
135    pub is_constant: bool,
136    /// Has been type-checked.
137    pub checked: bool,
138    /// Column number.
139    pub col: usize,
140}
141
142impl Expr {
143    /// Construct new Expr.
144    pub fn new(exp: ExprIs) -> Self {
145        Expr {
146            exp,
147            data_type: NONE,
148            is_constant: false,
149            checked: false,
150            col: 0,
151        }
152    }
153}
154
155/// Scalar Expression variants.
156#[non_exhaustive]
157pub enum ExprIs {
158    /// Constant.
159    Const(Value),
160    /// Local variable.
161    Local(usize),
162    /// Column.
163    ColName(LBox<str>),
164    /// Binary operator expression.
165    Binary(Token, TBox<Expr>, TBox<Expr>),
166    /// Not expression.
167    Not(TBox<Expr>),
168    /// Unary minus.
169    Minus(TBox<Expr>),
170    /// Case expression.
171    Case(TVec<(Expr, Expr)>, TBox<Expr>),
172    /// Function call.
173    FuncCall(ObjRef, TVec<Expr>),
174    /// Builtin function call.
175    BuiltinCall(TBox<str>, TVec<Expr>), // Note: Builtin map is shared between threads so cannot use LBox<str>.
176    /// Scalar select.
177    ScalarSelect(TBox<FromExpression>),
178    /// List of expressions.
179    List(TVec<Expr>),
180}
181
182/// Object reference ( Schema.Name ).
183#[derive(PartialEq, PartialOrd, Eq, Hash, Clone)]
184#[non_exhaustive]
185pub struct ObjRef {
186    /// Schema.
187    pub schema: LBox<str>,
188    /// Name within Schema.
189    pub name: LBox<str>,
190}
191
192impl ObjRef {
193    /// Construct from string references.
194    pub fn new(s: &str, n: &str) -> Self {
195        Self {
196            schema: lboxstr(s),
197            name: lboxstr(n),
198        }
199    }
200    /// Used for error messages.
201    pub fn str(&self) -> String {
202        format!("[{}].[{}]", &self.schema, &self.name)
203    }
204}
205
206/// Binary=1, String=2, Int=3, Float=4, Bool=5.
207#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
208#[non_exhaustive]
209pub enum DataKind {
210    /// None.
211    None = 0,
212    /// Binary.
213    Binary = 1,
214    /// String.
215    String = 2,
216    /// Integer.
217    Int = 3,
218    /// Float.
219    Float = 4,
220    /// Bool.
221    Bool = 5,
222}
223
224/// Low 3 (KBITS) bits are DataKind, rest is size in bytes.
225pub type DataType = usize;
226
227pub(crate) const KBITS: usize = 3;
228pub(crate) const NONE: DataType = DataKind::None as usize;
229pub(crate) const BINARY: DataType = DataKind::Binary as usize + (16 << KBITS);
230pub(crate) const STRING: DataType = DataKind::String as usize + (16 << KBITS);
231pub(crate) const NAMESTR: DataType = DataKind::String as usize + (32 << KBITS);
232pub(crate) const BIGSTR: DataType = DataKind::String as usize + (250 << KBITS);
233pub(crate) const INT: DataType = DataKind::Int as usize + (8 << KBITS);
234pub(crate) const FLOAT: DataType = DataKind::Float as usize + (4 << KBITS);
235pub(crate) const DOUBLE: DataType = DataKind::Float as usize + (8 << KBITS);
236pub(crate) const BOOL: DataType = DataKind::Bool as usize + (1 << KBITS);
237
238/// Compute the DataKind of a DataType.
239pub fn data_kind(x: DataType) -> DataKind {
240    const DKLOOK: [DataKind; 6] = [
241        DataKind::None,
242        DataKind::Binary,
243        DataKind::String,
244        DataKind::Int,
245        DataKind::Float,
246        DataKind::Bool,
247    ];
248    DKLOOK[x % (1 << KBITS)]
249}
250
251/// Compute the number of bytes required to store a value of the specified DataType.
252#[must_use]
253pub fn data_size(x: DataType) -> usize {
254    x >> KBITS
255}
256
257/// Compilation block ( body of function or batch section ).
258pub struct Block<'a> {
259    /// Number of function parameters.
260    pub param_count: usize,
261    /// Function return type.
262    pub return_type: DataType,
263    /// Datatypes of paramaters and local variables.
264    pub local_typ: LVec<DataType>,
265    /// List of instructions.
266    pub ilist: LVec<Instruction>,
267    /// Id of break.
268    pub break_id: usize,
269    /// Database.
270    pub db: DB,
271    /// Current table in scope by FROM clause( or UPDATE statment ).
272    pub from: Option<CTableExpression>,
273    /// Only parse, no type checking or compilation.
274    pub parse_only: bool,
275    /// List of jumps.
276    jumps: LVec<usize>,
277    /// Lookup jump label by name.   
278    labels: LHashMap<&'a [u8], usize>,
279    /// Lookup local variable by name.
280    local_map: LHashMap<&'a [u8], usize>,
281    /// Names of local variables.
282    locals: LVec<&'a [u8]>,
283}
284
285impl<'a> Block<'a> {
286    /// Construct a new block.
287    pub fn new(db: DB) -> Self {
288        Block {
289            ilist: lvec(),
290            jumps: lvec(),
291            labels: lhashmap(),
292            local_map: lhashmap(),
293            locals: lvec(),
294            local_typ: lvec(),
295            break_id: 0,
296            param_count: 0,
297            return_type: NONE,
298            from: None,
299            db,
300            parse_only: false,
301        }
302    }
303
304    /// Check labels are all defined and patch jump instructions.
305    pub fn resolve_jumps(&mut self) {
306        for (k, v) in &self.labels {
307            if self.jumps[*v] == usize::MAX {
308                panic!("undefined label: {}", parse::tos(k));
309            }
310        }
311        for i in &mut self.ilist {
312            match i {
313                JumpIfFalse(x, _) | Jump(x) | ForNext(x, _) | ForSortNext(x, _) => {
314                    *x = self.jumps[*x]
315                }
316                _ => {}
317            }
318        }
319    }
320
321    /// Add an instruction to the instruction list.
322    pub fn add(&mut self, s: Instruction) {
323        if !self.parse_only {
324            self.ilist.push(s);
325        }
326    }
327
328    /// Add a Data Operation (DO) to the instruction list.
329    pub fn dop(&mut self, dop: DO) {
330        if !self.parse_only {
331            self.add(DataOp(lbox(dop)));
332        }
333    }
334
335    /// Check the parameter kinds match the function.
336    pub fn check_types(&self, r: &LRc<Function>, pkinds: &[DataKind]) {
337        if pkinds.len() != r.param_count {
338            panic!("param count mismatch");
339        }
340        for (i, pk) in pkinds.iter().enumerate() {
341            let ft = data_kind(r.local_typ[i]);
342            let et = *pk;
343            if ft != et {
344                panic!("param type mismatch expected {:?} got {:?}", ft, et);
345            }
346        }
347    }
348
349    // Helper functions for other statements.
350
351    /// Define a local variable ( parameter or declared ).
352    pub fn def_local(&mut self, name: &'a [u8], dt: DataType) {
353        let local_id = self.local_typ.len();
354        self.local_typ.push(dt);
355        self.locals.push(name);
356        if self.local_map.contains_key(name) {
357            panic!("duplicate variable name");
358        }
359        self.local_map.insert(name, local_id);
360    }
361
362    /// Get the number of a local variable from a name.
363    pub fn get_local(&self, name: &[u8]) -> Option<&usize> {
364        self.local_map.get(name)
365    }
366
367    /// Get the name of a local variable from a number.
368    pub fn local_name(&self, num: usize) -> &[u8] {
369        self.locals[num]
370    }
371
372    /// Get a local jump id.
373    pub fn get_jump_id(&mut self) -> usize {
374        let result = self.jumps.len();
375        self.jumps.push(usize::MAX);
376        result
377    }
378
379    /// Set instruction location of jump id.
380    pub fn set_jump(&mut self, jump_id: usize) {
381        self.jumps[jump_id] = self.ilist.len();
382    }
383
384    /// Get a local jump id to current location.
385    pub fn get_loop_id(&mut self) -> usize {
386        let result = self.get_jump_id();
387        self.set_jump(result);
388        result
389    }
390
391    /// Get a number for a local goto label.
392    pub fn get_goto_label(&mut self, s: &'a [u8]) -> usize {
393        if let Some(jump_id) = self.labels.get(s) {
394            *jump_id
395        } else {
396            let jump_id = self.get_jump_id();
397            self.labels.insert(s, jump_id);
398            jump_id
399        }
400    }
401
402    /// Set the local for a local goto lable.
403    pub fn set_goto_label(&mut self, s: &'a [u8]) {
404        if let Some(jump_id) = self.labels.get(s) {
405            let j = *jump_id;
406            if self.jumps[j] != usize::MAX {
407                panic!("label already set");
408            }
409            self.set_jump(j);
410        } else {
411            let jump_id = self.get_loop_id();
412            self.labels.insert(s, jump_id);
413        }
414    }
415
416    /// Get the DataKind of an expression.
417    pub fn kind(&self, e: &mut Expr) -> DataKind {
418        compile::c_check(self, e);
419        data_kind(e.data_type)
420    }
421}