rustdb/
expr.rs

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