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
10pub struct Parser<'a> {
18 pub b: Block<'a>,
20 pub function_name: Option<&'a ObjRef>,
22 source: &'a [u8],
24 source_ix: usize,
26 cc: u8,
28 token: Token,
30 token_start: usize,
32 token_space_start: usize,
34 cs: &'a [u8],
36 ts: String,
38 source_column: usize,
39 source_line: usize,
40 decimal_int: i64,
41 prev_source_column: usize,
43 prev_source_line: usize,
44}
45
46impl<'a> Parser<'a> {
47 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 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 } 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 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 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 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 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 {
176 self.source_column += 1;
177 }
178 self.source_ix += 1;
179 }
180 self.cc = cc;
181 cc
182 }
183
184 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 {
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 {
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 } self.token = token;
342 }
343
344 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 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 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 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 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 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 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 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 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 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 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); 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 {
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 fn exp(&mut self) -> Expr {
599 self.exp_p(0)
600 }
601
602 fn exp_p(&mut self, precedence: i8) -> Expr {
604 let pr = self.exp_primary();
605 self.exp_lp(pr, precedence)
606 }
607
608 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 {
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 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 Expr::new(ExprIs::ScalarSelect(Box::new(te)))
647 }
648
649 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 } }
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 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 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 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 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)); 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} pub fn tos(s: &[u8]) -> &str {
1139 str::from_utf8(s).unwrap()
1140}
1141
1142pub fn to_s(s: &[u8]) -> String {
1144 str::from_utf8(s).unwrap().to_string()
1145}