Browse Source

Remove LIMIT and ORDER BY from the language

Cesar Rodas 9 months ago
parent
commit
4e44587154

+ 1 - 1
utxo/src/filter_expr/compiler/mod.rs

@@ -144,7 +144,7 @@ impl<'a> Compiler<'a> {
             optimizations::calculate_static_values,
             optimizations::remove_useless_jumps,
             optimizations::remove_dead_code,
-            //optimizations::move_load_top,
+            optimizations::move_load_top,
         ]
         .into_iter()
         .fold((opcodes, false), |(opcodes, has_optimized), f| {

+ 3 - 8
utxo/src/filter_expr/expr.pest

@@ -1,13 +1,8 @@
 COMMENT    = { "//" ~ (!NEWLINE ~ ANY)* ~ NEWLINE }
 WHITESPACE = _{ " " | "\t" | NEWLINE }
 
-query       = _{ SOI ~ where_clause? ~ limit_clause? ~ order_by_clause? ~ EOI }
-where_clause = { ^"WHERE" ~ expr }
-limit_clause = { ^"LIMIT" ~ number }
-order_by_clause = { ^"ORDER" ~ ^"BY" ~  variable ~ order }
-
-order       = { ^"ASC" | ^"DESC" }
-expr        = _{ logical_expr }
+init         = _{ SOI ~ expr ~ EOI }
+expr         = { logical_expr }
 logical_expr = { logical_term ~ (logical_op ~ logical_term)* }
 logical_term = { not_expr | comparison }
 logical_op   = { ^"AND" |  "&&" | "||" | ^"OR" }
@@ -15,7 +10,7 @@ not_expr     = { (^"NOT" | "!") ~ logical_expr }
 comparison   = { sum ~ (comp_op ~ sum)? }
 sum          = { product ~ (add_op ~ product)* }
 product      = { factor ~ (mul_op ~ factor)* }
-factor       = { number | string | variable  | bool | "(" ~ expr ~ ")" }
+factor       = { number | string | variable  | bool | "(" ~ logical_expr ~ ")" }
 comp_op      = { "=" | "!=" | "<" | "<=" | ">" | ">=" }
 add_op       = { "+" | "-" }
 mul_op       = { "*" | "/" }

+ 6 - 20
utxo/src/filter_expr/filter.rs

@@ -2,7 +2,7 @@ use super::{
     compiler::Compiler,
     expr::{Expr, ExprOp, Variable},
     opcode::OpCode,
-    parser::{parse_query, Query},
+    parser::parse,
     runtime::execute,
     value::{Value, ValueOrRef},
     Addr, Error, Register,
@@ -13,7 +13,7 @@ use std::collections::HashMap;
 #[derive(Debug, Clone)]
 pub struct Filter<'a> {
     /// Query
-    query: Query,
+    expr: Option<Expr>,
     /// List of external variables
     variables: Vec<Variable>,
     /// Unoptimized opcodes
@@ -29,8 +29,8 @@ pub struct Filter<'a> {
 
 impl<'a> Filter<'a> {
     pub fn new(code: &str) -> Result<Self, Error> {
-        let query = parse_query(code)?;
-        let opcodes = query.where_clause.as_ref().map_or_else(
+        let expr = parse(code)?;
+        let opcodes = expr.as_ref().map_or_else(
             || {
                 Ok(vec![
                     OpCode::LOAD(0.into(), true.into()),
@@ -41,7 +41,7 @@ impl<'a> Filter<'a> {
         )?;
 
         let instance = Self {
-            query,
+            expr,
             dbg_opcodes: opcodes.clone(),
             opcodes: opcodes.clone(),
             variables: opcodes
@@ -71,21 +71,7 @@ impl<'a> Filter<'a> {
 
         self.opcodes = new_opcodes;
         self.initial_register.clear();
-        self.opcodes_to_execute = Compiler::resolve_label_to_addr(
-            self.opcodes.clone(), /*
-                                  self.opcodes
-                                      .iter()
-                                      .filter_map(|opcode| match opcode {
-                                          OpCode::LOAD(addr, value) => {
-                                              self.initial_register
-                                                  .insert(*addr, ValueOrRef::Value(value.clone()));
-                                              None
-                                          }
-                                          _ => Some(opcode.clone()),
-                                      })
-                                      .collect::<Vec<_>>()*/
-        )
-        .unwrap();
+        self.opcodes_to_execute = Compiler::resolve_label_to_addr(self.opcodes.clone()).unwrap();
         self
     }
 

+ 6 - 51
utxo/src/filter_expr/parser.rs

@@ -10,13 +10,6 @@ use std::str::FromStr;
 #[grammar = "src/filter_expr/expr.pest"] // relative path to your .pest file
 struct QueryParser;
 
-#[derive(Debug, Clone)]
-pub struct Query {
-    pub where_clause: Option<Expr>,
-    pub limit_clause: Option<i128>,
-    pub order_by_clause: Option<(Variable, Order)>,
-}
-
 /// Borrowed from https://github.com/pest-parser/pest/blob/master/meta/src/parser.rs#L687C2-L741C2
 fn unescape(string: &str) -> Option<String> {
     let mut result = String::new();
@@ -139,65 +132,27 @@ fn parse_expr(pair: pest::iterators::Pair<Rule>) -> Result<Expr, Error> {
 }
 
 /// Parses a string a returns a result wrappign a Query struct
-pub fn parse_query(query: &str) -> Result<Query, Error> {
-    let pairs = QueryParser::parse(Rule::query, query)?;
-
-    let mut where_clause = None;
-    let mut limit_clause = None;
-    let mut order_by_clause = None;
+pub fn parse(query: &str) -> Result<Option<Expr>, Error> {
+    let pairs = QueryParser::parse(Rule::init, query)?;
 
     for pair in pairs {
         match pair.as_rule() {
             Rule::EOI => {
                 break;
             }
-            Rule::where_clause => {
-                where_clause = Some(
+            Rule::expr => {
+                return Ok(Some(
                     pair.into_inner()
                         .next()
                         .map(parse_expr)
                         .ok_or(Error::MissingNextRule)??
                         .rearrange_expression(),
-                );
-            }
-            Rule::limit_clause => {
-                limit_clause = match pair
-                    .into_inner()
-                    .next()
-                    .map(parse_expr)
-                    .ok_or(Error::MissingNextRule)??
-                {
-                    Expr::Number(v) => Some(v),
-                    _ => unreachable!(),
-                };
-            }
-            Rule::order_by_clause => {
-                let mut iter = pair.into_inner();
-                let expr = match iter
-                    .next()
-                    .map(parse_expr)
-                    .ok_or(Error::MissingNextRule)??
-                {
-                    Expr::Variable(variable) => variable,
-                    _ => unreachable!(),
-                };
-
-                let order = if let Some(order_by_text) = iter.next() {
-                    order_by_text.as_str().parse()?
-                } else {
-                    Order::Ascending
-                };
-
-                order_by_clause = Some((expr, order));
+                ));
             }
             Rule::COMMENT => {}
             _ => unreachable!(),
         }
     }
 
-    Ok(Query {
-        where_clause,
-        limit_clause,
-        order_by_clause,
-    })
+    Ok(None)
 }

+ 6 - 7
utxo/src/filter_expr/tests/always_true.expr

@@ -2,10 +2,9 @@
 /// because the cheaper expression is always true (1 = 1) which is evaluated at compile time, since
 /// the expression is an OR, the whole expression is true and it makes no further sense to continue
 /// evaluating
-WHERE
-    (
-        $foo = 3 + 2 * 4 / 2 * 298210 + $bar
-        AND 25 = 5*$five
-    )
-    OR false
-    OR  1 = 1
+(
+    $foo = 3 + 2 * 4 / 2 * 298210 + $bar
+    AND 25 = 5*$five
+)
+OR false
+OR  1 = 1

+ 1 - 3
utxo/src/filter_expr/tests/nested.expr

@@ -1,3 +1 @@
-WHERE
-    $foo = 3 + 2 * 4 / 2 * 298210 + $bar
-    AND 25+1-1 = 5*$five
+$foo = 3 + 2 * 4 / 2 * 298210 + $bar AND 25 * 27 / 3/ 3 /3 = 5*$five

+ 1 - 4
utxo/src/filter_expr/tests/program1.expr

@@ -1,4 +1 @@
-WHERE
-    5 + 1 = $external + 1
-    AND 5 = $external
-LIMIT 5
+5 + 1 = $external + 1 AND 5 = $external