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
11pub struct Parser<'a> {
19 pub b: Block<'a>,
21 pub function_name: Option<&'a ObjRef>,
23 source: &'a [u8],
25 source_ix: usize,
27 cc: u8,
29 token: Token,
31 token_start: usize,
33 token_space_start: usize,
35 cs: &'a [u8],
37 ts: String,
39 source_column: usize,
40 source_line: usize,
41 decimal_int: i64,
42 prev_source_column: usize,
44 prev_source_line: usize,
45}
46
47impl<'a> Parser<'a> {
48 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 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 } 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 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 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 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 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 {
177 self.source_column += 1;
178 }
179 self.source_ix += 1;
180 }
181 self.cc = cc;
182 cc
183 }
184
185 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 {
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 {
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 } self.token = token;
343 }
344
345 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 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 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 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 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 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 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 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 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 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 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); 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 {
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 fn exp(&mut self) -> Expr {
598 self.exp_p(0)
599 }
600
601 fn exp_p(&mut self, precedence: i8) -> Expr {
603 let pr = self.exp_primary();
604 self.exp_lp(pr, precedence)
605 }
606
607 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 {
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 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 Expr::new(ExprIs::ScalarSelect(tbox(te)))
646 }
647
648 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 } }
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 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 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 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 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)); 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} pub fn tos(s: &[u8]) -> &str {
1138 str::from_utf8(s).unwrap()
1139}
1140
1141pub fn to_s(s: &[u8]) -> String {
1143 str::from_utf8(s).unwrap().to_string()
1144}