Skip to main content

rustdb/
parse.rs

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