Skip to main content

rustdb/
parse.rs

1use crate::alloc::{LBox, LVec, lbox, lboxstr, lvec, tbox, tboxstr, tvec};
2use crate::{
3    AlterCol, AssignOp, BINARY, BOOL, Block, ColInfo, DB, DO, DOUBLE, DataType, EvalEnv, Expr,
4    ExprIs, FLOAT, FromExpression, INT, IndexInfo, Instruction, NONE, ObjRef, Rc, STRING, SqlError,
5    TableExpression, Token, Transaction, Value, c_bool, compile, data_kind, panic, util,
6};
7use Instruction::{Call, Execute, Jump, JumpIfFalse, PopToLocal, Return, Select, Throw};
8use compile::{c_delete, c_for, c_function, c_select, c_set, c_table, c_te, c_update, push};
9use std::{mem, str};
10
11/// SQL parser.
12///
13/// Name convention for methods:
14///
15/// s_ parses a statement.
16///
17/// exp_ parses an expression.
18pub struct Parser<'a> {
19    /// Block information - local labels, jumps, instructions etc.
20    pub b: Block<'a>,
21    /// Name of function being compiled ( None if batch ).
22    pub function_name: Option<&'a ObjRef>,
23    /// Source SQL.
24    source: &'a [u8],
25    /// Index into source.
26    source_ix: usize,
27    /// Current input byte (char).
28    cc: u8,
29    /// Current token.
30    token: Token,
31    /// Source index of start of current token.
32    token_start: usize,
33    /// Source index of start of current token (including spacce).
34    token_space_start: usize,
35    /// source slice for current token ( but string literals are in ts )
36    cs: &'a [u8],
37    /// String literal.
38    ts: String,
39    source_column: usize,
40    source_line: usize,
41    decimal_int: i64,
42    /// May be able to get rid of this.
43    prev_source_column: usize,
44    prev_source_line: usize,
45}
46
47impl<'a> Parser<'a> {
48    /// Construct a new parser.
49    pub fn new(src: &'a str, db: &DB) -> Self {
50        let source = src.as_bytes();
51        let mut result = Self {
52            source,
53            function_name: None,
54            source_ix: 0,
55            cc: 0,
56            token_start: 0,
57            token_space_start: 0,
58            token: Token::EndOfFile,
59            cs: source,
60            ts: String::new(),
61            source_column: 1,
62            source_line: 1,
63            prev_source_column: 1,
64            prev_source_line: 1,
65            decimal_int: 0,
66            b: Block::new(db.clone()),
67        };
68        result.read_char();
69        result.read_token();
70        result
71    }
72
73    /// Parse a single statement.
74    fn statement(&mut self) {
75        if self.token == Token::Id {
76            let id = self.cs;
77            self.read_token();
78            if self.test(Token::Colon) {
79                self.b.set_goto_label(id);
80            } else {
81                match id {
82                    b"ALTER" => self.s_alter(),
83                    b"BEGIN" => self.s_begin(),
84                    b"BREAK" => self.s_break(),
85                    b"CREATE" => self.s_create(),
86                    b"DROP" => self.s_drop(),
87                    b"DECLARE" => self.s_declare(),
88                    b"DELETE" => self.s_delete(),
89                    b"EXEC" => self.s_exec(),
90                    b"CHECK" => self.s_check(),
91                    b"EXECUTE" => self.s_execute(),
92                    b"FOR" => self.s_for(),
93                    b"GOTO" => self.s_goto(),
94                    b"IF" => self.s_if(),
95                    b"INSERT" => self.s_insert(),
96                    b"RETURN" => self.s_return(),
97                    b"SELECT" => self.s_select(),
98                    b"SET" => self.s_set(),
99                    b"THROW" => self.s_throw(),
100                    b"UPDATE" => self.s_update(),
101                    b"WHILE" => self.s_while(),
102                    _ => panic!("statement keyword expected, got '{}'", tos(id)),
103                }
104            }
105        } else {
106            panic!("statement keyword expected, got '{:?}'", self.token)
107        }
108    } // end fn statement
109
110    /// Parse and execute a batch of statements.
111    pub fn batch(&mut self, rs: &mut dyn Transaction) {
112        loop {
113            while self.token != Token::EndOfFile && !self.test_id(b"GO") {
114                self.statement();
115            }
116            self.b.resolve_jumps();
117            let mut ee = EvalEnv::new(self.b.db.clone(), rs);
118            // let start = std::time::Instant::now();
119            ee.alloc_locals(&self.b.local_typ, 0);
120            ee.go(&self.b.ilist);
121            if self.token == Token::EndOfFile {
122                break;
123            }
124            self.b = Block::new(self.b.db.clone());
125        }
126    }
127
128    /// Parse the definition of a function.
129    pub fn parse_function(&mut self) {
130        self.read(Token::LBra);
131        while self.token == Token::Id {
132            let name = self.id_ref();
133            let typ = self.read_data_type();
134            self.b.def_local(name, typ);
135            self.b.param_count += 1;
136            if self.token == Token::RBra {
137                break;
138            }
139            assert!(
140                self.token == Token::Comma,
141                "comma or closing bracket expected"
142            );
143            self.read_token();
144        }
145        self.read(Token::RBra);
146        self.b.return_type = if
147        /*is_func == 1 || is_func == 0 &&*/
148        self.cs == b"RETURNS" {
149            self.read_id(b"RETURNS");
150            self.read_data_type()
151        } else {
152            NONE
153        };
154        if self.b.return_type != NONE {
155            self.b.def_local(b"result", self.b.return_type);
156        }
157        self.read_id(b"AS");
158        self.read_id(b"BEGIN");
159        self.s_begin();
160        self.b.resolve_jumps();
161    }
162
163    /// Read a byte, adjusting source line/column.
164    fn read_char(&mut self) -> u8 {
165        let cc;
166        if self.source_ix >= self.source.len() {
167            cc = 0;
168            self.source_ix = self.source.len() + 1;
169        } else {
170            cc = self.source[self.source_ix];
171            if cc == b'\n' {
172                self.source_column = 1;
173                self.source_line += 1;
174            } else if (cc & 192) != 128
175            // Test allows for UTF8 continuation chars.
176            {
177                self.source_column += 1;
178            }
179            self.source_ix += 1;
180        }
181        self.cc = cc;
182        cc
183    }
184
185    /// Read the next token.
186    fn read_token(&mut self) {
187        self.token_space_start = self.source_ix - 1;
188        self.prev_source_line = self.source_line;
189        self.prev_source_column = self.source_column;
190        let mut cc = self.cc;
191        let mut token;
192        'skip_space: loop {
193            while cc == b' ' || cc == b'\n' || cc == b'\r' {
194                cc = self.read_char();
195            }
196            self.token_start = self.source_ix - 1;
197            let sc: u8 = cc;
198            cc = self.read_char();
199            match sc {
200                b'A'..=b'Z' | b'a'..=b'z' | b'@' => {
201                    token = Token::Id;
202                    while cc.is_ascii_alphabetic() {
203                        cc = self.read_char();
204                    }
205                    self.cs = &self.source[self.token_start..self.source_ix - 1];
206                }
207                b'0'..=b'9' => {
208                    token = Token::Number;
209                    let fc = self.source[self.token_start];
210                    if fc == b'0' && cc == b'x' {
211                        cc = self.read_char();
212                        token = Token::Hex;
213                        while cc.is_ascii_hexdigit() {
214                            cc = self.read_char();
215                        }
216                    } else {
217                        while cc.is_ascii_digit() {
218                            cc = self.read_char();
219                        }
220                        let part1 = self.source_ix - 1;
221                        let s = str::from_utf8(&self.source[self.token_start..part1]).unwrap();
222                        self.decimal_int = s.parse().unwrap();
223                    }
224                    self.cs = &self.source[self.token_start..self.source_ix - 1];
225                }
226
227                b'[' => {
228                    token = Token::Id;
229                    let start = self.source_ix - 1;
230                    while cc != 0 {
231                        if cc == b']' {
232                            self.read_char();
233                            break;
234                        }
235                        cc = self.read_char();
236                    }
237                    self.cs = &self.source[start..self.source_ix - 2];
238                }
239
240                b'\'' => {
241                    token = Token::String;
242                    let mut start = self.source_ix - 1;
243                    self.ts = String::new();
244                    loop {
245                        assert!(cc != 0, "missing closing quote for string literal");
246                        if cc == b'\'' {
247                            cc = self.read_char();
248                            if cc != b'\'' {
249                                break;
250                            }
251                            self.ts.push_str(
252                                str::from_utf8(&self.source[start..self.source_ix - 1]).unwrap(),
253                            );
254                            start = self.source_ix;
255                        }
256                        cc = self.read_char();
257                    }
258                    self.ts
259                        .push_str(str::from_utf8(&self.source[start..self.source_ix - 2]).unwrap());
260                    break;
261                }
262                b'/' => {
263                    token = Token::Divide;
264                    if cc == b'*'
265                    // Skip comment.
266                    {
267                        cc = self.read_char();
268                        let mut prevchar = b'X';
269                        while (cc != b'/' || prevchar != b'*') && cc != 0 {
270                            prevchar = cc;
271                            cc = self.read_char();
272                        }
273                        cc = self.read_char();
274                        continue 'skip_space;
275                    }
276                }
277                b'>' => {
278                    token = Token::Greater;
279                    if cc == b'=' {
280                        token = Token::GreaterEqual;
281                        self.read_char();
282                    }
283                }
284                b'<' => {
285                    token = Token::Less;
286                    if cc == b'=' {
287                        token = Token::LessEqual;
288                        self.read_char();
289                    } else if cc == b'>' {
290                        token = Token::NotEqual;
291                        self.read_char();
292                    }
293                }
294                b'!' => {
295                    token = Token::Exclamation;
296                    if cc == b'=' {
297                        token = Token::NotEqual;
298                        self.read_char();
299                    }
300                }
301                b'(' => token = Token::LBra,
302                b')' => token = Token::RBra,
303                b'|' => {
304                    token = Token::VBar;
305                    if cc == b'=' {
306                        token = Token::VBarEqual;
307                        self.read_char();
308                    }
309                }
310                b'+' => {
311                    token = Token::Plus;
312                    if cc == b'=' {
313                        token = Token::PlusEqual;
314                        self.read_char();
315                    }
316                }
317                b'-' => {
318                    token = Token::Minus;
319                    if cc == b'-'
320                    // Skip single line comment.
321                    {
322                        while cc != b'\n' && cc != 0 {
323                            cc = self.read_char();
324                        }
325                        continue 'skip_space;
326                    } else if cc == b'=' {
327                        token = Token::MinusEqual;
328                        self.read_char();
329                    }
330                }
331                b',' => token = Token::Comma,
332                b'.' => token = Token::Dot,
333                b'=' => token = Token::Equal,
334                b':' => token = Token::Colon,
335                b'*' => token = Token::Times,
336                b'%' => token = Token::Percent,
337                0 => token = Token::EndOfFile,
338                _ => token = Token::Unknown,
339            }
340            break;
341        } // skip_space loop
342        self.token = token;
343    }
344
345    // ****************** Helper functions for parsing.
346
347    fn source_from(&self, start: usize, end: usize) -> String {
348        to_s(&self.source[start..end])
349    }
350
351    fn read_data_type(&mut self) -> DataType {
352        assert!(self.token == Token::Id, "datatype expected");
353        let mut t = match self.id_ref() {
354            b"int" => INT,
355            b"string" => STRING,
356            b"binary" => BINARY,
357            b"float" => FLOAT,
358            b"double" => DOUBLE,
359            b"bool" => BOOL,
360            _ => panic!("datatype expected"),
361        };
362        if self.test(Token::LBra) {
363            let mut n = self.decimal_int as usize;
364            self.read(Token::Number);
365            self.read(Token::RBra);
366            match t {
367                BINARY | STRING => {
368                    n += 1;
369                    n = n.clamp(9, 250);
370                }
371                INT => {
372                    assert!(n >= 1, "minimum int precision is 1");
373                    assert!(n <= 8, "maximum int precision is 8");
374                }
375                _ => panic!("invalid data type specification"),
376            }
377            t = (t % 8) + (8 * n);
378        }
379        t
380    }
381
382    /// Examine current token, determine if it is an operator.
383    /// Result is operator token and precedence, or -1 if current token is not an operator.
384    fn operator(&mut self) -> (Token, i8) {
385        let mut t = self.token;
386        if t >= Token::Id {
387            if t == Token::Id {
388                t = match self.cs {
389                    b"AND" => Token::And,
390                    b"OR" => Token::Or,
391                    b"IN" => Token::In,
392                    _ => return (t, -1),
393                }
394            } else {
395                return (t, -1);
396            }
397        }
398        (t, t.precedence())
399    }
400
401    fn idb(&mut self) -> LBox<str> {
402        lboxstr(tos(self.id_ref()))
403    }
404
405    fn id_ref(&mut self) -> &'a [u8] {
406        assert!(self.token == Token::Id, "name expected");
407        let result = self.cs;
408        self.read_token();
409        result
410    }
411
412    fn local(&mut self) -> usize {
413        let result: usize;
414        assert!(self.token == Token::Id, "name expected");
415        if let Some(lnum) = self.b.get_local(self.cs) {
416            result = *lnum;
417        } else {
418            panic!("undeclared local: {}", tos(self.cs))
419        }
420        self.read_token();
421        result
422    }
423
424    /// Checks the token is as expected, and consumes it.
425    fn read(&mut self, t: Token) {
426        if self.token != t {
427            panic!("expected '{:?}' got '{:?}'", t, self.token)
428        } else {
429            self.read_token();
430        }
431    }
432
433    /// Checks the token is the specified Id and consumes it.
434    fn read_id(&mut self, s: &[u8]) {
435        if self.token != Token::Id || self.cs != s {
436            panic!("expected '{}' got '{}'", tos(s), tos(self.cs));
437        } else {
438            self.read_token();
439        }
440    }
441
442    /// Tests whether the token is as specified. If so, it is consumed.
443    fn test(&mut self, t: Token) -> bool {
444        let result = self.token == t;
445        if result {
446            self.read_token();
447        }
448        result
449    }
450
451    /// Tests whether the token is the specified id. If so, it is consumed.
452    fn test_id(&mut self, s: &[u8]) -> bool {
453        if self.token != Token::Id || self.cs != s {
454            false
455        } else {
456            self.read_token();
457            true
458        }
459    }
460
461    /// Reads an ObjRef ( schema.name pair ).
462    fn obj_ref(&mut self) -> ObjRef {
463        let schema = self.idb();
464        self.read(Token::Dot);
465        let name = self.idb();
466        ObjRef { schema, name }
467    }
468
469    // Error handling.
470    /// Get the function name or "batch" if no function.
471    fn rname(&self) -> String {
472        if let Some(name) = self.function_name {
473            name.str()
474        } else {
475            "batch".to_string()
476        }
477    }
478
479    /// Construct SqlError based on current line/column/rname.
480    pub(crate) fn make_error(&self, msg: String) -> SqlError {
481        SqlError {
482            line: self.prev_source_line,
483            column: self.prev_source_column,
484            msg,
485            rname: self.rname(),
486        }
487    }
488
489    // End Helper functions for parsing.
490
491    // ****************** Expression parsing
492
493    /// Parses an expression that starts with an id.
494    fn exp_id(&mut self) -> Expr {
495        let name = self.id_ref();
496        if self.test(Token::Dot) {
497            let fname = self.id_ref();
498            let mut parms = tvec();
499            self.read(Token::LBra);
500            if self.token != Token::RBra {
501                loop {
502                    parms.push(self.exp());
503                    if !self.test(Token::Comma) {
504                        break;
505                    }
506                }
507            }
508            self.read(Token::RBra);
509            let name = ObjRef::new(tos(name), tos(fname));
510            Expr::new(ExprIs::FuncCall(name, parms))
511        } else if self.test(Token::LBra) {
512            let mut parms = tvec();
513            if self.token != Token::RBra {
514                loop {
515                    parms.push(self.exp());
516                    if !self.test(Token::Comma) {
517                        break;
518                    }
519                }
520            }
521            self.read(Token::RBra);
522            Expr::new(ExprIs::BuiltinCall(tboxstr(tos(name)), parms))
523        } else if name == b"true" {
524            Expr::new(ExprIs::Const(Value::Bool(true)))
525        } else if name == b"false" {
526            Expr::new(ExprIs::Const(Value::Bool(false)))
527        } else if let Some(lnum) = self.b.get_local(name) {
528            Expr::new(ExprIs::Local(*lnum))
529        } else {
530            Expr::new(ExprIs::ColName(lboxstr(tos(name))))
531        }
532    }
533
534    /// Parses a primary expression ( basic expression with no operators ).
535    fn exp_primary(&mut self) -> Expr {
536        let result;
537        if self.token == Token::Id {
538            result = if self.test_id(b"CASE") {
539                self.exp_case()
540            } else if self.test_id(b"NOT") {
541                let e = self.exp_p(10); // Not sure about precedence here.
542                Expr::new(ExprIs::Not(tbox(e)))
543            } else {
544                self.exp_id()
545            };
546        } else if self.test(Token::LBra) {
547            if self.test_id(b"SELECT") {
548                result = self.exp_scalar_select();
549            } else {
550                let exp = self.exp();
551                if self.test(Token::Comma)
552                // Operand of IN e.g. X IN ( 1,2,3 )
553                {
554                    let mut list = tvec();
555                    list.push(exp);
556                    loop {
557                        list.push(self.exp());
558                        if !self.test(Token::Comma) {
559                            break;
560                        }
561                    }
562                    result = Expr::new(ExprIs::List(list));
563                } else {
564                    result = exp;
565                }
566            }
567            self.read(Token::RBra);
568        } else if self.token == Token::String {
569            result = Expr::new(ExprIs::Const(Value::String(Rc::new(self.ts.clone()))));
570            self.read_token();
571        } else if self.token == Token::Number {
572            let value = self.decimal_int;
573            result = Expr::new(ExprIs::Const(Value::Int(value)));
574            self.read_token();
575        } else if self.token == Token::Hex {
576            assert!(
577                self.cs.len().is_multiple_of(2),
578                "hex literal must have even number of characters"
579            );
580            let hb = &self.source[self.token_start + 2..self.source_ix - 1];
581            result = Expr::new(ExprIs::Const(Value::RcBinary(Rc::new(util::parse_hex(hb)))));
582            self.read_token();
583        } else if self.test(Token::Minus) {
584            result = Expr::new(ExprIs::Minus(tbox(self.exp_p(30))));
585        } else {
586            panic!("expression expected")
587        }
588        result
589    }
590
591    fn exp_or_agg(&mut self) -> Expr {
592        let pri = self.exp_primary();
593        self.exp_lp(pri, 0)
594    }
595
596    /// Parse an expression.
597    fn exp(&mut self) -> Expr {
598        self.exp_p(0)
599    }
600
601    /// Parse an expression, with specified operator precedence.
602    fn exp_p(&mut self, precedence: i8) -> Expr {
603        let pr = self.exp_primary();
604        self.exp_lp(pr, precedence)
605    }
606
607    /// Apply binary operator to lhs based on precedence.
608    fn exp_lp(&mut self, mut lhs: Expr, precedence: i8) -> Expr {
609        let mut t = self.operator();
610        while t.1 >= precedence {
611            let op = t;
612            self.read_token();
613            let mut rhs = self.exp_primary();
614            t = self.operator();
615            while t.1 > op.1
616            /* or t is right-associative and t.1 == op.1 */
617            {
618                rhs = self.exp_lp(rhs, t.1);
619                t = self.operator();
620            }
621            lhs = Expr::new(ExprIs::Binary(op.0, tbox(lhs), tbox(rhs)));
622        }
623        lhs
624    }
625
626    /// Parse a CASE expression.
627    fn exp_case(&mut self) -> Expr {
628        let mut list = tvec();
629        while self.test_id(b"WHEN") {
630            let test = self.exp();
631            self.read_id(b"THEN");
632            let e = self.exp();
633            list.push((test, e));
634        }
635        assert!(!list.is_empty(), "empty CASE expression");
636        self.read_id(b"ELSE");
637        let els = tbox(self.exp());
638        self.read_id(b"END");
639        Expr::new(ExprIs::Case(list, els))
640    }
641
642    fn exp_scalar_select(&mut self) -> Expr {
643        let te = self.select_expression(false);
644        // if ( te.ColumnCount != 1 ) Error ( "Scalar select must have one column" );
645        Expr::new(ExprIs::ScalarSelect(tbox(te)))
646    }
647
648    // End Expression parsing
649
650    // ****************** Table expression parsing
651
652    fn insert_expression(&mut self, expect: usize) -> TableExpression {
653        self.read_id(b"VALUES");
654        let mut values = tvec();
655        while self.test(Token::LBra) {
656            let mut v = tvec();
657            loop {
658                v.push(self.exp());
659                if self.test(Token::RBra) {
660                    break;
661                }
662                assert!(
663                    self.token == Token::Comma,
664                    "comma or closing bracket expected"
665                );
666                self.read_token();
667            }
668            assert!(v.len() == expect, "wrong number of values");
669            values.push(v);
670            if !self.test(Token::Comma) && self.token != Token::LBra {
671                break;
672            } // The comma between multiple VALUES is optional.
673        }
674        TableExpression::Values(values)
675    }
676
677    fn te_named_table(&mut self) -> TableExpression {
678        let schema = self.idb();
679        self.read(Token::Dot);
680        let name = self.idb();
681        let name = ObjRef { schema, name };
682        TableExpression::Base(name)
683    }
684
685    fn primary_table_exp(&mut self) -> TableExpression {
686        assert!(self.token == Token::Id, "table name expected");
687        self.te_named_table()
688    }
689
690    fn exp_name(&self, exp: &Expr) -> LBox<str> {
691        match &exp.exp {
692            ExprIs::Local(num) => lboxstr(tos(self.b.local_name(*num))),
693            ExprIs::ColName(name) => lboxstr(name),
694            _ => lboxstr(""),
695        }
696    }
697
698    /// Parse a SELECT / SET / FOR expression.
699    fn select_expression(&mut self, set_or_for: bool) -> FromExpression {
700        let mut exps = tvec();
701        let mut colnames: LVec<LBox<str>> = lvec();
702        let mut assigns = lvec();
703        loop {
704            if set_or_for {
705                let local = self.local();
706                let op = match self.token {
707                    Token::Equal => AssignOp::Assign,
708                    Token::VBarEqual => AssignOp::Append,
709                    Token::PlusEqual => AssignOp::Inc,
710                    Token::MinusEqual => AssignOp::Dec,
711                    _ => panic!("assign operator expected"),
712                };
713                self.read_token();
714                assigns.push((local, op));
715            }
716            let exp = self.exp_or_agg();
717            if self.test_id(b"AS") {
718                colnames.push(self.idb());
719            } else {
720                colnames.push(self.exp_name(&exp));
721            }
722            exps.push(exp);
723            if !self.test(Token::Comma) {
724                break;
725            }
726        }
727        let from = if self.test_id(b"FROM") {
728            Some(tbox(self.primary_table_exp()))
729        } else {
730            None
731        };
732        let wher = if self.test_id(b"WHERE") {
733            Some(self.exp())
734        } else {
735            None
736        };
737        let mut orderby = tvec();
738        if self.test_id(b"ORDER") {
739            self.read_id(b"BY");
740            loop {
741                let exp = self.exp();
742                let desc = if self.test_id(b"DESC") {
743                    true
744                } else {
745                    self.test_id(b"ASC");
746                    false
747                };
748                orderby.push((exp, desc));
749                if !self.test(Token::Comma) {
750                    break;
751                }
752            }
753        }
754        FromExpression {
755            colnames,
756            assigns,
757            exps,
758            from,
759            wher,
760            orderby,
761        }
762    }
763
764    // ****************** Statement parsing
765
766    fn s_select(&mut self) {
767        let se = self.select_expression(false);
768        if !self.b.parse_only {
769            let cte = c_select(&mut self.b, se);
770            self.b.add(Select(lbox(cte)));
771        }
772    }
773
774    fn s_set(&mut self) {
775        let se = self.select_expression(true);
776        if !self.b.parse_only {
777            c_set(&mut self.b, se);
778        }
779    }
780
781    fn s_insert(&mut self) {
782        self.read_id(b"INTO");
783        let tr = self.obj_ref();
784        self.read(Token::LBra);
785        let mut cnames = lvec();
786        loop {
787            let cname = self.id_ref();
788            assert!(!cnames.contains(&cname), "duplicate column name");
789            cnames.push(cname);
790            if self.test(Token::RBra) {
791                break;
792            }
793            assert!(self.test(Token::Comma), "comma or closing bracket expected");
794        }
795        let mut src = self.insert_expression(cnames.len());
796        if !self.b.parse_only {
797            let t = c_table(&self.b, &tr);
798            let mut cnums: LVec<usize> = lvec();
799            {
800                for cname in &cnames {
801                    if let Some(cnum) = t.info.get(tos(cname)) {
802                        cnums.push(*cnum);
803                    } else {
804                        panic!("column name '{}' not found", tos(cname))
805                    }
806                }
807            }
808            let csrc = c_te(&self.b, &mut src);
809            self.b.dop(DO::Insert(t, cnums, csrc));
810        }
811    }
812
813    fn s_update(&mut self) {
814        let tname = self.obj_ref();
815        self.read_id(b"SET");
816        let mut assigns = tvec();
817        loop {
818            let name = self.idb();
819            self.read(Token::Equal);
820            let exp = self.exp();
821            assigns.push((name, exp));
822            if !self.test(Token::Comma) {
823                break;
824            }
825        }
826        assert!(self.test_id(b"WHERE"), "UPDATE must have a WHERE");
827        let mut wher = Some(self.exp());
828        if !self.b.parse_only {
829            c_update(&mut self.b, &tname, &mut assigns, &mut wher);
830        }
831    }
832
833    fn s_delete(&mut self) {
834        self.read_id(b"FROM");
835        let tname = self.obj_ref();
836        assert!(self.test_id(b"WHERE"), "DELETE must have a WHERE");
837        let mut wher = Some(self.exp());
838        if !self.b.parse_only {
839            c_delete(&mut self.b, &tname, &mut wher);
840        }
841    }
842
843    fn s_execute(&mut self) {
844        self.read(Token::LBra);
845        let mut exp = self.exp();
846        self.read(Token::RBra);
847        if !self.b.parse_only {
848            push(&mut self.b, &mut exp);
849            self.b.add(Execute);
850        }
851    }
852
853    fn s_check(&mut self) {
854        let name = self.obj_ref();
855        if !self.b.parse_only {
856            c_function(&self.b.db, &name);
857        }
858    }
859
860    fn s_exec(&mut self) {
861        let mut pname = self.idb();
862        let mut sname = lboxstr("");
863        if self.test(Token::Dot) {
864            sname = pname;
865            pname = self.idb();
866        }
867        let name = ObjRef {
868            schema: sname,
869            name: pname,
870        };
871        self.read(Token::LBra);
872        let mut pkinds = tvec();
873        if !self.test(Token::RBra) {
874            let mut e = self.exp();
875            pkinds.push(push(&mut self.b, &mut e));
876            while self.test(Token::Comma) {
877                let mut e = self.exp();
878                pkinds.push(push(&mut self.b, &mut e));
879            }
880            self.read(Token::RBra);
881        }
882        if !self.b.parse_only {
883            let func = c_function(&self.b.db, &name);
884            assert!(
885                func.return_type == NONE,
886                "EXEC function cannot have a return type"
887            );
888            self.b.check_types(&func, &pkinds);
889            self.b.add(Call(func));
890        }
891    }
892
893    fn s_for(&mut self) {
894        let se: FromExpression = self.select_expression(true);
895        let for_id = self.b.local_typ.len();
896        self.b.local_typ.push(NONE);
897        let start_id = self.b.get_jump_id();
898        let break_id = self.b.get_jump_id();
899        if !self.b.parse_only {
900            c_for(&mut self.b, se, start_id, break_id, for_id);
901        }
902        let save = self.b.break_id;
903        self.b.break_id = break_id;
904        self.statement();
905        self.b.break_id = save;
906        self.b.add(Jump(start_id));
907        self.b.set_jump(break_id);
908    }
909
910    // ****************** Parse Create statements.
911
912    fn create_table(&mut self) {
913        let name = self.obj_ref();
914        let source_start = self.source_ix - 2;
915        self.read(Token::LBra);
916        let mut ti = ColInfo::empty(name);
917        while !self.test(Token::RBra) {
918            let cname = tos(self.id_ref());
919            let typ = self.read_data_type();
920            assert!(!ti.add(cname, typ), "duplicate column name");
921            self.test(Token::Comma);
922        }
923        if !self.b.parse_only {
924            let _source = self.source_from(source_start, self.token_start);
925            self.b.dop(DO::CreateTable(ti));
926        }
927    }
928
929    fn create_index(&mut self) {
930        let iname = self.idb();
931        self.read_id(b"ON");
932        let tname = self.obj_ref();
933        self.read(Token::LBra);
934        let mut cnames = tvec();
935        loop {
936            cnames.push(tos(self.id_ref()));
937            if self.test(Token::RBra) {
938                break;
939            }
940            assert!(
941                self.token == Token::Comma,
942                "comma or closing bracket expected"
943            );
944            self.read_token();
945        }
946        if !self.b.parse_only {
947            let mut cols = lvec();
948            let table = c_table(&self.b, &tname);
949            for cname in &cnames {
950                if let Some(cnum) = table.info.colmap.get(*cname) {
951                    cols.push(*cnum);
952                } else {
953                    panic!("index column name not found {}", cname);
954                }
955            }
956            self.b
957                .dop(DO::CreateIndex(IndexInfo { tname, iname, cols }));
958        }
959    }
960
961    fn create_function(&mut self, alter: bool) {
962        let rref: ObjRef = self.obj_ref();
963        let source_start: usize = self.source_ix - 2;
964        let db = self.b.db.clone();
965        let save: Block = mem::replace(&mut self.b, Block::new(db));
966        let save2: bool = self.b.parse_only;
967        self.b.parse_only = true;
968        self.parse_function();
969        let _cb: Block = mem::replace(&mut self.b, save);
970        self.b.parse_only = save2;
971        if !self.b.parse_only {
972            let source: String = self.source_from(source_start, self.token_space_start);
973            self.b.dop(DO::CreateFunction(rref, Rc::new(source), alter));
974        }
975    }
976
977    fn s_create(&mut self) {
978        match self.id_ref() {
979            b"FN" => self.create_function(false),
980            b"TABLE" => self.create_table(),
981            b"SCHEMA" => {
982                let name = self.idb();
983                self.b.dop(DO::CreateSchema(name));
984            }
985            b"INDEX" => self.create_index(),
986            _ => panic!("CREATE : TABLE<FN.. expected"),
987        }
988    }
989
990    fn s_alter(&mut self) {
991        match self.id_ref() {
992            b"FN" => self.create_function(true),
993            b"TABLE" => self.s_alter_table(),
994            _ => panic!("ALTER : TABLE,FN.. expected"),
995        }
996    }
997
998    fn s_drop(&mut self) {
999        match self.id_ref() {
1000            b"TABLE" => {
1001                let tr = self.obj_ref();
1002                self.b.dop(DO::DropTable(tr));
1003            }
1004            b"INDEX" => {
1005                let ix = self.idb();
1006                self.read_id(b"ON");
1007                let tr = self.obj_ref();
1008                self.b.dop(DO::DropIndex(tr, ix));
1009            }
1010            b"FN" => {
1011                let fr = self.obj_ref();
1012                self.b.dop(DO::DropFunction(fr));
1013            }
1014            b"SCHEMA" => {
1015                let s = self.idb();
1016                self.b.dop(DO::DropSchema(s));
1017            }
1018            _ => {
1019                panic!("DROP : TABLE,FN .. expected");
1020            }
1021        }
1022    }
1023
1024    fn s_alter_table(&mut self) {
1025        let tr = self.obj_ref();
1026        let mut list = lvec();
1027        loop {
1028            if self.test_id(b"ADD") {
1029                let col = self.idb();
1030                let datatype = self.read_data_type();
1031                list.push(AlterCol::Add(col, datatype));
1032            } else if self.test_id(b"DROP") {
1033                let col = self.idb();
1034                list.push(AlterCol::Drop(col));
1035            } else if self.test_id(b"MODIFY") {
1036                let col = self.idb();
1037                let datatype = self.read_data_type();
1038                list.push(AlterCol::Modify(col, datatype));
1039            } else {
1040                break;
1041            }
1042            if !self.test(Token::Comma) {
1043                break;
1044            }
1045        }
1046        self.b.dop(DO::AlterTable(tr, list));
1047    }
1048
1049    // Other statements.
1050    fn s_declare(&mut self) {
1051        loop {
1052            let name = self.id_ref();
1053            let dt = self.read_data_type();
1054            self.b.def_local(name, dt);
1055            if !self.test(Token::Comma) {
1056                break;
1057            }
1058        }
1059    }
1060
1061    fn s_while(&mut self) {
1062        let mut exp = self.exp();
1063        let start_id = self.b.get_loop_id();
1064        let break_id = self.b.get_jump_id();
1065        if !self.b.parse_only {
1066            let exp = c_bool(&self.b, &mut exp);
1067            self.b.add(JumpIfFalse(break_id, exp));
1068            let save = self.b.break_id;
1069            self.b.break_id = break_id;
1070            self.statement();
1071            self.b.break_id = save;
1072            self.b.add(Jump(start_id));
1073            self.b.set_jump(break_id);
1074        }
1075    }
1076
1077    fn s_if(&mut self) {
1078        let mut exp = self.exp();
1079        let false_id = self.b.get_jump_id();
1080        if !self.b.parse_only {
1081            let exp = c_bool(&self.b, &mut exp);
1082            self.b.add(JumpIfFalse(false_id, exp));
1083        }
1084        self.statement();
1085        if self.test_id(b"ELSE") {
1086            let end_id = self.b.get_jump_id();
1087            self.b.add(Jump(end_id)); // Skip over the else clause
1088            self.b.set_jump(false_id);
1089            self.statement();
1090            self.b.set_jump(end_id);
1091        } else {
1092            self.b.set_jump(false_id);
1093        }
1094    }
1095
1096    fn s_goto(&mut self) {
1097        let label = self.id_ref();
1098        let to = self.b.get_goto_label(label);
1099        self.b.add(Jump(to));
1100    }
1101
1102    fn s_break(&mut self) {
1103        let break_id = self.b.break_id;
1104        assert!(break_id != usize::MAX, "no enclosing loop for break");
1105        self.b.add(Jump(break_id));
1106    }
1107
1108    fn s_return(&mut self) {
1109        if self.b.return_type != NONE {
1110            let mut e = self.exp();
1111            if !self.b.parse_only {
1112                let k = push(&mut self.b, &mut e);
1113                let rk = data_kind(self.b.return_type);
1114                assert!(k == rk, "return type mismatch expected {rk:?} got {k:?}");
1115                self.b.add(PopToLocal(self.b.param_count));
1116            }
1117        }
1118        self.b.add(Return);
1119    }
1120
1121    fn s_throw(&mut self) {
1122        let mut msg = self.exp();
1123        if !self.b.parse_only {
1124            push(&mut self.b, &mut msg);
1125            self.b.add(Throw);
1126        }
1127    }
1128
1129    fn s_begin(&mut self) {
1130        while !self.test_id(b"END") {
1131            self.statement();
1132        }
1133    }
1134} // end impl Parser
1135
1136/// Convert byte ref to &str.
1137pub fn tos(s: &[u8]) -> &str {
1138    str::from_utf8(s).unwrap()
1139}
1140
1141/// Convert byte ref to String.
1142pub fn to_s(s: &[u8]) -> String {
1143    str::from_utf8(s).unwrap().to_string()
1144}