Skip to main content

rustdb/
parse.rs

1use crate::alloc::{LVec, lbox, lvec, tbox, 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 id(&mut self) -> String {
402        to_s(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.id();
464        self.read(Token::Dot);
465        let name = self.id();
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 {
510                schema: to_s(name),
511                name: to_s(fname),
512            };
513            Expr::new(ExprIs::FuncCall(name, parms))
514        } else if self.test(Token::LBra) {
515            let mut parms = tvec();
516            if self.token != Token::RBra {
517                loop {
518                    parms.push(self.exp());
519                    if !self.test(Token::Comma) {
520                        break;
521                    }
522                }
523            }
524            self.read(Token::RBra);
525            Expr::new(ExprIs::BuiltinCall(to_s(name), parms))
526        } else if name == b"true" {
527            Expr::new(ExprIs::Const(Value::Bool(true)))
528        } else if name == b"false" {
529            Expr::new(ExprIs::Const(Value::Bool(false)))
530        } else if let Some(lnum) = self.b.get_local(name) {
531            Expr::new(ExprIs::Local(*lnum))
532        } else {
533            Expr::new(ExprIs::ColName(to_s(name)))
534        }
535    }
536
537    /// Parses a primary expression ( basic expression with no operators ).
538    fn exp_primary(&mut self) -> Expr {
539        let result;
540        if self.token == Token::Id {
541            result = if self.test_id(b"CASE") {
542                self.exp_case()
543            } else if self.test_id(b"NOT") {
544                let e = self.exp_p(10); // Not sure about precedence here.
545                Expr::new(ExprIs::Not(tbox(e)))
546            } else {
547                self.exp_id()
548            };
549        } else if self.test(Token::LBra) {
550            if self.test_id(b"SELECT") {
551                result = self.exp_scalar_select();
552            } else {
553                let exp = self.exp();
554                if self.test(Token::Comma)
555                // Operand of IN e.g. X IN ( 1,2,3 )
556                {
557                    let mut list = tvec();
558                    list.push(exp);
559                    loop {
560                        list.push(self.exp());
561                        if !self.test(Token::Comma) {
562                            break;
563                        }
564                    }
565                    result = Expr::new(ExprIs::List(list));
566                } else {
567                    result = exp;
568                }
569            }
570            self.read(Token::RBra);
571        } else if self.token == Token::String {
572            result = Expr::new(ExprIs::Const(Value::String(Rc::new(self.ts.clone()))));
573            self.read_token();
574        } else if self.token == Token::Number {
575            let value = self.decimal_int;
576            result = Expr::new(ExprIs::Const(Value::Int(value)));
577            self.read_token();
578        } else if self.token == Token::Hex {
579            assert!(
580                self.cs.len().is_multiple_of(2),
581                "hex literal must have even number of characters"
582            );
583            let hb = &self.source[self.token_start + 2..self.source_ix - 1];
584            result = Expr::new(ExprIs::Const(Value::RcBinary(Rc::new(util::parse_hex(hb)))));
585            self.read_token();
586        } else if self.test(Token::Minus) {
587            result = Expr::new(ExprIs::Minus(tbox(self.exp_p(30))));
588        } else {
589            panic!("expression expected")
590        }
591        result
592    }
593
594    fn exp_or_agg(&mut self) -> Expr {
595        let pri = self.exp_primary();
596        self.exp_lp(pri, 0)
597    }
598
599    /// Parse an expression.
600    fn exp(&mut self) -> Expr {
601        self.exp_p(0)
602    }
603
604    /// Parse an expression, with specified operator precedence.
605    fn exp_p(&mut self, precedence: i8) -> Expr {
606        let pr = self.exp_primary();
607        self.exp_lp(pr, precedence)
608    }
609
610    /// Apply binary operator to lhs based on precedence.
611    fn exp_lp(&mut self, mut lhs: Expr, precedence: i8) -> Expr {
612        let mut t = self.operator();
613        while t.1 >= precedence {
614            let op = t;
615            self.read_token();
616            let mut rhs = self.exp_primary();
617            t = self.operator();
618            while t.1 > op.1
619            /* or t is right-associative and t.1 == op.1 */
620            {
621                rhs = self.exp_lp(rhs, t.1);
622                t = self.operator();
623            }
624            lhs = Expr::new(ExprIs::Binary(op.0, tbox(lhs), tbox(rhs)));
625        }
626        lhs
627    }
628
629    /// Parse a CASE expression.
630    fn exp_case(&mut self) -> Expr {
631        let mut list = tvec();
632        while self.test_id(b"WHEN") {
633            let test = self.exp();
634            self.read_id(b"THEN");
635            let e = self.exp();
636            list.push((test, e));
637        }
638        assert!(!list.is_empty(), "empty CASE expression");
639        self.read_id(b"ELSE");
640        let els = tbox(self.exp());
641        self.read_id(b"END");
642        Expr::new(ExprIs::Case(list, els))
643    }
644
645    fn exp_scalar_select(&mut self) -> Expr {
646        let te = self.select_expression(false);
647        // if ( te.ColumnCount != 1 ) Error ( "Scalar select must have one column" );
648        Expr::new(ExprIs::ScalarSelect(tbox(te)))
649    }
650
651    // End Expression parsing
652
653    // ****************** Table expression parsing
654
655    fn insert_expression(&mut self, expect: usize) -> TableExpression {
656        self.read_id(b"VALUES");
657        let mut values = tvec();
658        while self.test(Token::LBra) {
659            let mut v = tvec();
660            loop {
661                v.push(self.exp());
662                if self.test(Token::RBra) {
663                    break;
664                }
665                assert!(
666                    self.token == Token::Comma,
667                    "comma or closing bracket expected"
668                );
669                self.read_token();
670            }
671            assert!(v.len() == expect, "wrong number of values");
672            values.push(v);
673            if !self.test(Token::Comma) && self.token != Token::LBra {
674                break;
675            } // The comma between multiple VALUES is optional.
676        }
677        TableExpression::Values(values)
678    }
679
680    fn te_named_table(&mut self) -> TableExpression {
681        let schema = self.id();
682        self.read(Token::Dot);
683        let name = self.id();
684        let name = ObjRef { schema, name };
685        TableExpression::Base(name)
686    }
687
688    fn primary_table_exp(&mut self) -> TableExpression {
689        assert!(self.token == Token::Id, "table name expected");
690        self.te_named_table()
691    }
692
693    fn exp_name(&self, exp: &Expr) -> String {
694        match &exp.exp {
695            ExprIs::Local(num) => to_s(self.b.local_name(*num)),
696            ExprIs::ColName(name) => name.to_string(),
697            _ => "".to_string(),
698        }
699    }
700
701    /// Parse a SELECT / SET / FOR expression.
702    fn select_expression(&mut self, set_or_for: bool) -> FromExpression {
703        let mut exps = tvec();
704        let mut colnames = lvec();
705        let mut assigns = lvec();
706        loop {
707            if set_or_for {
708                let local = self.local();
709                let op = match self.token {
710                    Token::Equal => AssignOp::Assign,
711                    Token::VBarEqual => AssignOp::Append,
712                    Token::PlusEqual => AssignOp::Inc,
713                    Token::MinusEqual => AssignOp::Dec,
714                    _ => panic!("assign operator expected"),
715                };
716                self.read_token();
717                assigns.push((local, op));
718            }
719            let exp = self.exp_or_agg();
720            if self.test_id(b"AS") {
721                colnames.push(self.id());
722            } else {
723                colnames.push(self.exp_name(&exp));
724            }
725            exps.push(exp);
726            if !self.test(Token::Comma) {
727                break;
728            }
729        }
730        let from = if self.test_id(b"FROM") {
731            Some(tbox(self.primary_table_exp()))
732        } else {
733            None
734        };
735        let wher = if self.test_id(b"WHERE") {
736            Some(self.exp())
737        } else {
738            None
739        };
740        let mut orderby = tvec();
741        if self.test_id(b"ORDER") {
742            self.read_id(b"BY");
743            loop {
744                let exp = self.exp();
745                let desc = if self.test_id(b"DESC") {
746                    true
747                } else {
748                    self.test_id(b"ASC");
749                    false
750                };
751                orderby.push((exp, desc));
752                if !self.test(Token::Comma) {
753                    break;
754                }
755            }
756        }
757        FromExpression {
758            colnames,
759            assigns,
760            exps,
761            from,
762            wher,
763            orderby,
764        }
765    }
766
767    // ****************** Statement parsing
768
769    fn s_select(&mut self) {
770        let se = self.select_expression(false);
771        if !self.b.parse_only {
772            let cte = c_select(&mut self.b, se);
773            self.b.add(Select(lbox(cte)));
774        }
775    }
776
777    fn s_set(&mut self) {
778        let se = self.select_expression(true);
779        if !self.b.parse_only {
780            c_set(&mut self.b, se);
781        }
782    }
783
784    fn s_insert(&mut self) {
785        self.read_id(b"INTO");
786        let tr = self.obj_ref();
787        self.read(Token::LBra);
788        let mut cnames = lvec();
789        loop {
790            let cname = self.id_ref();
791            assert!(!cnames.contains(&cname), "duplicate column name");
792            cnames.push(cname);
793            if self.test(Token::RBra) {
794                break;
795            }
796            assert!(self.test(Token::Comma), "comma or closing bracket expected");
797        }
798        let mut src = self.insert_expression(cnames.len());
799        if !self.b.parse_only {
800            let t = c_table(&self.b, &tr);
801            let mut cnums: LVec<usize> = lvec();
802            {
803                for cname in &cnames {
804                    if let Some(cnum) = t.info.get(tos(cname)) {
805                        cnums.push(*cnum);
806                    } else {
807                        panic!("column name '{}' not found", tos(cname))
808                    }
809                }
810            }
811            let csrc = c_te(&self.b, &mut src);
812            self.b.dop(DO::Insert(t, cnums, csrc));
813        }
814    }
815
816    fn s_update(&mut self) {
817        let tname = self.obj_ref();
818        self.read_id(b"SET");
819        let mut assigns = tvec();
820        loop {
821            let name = self.id();
822            self.read(Token::Equal);
823            let exp = self.exp();
824            assigns.push((name, exp));
825            if !self.test(Token::Comma) {
826                break;
827            }
828        }
829        assert!(self.test_id(b"WHERE"), "UPDATE must have a WHERE");
830        let mut wher = Some(self.exp());
831        if !self.b.parse_only {
832            c_update(&mut self.b, &tname, &mut assigns, &mut wher);
833        }
834    }
835
836    fn s_delete(&mut self) {
837        self.read_id(b"FROM");
838        let tname = self.obj_ref();
839        assert!(self.test_id(b"WHERE"), "DELETE must have a WHERE");
840        let mut wher = Some(self.exp());
841        if !self.b.parse_only {
842            c_delete(&mut self.b, &tname, &mut wher);
843        }
844    }
845
846    fn s_execute(&mut self) {
847        self.read(Token::LBra);
848        let mut exp = self.exp();
849        self.read(Token::RBra);
850        if !self.b.parse_only {
851            push(&mut self.b, &mut exp);
852            self.b.add(Execute);
853        }
854    }
855
856    fn s_check(&mut self) {
857        let name = self.obj_ref();
858        if !self.b.parse_only {
859            c_function(&self.b.db, &name);
860        }
861    }
862
863    fn s_exec(&mut self) {
864        let mut pname = self.id();
865        let mut sname = "".to_string();
866        if self.test(Token::Dot) {
867            sname = pname;
868            pname = self.id();
869        }
870        let name = ObjRef {
871            schema: sname,
872            name: pname,
873        };
874        self.read(Token::LBra);
875        let mut pkinds = tvec();
876        if !self.test(Token::RBra) {
877            let mut e = self.exp();
878            pkinds.push(push(&mut self.b, &mut e));
879            while self.test(Token::Comma) {
880                let mut e = self.exp();
881                pkinds.push(push(&mut self.b, &mut e));
882            }
883            self.read(Token::RBra);
884        }
885        if !self.b.parse_only {
886            let func = c_function(&self.b.db, &name);
887            assert!(
888                func.return_type == NONE,
889                "EXEC function cannot have a return type"
890            );
891            self.b.check_types(&func, &pkinds);
892            self.b.add(Call(func));
893        }
894    }
895
896    fn s_for(&mut self) {
897        let se: FromExpression = self.select_expression(true);
898        let for_id = self.b.local_typ.len();
899        self.b.local_typ.push(NONE);
900        let start_id = self.b.get_jump_id();
901        let break_id = self.b.get_jump_id();
902        if !self.b.parse_only {
903            c_for(&mut self.b, se, start_id, break_id, for_id);
904        }
905        let save = self.b.break_id;
906        self.b.break_id = break_id;
907        self.statement();
908        self.b.break_id = save;
909        self.b.add(Jump(start_id));
910        self.b.set_jump(break_id);
911    }
912
913    // ****************** Parse Create statements.
914
915    fn create_table(&mut self) {
916        let name = self.obj_ref();
917        let source_start = self.source_ix - 2;
918        self.read(Token::LBra);
919        let mut ti = ColInfo::empty(name);
920        while !self.test(Token::RBra) {
921            let cname = self.id();
922            let typ = self.read_data_type();
923            assert!(!ti.add(cname, typ), "duplicate column name");
924            self.test(Token::Comma);
925        }
926        if !self.b.parse_only {
927            let _source = self.source_from(source_start, self.token_start);
928            self.b.dop(DO::CreateTable(ti));
929        }
930    }
931
932    fn create_index(&mut self) {
933        let iname = self.id();
934        self.read_id(b"ON");
935        let tname = self.obj_ref();
936        self.read(Token::LBra);
937        let mut cnames = tvec();
938        loop {
939            cnames.push(self.id());
940            if self.test(Token::RBra) {
941                break;
942            }
943            assert!(
944                self.token == Token::Comma,
945                "comma or closing bracket expected"
946            );
947            self.read_token();
948        }
949        if !self.b.parse_only {
950            let mut cols = Vec::new();
951            let table = c_table(&self.b, &tname);
952            for cname in &cnames {
953                if let Some(cnum) = table.info.colmap.get(cname) {
954                    cols.push(*cnum);
955                } else {
956                    panic!("index column name not found {}", cname);
957                }
958            }
959            self.b
960                .dop(DO::CreateIndex(IndexInfo { tname, iname, cols }));
961        }
962    }
963
964    fn create_function(&mut self, alter: bool) {
965        let rref: ObjRef = self.obj_ref();
966        let source_start: usize = self.source_ix - 2;
967        let db = self.b.db.clone();
968        let save: Block = mem::replace(&mut self.b, Block::new(db));
969        let save2: bool = self.b.parse_only;
970        self.b.parse_only = true;
971        self.parse_function();
972        let _cb: Block = mem::replace(&mut self.b, save);
973        self.b.parse_only = save2;
974        if !self.b.parse_only {
975            let source: String = self.source_from(source_start, self.token_space_start);
976            self.b.dop(DO::CreateFunction(rref, Rc::new(source), alter));
977        }
978    }
979
980    fn s_create(&mut self) {
981        match self.id_ref() {
982            b"FN" => self.create_function(false),
983            b"TABLE" => self.create_table(),
984            b"SCHEMA" => {
985                let name = self.id();
986                self.b.dop(DO::CreateSchema(name));
987            }
988            b"INDEX" => self.create_index(),
989            _ => panic!("CREATE : TABLE<FN.. expected"),
990        }
991    }
992
993    fn s_alter(&mut self) {
994        match self.id_ref() {
995            b"FN" => self.create_function(true),
996            b"TABLE" => self.s_alter_table(),
997            _ => panic!("ALTER : TABLE,FN.. expected"),
998        }
999    }
1000
1001    fn s_drop(&mut self) {
1002        match self.id_ref() {
1003            b"TABLE" => {
1004                let tr = self.obj_ref();
1005                self.b.dop(DO::DropTable(tr));
1006            }
1007            b"INDEX" => {
1008                let ix = self.id();
1009                self.read_id(b"ON");
1010                let tr = self.obj_ref();
1011                self.b.dop(DO::DropIndex(tr, ix));
1012            }
1013            b"FN" => {
1014                let fr = self.obj_ref();
1015                self.b.dop(DO::DropFunction(fr));
1016            }
1017            b"SCHEMA" => {
1018                let s = self.id();
1019                self.b.dop(DO::DropSchema(s));
1020            }
1021            _ => {
1022                panic!("DROP : TABLE,FN .. expected");
1023            }
1024        }
1025    }
1026
1027    fn s_alter_table(&mut self) {
1028        let tr = self.obj_ref();
1029        let mut list = lvec();
1030        loop {
1031            if self.test_id(b"ADD") {
1032                let col = self.id();
1033                let datatype = self.read_data_type();
1034                list.push(AlterCol::Add(col, datatype));
1035            } else if self.test_id(b"DROP") {
1036                let col = self.id();
1037                list.push(AlterCol::Drop(col));
1038            } else if self.test_id(b"MODIFY") {
1039                let col = self.id();
1040                let datatype = self.read_data_type();
1041                list.push(AlterCol::Modify(col, datatype));
1042            } else {
1043                break;
1044            }
1045            if !self.test(Token::Comma) {
1046                break;
1047            }
1048        }
1049        self.b.dop(DO::AlterTable(tr, list));
1050    }
1051
1052    // Other statements.
1053    fn s_declare(&mut self) {
1054        loop {
1055            let name = self.id_ref();
1056            let dt = self.read_data_type();
1057            self.b.def_local(name, dt);
1058            if !self.test(Token::Comma) {
1059                break;
1060            }
1061        }
1062    }
1063
1064    fn s_while(&mut self) {
1065        let mut exp = self.exp();
1066        let start_id = self.b.get_loop_id();
1067        let break_id = self.b.get_jump_id();
1068        if !self.b.parse_only {
1069            let exp = c_bool(&self.b, &mut exp);
1070            self.b.add(JumpIfFalse(break_id, exp));
1071            let save = self.b.break_id;
1072            self.b.break_id = break_id;
1073            self.statement();
1074            self.b.break_id = save;
1075            self.b.add(Jump(start_id));
1076            self.b.set_jump(break_id);
1077        }
1078    }
1079
1080    fn s_if(&mut self) {
1081        let mut exp = self.exp();
1082        let false_id = self.b.get_jump_id();
1083        if !self.b.parse_only {
1084            let exp = c_bool(&self.b, &mut exp);
1085            self.b.add(JumpIfFalse(false_id, exp));
1086        }
1087        self.statement();
1088        if self.test_id(b"ELSE") {
1089            let end_id = self.b.get_jump_id();
1090            self.b.add(Jump(end_id)); // Skip over the else clause
1091            self.b.set_jump(false_id);
1092            self.statement();
1093            self.b.set_jump(end_id);
1094        } else {
1095            self.b.set_jump(false_id);
1096        }
1097    }
1098
1099    fn s_goto(&mut self) {
1100        let label = self.id_ref();
1101        let to = self.b.get_goto_label(label);
1102        self.b.add(Jump(to));
1103    }
1104
1105    fn s_break(&mut self) {
1106        let break_id = self.b.break_id;
1107        assert!(break_id != usize::MAX, "no enclosing loop for break");
1108        self.b.add(Jump(break_id));
1109    }
1110
1111    fn s_return(&mut self) {
1112        if self.b.return_type != NONE {
1113            let mut e = self.exp();
1114            if !self.b.parse_only {
1115                let k = push(&mut self.b, &mut e);
1116                let rk = data_kind(self.b.return_type);
1117                assert!(k == rk, "return type mismatch expected {rk:?} got {k:?}");
1118                self.b.add(PopToLocal(self.b.param_count));
1119            }
1120        }
1121        self.b.add(Return);
1122    }
1123
1124    fn s_throw(&mut self) {
1125        let mut msg = self.exp();
1126        if !self.b.parse_only {
1127            push(&mut self.b, &mut msg);
1128            self.b.add(Throw);
1129        }
1130    }
1131
1132    fn s_begin(&mut self) {
1133        while !self.test_id(b"END") {
1134            self.statement();
1135        }
1136    }
1137} // end impl Parser
1138
1139/// Convert byte ref to &str.
1140pub fn tos(s: &[u8]) -> &str {
1141    str::from_utf8(s).unwrap()
1142}
1143
1144/// Convert byte ref to String.
1145pub fn to_s(s: &[u8]) -> String {
1146    str::from_utf8(s).unwrap().to_string()
1147}