1use crate::*;
2use Instruction::{DataOp, ForNext, ForSortNext, Jump, JumpIfFalse};
3
4#[derive(Clone)]
6pub(crate) struct SqlError {
7 pub rname: String,
8 pub line: usize,
9 pub column: usize,
10 pub msg: String,
11}
12pub enum TableExpression {
14 Base(ObjRef),
16 Values(Vec<Vec<Expr>>),
18}
19#[derive(Clone, Copy)]
21#[non_exhaustive]
22pub enum AssignOp {
23 Assign,
25 Append,
27 Inc,
29 Dec,
31}
32pub type Assigns = Vec<(usize, AssignOp)>;
34
35#[non_exhaustive]
37pub struct FromExpression {
38 pub colnames: Vec<String>,
40 pub assigns: Assigns,
42 pub exps: Vec<Expr>,
44 pub from: Option<Box<TableExpression>>,
46 pub wher: Option<Expr>,
48 pub orderby: Vec<(Expr, bool)>,
50}
51
52#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
54pub enum Token {
55 Less,
58 LessEqual,
60 GreaterEqual,
62 Greater,
64 Equal,
66 NotEqual,
68 In,
70 Plus,
72 Minus,
74 Times,
76 Divide,
78 Percent,
80 VBar,
82 And,
84 Or,
86 VBarEqual,
88 PlusEqual,
90 MinusEqual,
92 Id,
94 Number,
96 Hex,
98 String,
100 LBra,
102 RBra,
104 Comma,
106 Colon,
108 Dot,
110 Exclamation,
112 Unknown,
114 EndOfFile,
116}
117
118impl Token {
119 pub fn precedence(self) -> i8 {
121 const PA: [i8; 15] = [10, 10, 10, 10, 10, 10, 10, 20, 20, 30, 30, 30, 15, 8, 5];
122 PA[self as usize]
123 }
124}
125
126#[non_exhaustive]
128pub struct Expr {
129 pub exp: ExprIs,
131 pub data_type: DataType,
133 pub is_constant: bool,
135 pub checked: bool,
137 pub col: usize,
139}
140
141impl Expr {
142 pub fn new(exp: ExprIs) -> Self {
144 Expr {
145 exp,
146 data_type: NONE,
147 is_constant: false,
148 checked: false,
149 col: 0,
150 }
151 }
152}
153
154#[non_exhaustive]
156pub enum ExprIs {
157 Const(Value),
159 Local(usize),
161 ColName(String),
163 Binary(Token, Box<Expr>, Box<Expr>),
165 Not(Box<Expr>),
167 Minus(Box<Expr>),
169 Case(Vec<(Expr, Expr)>, Box<Expr>),
171 FuncCall(ObjRef, Vec<Expr>),
173 BuiltinCall(String, Vec<Expr>),
175 ScalarSelect(Box<FromExpression>),
177 List(Vec<Expr>),
179}
180
181#[derive(PartialEq, PartialOrd, Eq, Hash, Clone)]
183#[non_exhaustive]
184pub struct ObjRef {
185 pub schema: String,
187 pub name: String,
189}
190
191impl ObjRef {
192 pub fn new(s: &str, n: &str) -> Self {
194 Self {
195 schema: s.to_string(),
196 name: n.to_string(),
197 }
198 }
199 pub fn str(&self) -> String {
201 format!("[{}].[{}]", &self.schema, &self.name)
202 }
203}
204
205#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
207#[non_exhaustive]
208pub enum DataKind {
209 None = 0,
211 Binary = 1,
213 String = 2,
215 Int = 3,
217 Float = 4,
219 Bool = 5,
221}
222
223pub type DataType = usize;
225
226pub(crate) const KBITS: usize = 3;
227pub(crate) const NONE: DataType = DataKind::None as usize;
228pub(crate) const BINARY: DataType = DataKind::Binary as usize + (16 << KBITS);
229pub(crate) const STRING: DataType = DataKind::String as usize + (16 << KBITS);
230pub(crate) const NAMESTR: DataType = DataKind::String as usize + (32 << KBITS);
231pub(crate) const BIGSTR: DataType = DataKind::String as usize + (250 << KBITS);
232pub(crate) const INT: DataType = DataKind::Int as usize + (8 << KBITS);
233pub(crate) const FLOAT: DataType = DataKind::Float as usize + (4 << KBITS);
234pub(crate) const DOUBLE: DataType = DataKind::Float as usize + (8 << KBITS);
235pub(crate) const BOOL: DataType = DataKind::Bool as usize + (1 << KBITS);
236
237pub fn data_kind(x: DataType) -> DataKind {
239 const DKLOOK: [DataKind; 6] = [
240 DataKind::None,
241 DataKind::Binary,
242 DataKind::String,
243 DataKind::Int,
244 DataKind::Float,
245 DataKind::Bool,
246 ];
247 DKLOOK[x % (1 << KBITS)]
248}
249
250#[must_use]
252pub fn data_size(x: DataType) -> usize {
253 x >> KBITS
254}
255
256pub struct Block<'a> {
258 pub param_count: usize,
260 pub return_type: DataType,
262 pub local_typ: Vec<DataType>,
264 pub ilist: Vec<Instruction>,
266 pub break_id: usize,
268 pub db: DB,
270 pub from: Option<CTableExpression>,
272 pub parse_only: bool,
274 jumps: Vec<usize>,
276 labels: HashMap<&'a [u8], usize>,
278 local_map: HashMap<&'a [u8], usize>,
280 locals: Vec<&'a [u8]>,
282}
283
284impl<'a> Block<'a> {
285 pub fn new(db: DB) -> Self {
287 Block {
288 ilist: Vec::new(),
289 jumps: Vec::new(),
290 labels: HashMap::default(),
291 local_map: HashMap::default(),
292 locals: Vec::new(),
293 local_typ: Vec::new(),
294 break_id: 0,
295 param_count: 0,
296 return_type: NONE,
297 from: None,
298 db,
299 parse_only: false,
300 }
301 }
302
303 pub fn resolve_jumps(&mut self) {
305 for (k, v) in &self.labels {
306 if self.jumps[*v] == usize::MAX {
307 panic!("undefined label: {}", parse::tos(k));
308 }
309 }
310 for i in &mut self.ilist {
311 match i {
312 JumpIfFalse(x, _) | Jump(x) | ForNext(x, _) | ForSortNext(x, _) => {
313 *x = self.jumps[*x]
314 }
315 _ => {}
316 }
317 }
318 }
319
320 pub fn add(&mut self, s: Instruction) {
322 if !self.parse_only {
323 self.ilist.push(s);
324 }
325 }
326
327 pub fn dop(&mut self, dop: DO) {
329 if !self.parse_only {
330 self.add(DataOp(Box::new(dop)));
331 }
332 }
333
334 pub fn check_types(&self, r: &Rc<Function>, pkinds: &[DataKind]) {
336 if pkinds.len() != r.param_count {
337 panic!("param count mismatch");
338 }
339 for (i, pk) in pkinds.iter().enumerate() {
340 let ft = data_kind(r.local_typ[i]);
341 let et = *pk;
342 if ft != et {
343 panic!("param type mismatch expected {:?} got {:?}", ft, et);
344 }
345 }
346 }
347
348 pub fn def_local(&mut self, name: &'a [u8], dt: DataType) {
352 let local_id = self.local_typ.len();
353 self.local_typ.push(dt);
354 self.locals.push(name);
355 if self.local_map.contains_key(name) {
356 panic!("duplicate variable name");
357 }
358 self.local_map.insert(name, local_id);
359 }
360
361 pub fn get_local(&self, name: &[u8]) -> Option<&usize> {
363 self.local_map.get(name)
364 }
365
366 pub fn local_name(&self, num: usize) -> &[u8] {
368 self.locals[num]
369 }
370
371 pub fn get_jump_id(&mut self) -> usize {
373 let result = self.jumps.len();
374 self.jumps.push(usize::MAX);
375 result
376 }
377
378 pub fn set_jump(&mut self, jump_id: usize) {
380 self.jumps[jump_id] = self.ilist.len();
381 }
382
383 pub fn get_loop_id(&mut self) -> usize {
385 let result = self.get_jump_id();
386 self.set_jump(result);
387 result
388 }
389
390 pub fn get_goto_label(&mut self, s: &'a [u8]) -> usize {
392 if let Some(jump_id) = self.labels.get(s) {
393 *jump_id
394 } else {
395 let jump_id = self.get_jump_id();
396 self.labels.insert(s, jump_id);
397 jump_id
398 }
399 }
400
401 pub fn set_goto_label(&mut self, s: &'a [u8]) {
403 if let Some(jump_id) = self.labels.get(s) {
404 let j = *jump_id;
405 if self.jumps[j] != usize::MAX {
406 panic!("label already set");
407 }
408 self.set_jump(j);
409 } else {
410 let jump_id = self.get_loop_id();
411 self.labels.insert(s, jump_id);
412 }
413 }
414
415 pub fn kind(&self, e: &mut Expr) -> DataKind {
417 compile::c_check(self, e);
418 data_kind(e.data_type)
419 }
420}