1use crate::alloc::{LBox, LHashMap, LRc, LVec, TBox, TVec, lbox, lboxstr, lhashmap, lvec};
2use crate::*;
3use Instruction::{DataOp, ForNext, ForSortNext, Jump, JumpIfFalse};
4
5#[derive(Clone)]
7pub(crate) struct SqlError {
8 pub rname: String,
9 pub line: usize,
10 pub column: usize,
11 pub msg: String,
12}
13pub enum TableExpression {
15 Base(ObjRef),
17 Values(TVec<TVec<Expr>>),
19}
20#[derive(Clone, Copy)]
22#[non_exhaustive]
23pub enum AssignOp {
24 Assign,
26 Append,
28 Inc,
30 Dec,
32}
33pub type Assigns = LVec<(usize, AssignOp)>;
35
36#[non_exhaustive]
38pub struct FromExpression {
39 pub colnames: LVec<LBox<str>>,
41 pub assigns: Assigns,
43 pub exps: TVec<Expr>,
45 pub from: Option<TBox<TableExpression>>,
47 pub wher: Option<Expr>,
49 pub orderby: TVec<(Expr, bool)>,
51}
52
53#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
55pub enum Token {
56 Less,
59 LessEqual,
61 GreaterEqual,
63 Greater,
65 Equal,
67 NotEqual,
69 In,
71 Plus,
73 Minus,
75 Times,
77 Divide,
79 Percent,
81 VBar,
83 And,
85 Or,
87 VBarEqual,
89 PlusEqual,
91 MinusEqual,
93 Id,
95 Number,
97 Hex,
99 String,
101 LBra,
103 RBra,
105 Comma,
107 Colon,
109 Dot,
111 Exclamation,
113 Unknown,
115 EndOfFile,
117}
118
119impl Token {
120 pub fn precedence(self) -> i8 {
122 const PA: [i8; 15] = [10, 10, 10, 10, 10, 10, 10, 20, 20, 30, 30, 30, 15, 8, 5];
123 PA[self as usize]
124 }
125}
126
127#[non_exhaustive]
129pub struct Expr {
130 pub exp: ExprIs,
132 pub data_type: DataType,
134 pub is_constant: bool,
136 pub checked: bool,
138 pub col: usize,
140}
141
142impl Expr {
143 pub fn new(exp: ExprIs) -> Self {
145 Expr {
146 exp,
147 data_type: NONE,
148 is_constant: false,
149 checked: false,
150 col: 0,
151 }
152 }
153}
154
155#[non_exhaustive]
157pub enum ExprIs {
158 Const(Value),
160 Local(usize),
162 ColName(LBox<str>),
164 Binary(Token, TBox<Expr>, TBox<Expr>),
166 Not(TBox<Expr>),
168 Minus(TBox<Expr>),
170 Case(TVec<(Expr, Expr)>, TBox<Expr>),
172 FuncCall(ObjRef, TVec<Expr>),
174 BuiltinCall(TBox<str>, TVec<Expr>), ScalarSelect(TBox<FromExpression>),
178 List(TVec<Expr>),
180}
181
182#[derive(PartialEq, PartialOrd, Eq, Hash, Clone)]
184#[non_exhaustive]
185pub struct ObjRef {
186 pub schema: LBox<str>,
188 pub name: LBox<str>,
190}
191
192impl ObjRef {
193 pub fn new(s: &str, n: &str) -> Self {
195 Self {
196 schema: lboxstr(s),
197 name: lboxstr(n),
198 }
199 }
200 pub fn str(&self) -> String {
202 format!("[{}].[{}]", &self.schema, &self.name)
203 }
204}
205
206#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
208#[non_exhaustive]
209pub enum DataKind {
210 None = 0,
212 Binary = 1,
214 String = 2,
216 Int = 3,
218 Float = 4,
220 Bool = 5,
222}
223
224pub type DataType = usize;
226
227pub(crate) const KBITS: usize = 3;
228pub(crate) const NONE: DataType = DataKind::None as usize;
229pub(crate) const BINARY: DataType = DataKind::Binary as usize + (16 << KBITS);
230pub(crate) const STRING: DataType = DataKind::String as usize + (16 << KBITS);
231pub(crate) const NAMESTR: DataType = DataKind::String as usize + (32 << KBITS);
232pub(crate) const BIGSTR: DataType = DataKind::String as usize + (250 << KBITS);
233pub(crate) const INT: DataType = DataKind::Int as usize + (8 << KBITS);
234pub(crate) const FLOAT: DataType = DataKind::Float as usize + (4 << KBITS);
235pub(crate) const DOUBLE: DataType = DataKind::Float as usize + (8 << KBITS);
236pub(crate) const BOOL: DataType = DataKind::Bool as usize + (1 << KBITS);
237
238pub fn data_kind(x: DataType) -> DataKind {
240 const DKLOOK: [DataKind; 6] = [
241 DataKind::None,
242 DataKind::Binary,
243 DataKind::String,
244 DataKind::Int,
245 DataKind::Float,
246 DataKind::Bool,
247 ];
248 DKLOOK[x % (1 << KBITS)]
249}
250
251#[must_use]
253pub fn data_size(x: DataType) -> usize {
254 x >> KBITS
255}
256
257pub struct Block<'a> {
259 pub param_count: usize,
261 pub return_type: DataType,
263 pub local_typ: LVec<DataType>,
265 pub ilist: LVec<Instruction>,
267 pub break_id: usize,
269 pub db: DB,
271 pub from: Option<CTableExpression>,
273 pub parse_only: bool,
275 jumps: LVec<usize>,
277 labels: LHashMap<&'a [u8], usize>,
279 local_map: LHashMap<&'a [u8], usize>,
281 locals: LVec<&'a [u8]>,
283}
284
285impl<'a> Block<'a> {
286 pub fn new(db: DB) -> Self {
288 Block {
289 ilist: lvec(),
290 jumps: lvec(),
291 labels: lhashmap(),
292 local_map: lhashmap(),
293 locals: lvec(),
294 local_typ: lvec(),
295 break_id: 0,
296 param_count: 0,
297 return_type: NONE,
298 from: None,
299 db,
300 parse_only: false,
301 }
302 }
303
304 pub fn resolve_jumps(&mut self) {
306 for (k, v) in &self.labels {
307 if self.jumps[*v] == usize::MAX {
308 panic!("undefined label: {}", parse::tos(k));
309 }
310 }
311 for i in &mut self.ilist {
312 match i {
313 JumpIfFalse(x, _) | Jump(x) | ForNext(x, _) | ForSortNext(x, _) => {
314 *x = self.jumps[*x]
315 }
316 _ => {}
317 }
318 }
319 }
320
321 pub fn add(&mut self, s: Instruction) {
323 if !self.parse_only {
324 self.ilist.push(s);
325 }
326 }
327
328 pub fn dop(&mut self, dop: DO) {
330 if !self.parse_only {
331 self.add(DataOp(lbox(dop)));
332 }
333 }
334
335 pub fn check_types(&self, r: &LRc<Function>, pkinds: &[DataKind]) {
337 if pkinds.len() != r.param_count {
338 panic!("param count mismatch");
339 }
340 for (i, pk) in pkinds.iter().enumerate() {
341 let ft = data_kind(r.local_typ[i]);
342 let et = *pk;
343 if ft != et {
344 panic!("param type mismatch expected {:?} got {:?}", ft, et);
345 }
346 }
347 }
348
349 pub fn def_local(&mut self, name: &'a [u8], dt: DataType) {
353 let local_id = self.local_typ.len();
354 self.local_typ.push(dt);
355 self.locals.push(name);
356 if self.local_map.contains_key(name) {
357 panic!("duplicate variable name");
358 }
359 self.local_map.insert(name, local_id);
360 }
361
362 pub fn get_local(&self, name: &[u8]) -> Option<&usize> {
364 self.local_map.get(name)
365 }
366
367 pub fn local_name(&self, num: usize) -> &[u8] {
369 self.locals[num]
370 }
371
372 pub fn get_jump_id(&mut self) -> usize {
374 let result = self.jumps.len();
375 self.jumps.push(usize::MAX);
376 result
377 }
378
379 pub fn set_jump(&mut self, jump_id: usize) {
381 self.jumps[jump_id] = self.ilist.len();
382 }
383
384 pub fn get_loop_id(&mut self) -> usize {
386 let result = self.get_jump_id();
387 self.set_jump(result);
388 result
389 }
390
391 pub fn get_goto_label(&mut self, s: &'a [u8]) -> usize {
393 if let Some(jump_id) = self.labels.get(s) {
394 *jump_id
395 } else {
396 let jump_id = self.get_jump_id();
397 self.labels.insert(s, jump_id);
398 jump_id
399 }
400 }
401
402 pub fn set_goto_label(&mut self, s: &'a [u8]) {
404 if let Some(jump_id) = self.labels.get(s) {
405 let j = *jump_id;
406 if self.jumps[j] != usize::MAX {
407 panic!("label already set");
408 }
409 self.set_jump(j);
410 } else {
411 let jump_id = self.get_loop_id();
412 self.labels.insert(s, jump_id);
413 }
414 }
415
416 pub fn kind(&self, e: &mut Expr) -> DataKind {
418 compile::c_check(self, e);
419 data_kind(e.data_type)
420 }
421}