<commit_before>//!
//! Interpreter Compiler for Expressions
//!

use common::constant::VECTOR_SIZE;
use common::err::{Error, TResult, Void, void_ok};
use eval::{Eval, MapEval};
use expr::{Datum, Expr, Visitor};
use rows::RowBlock;
use rows::vector::{Vector, as_mut_array, as_array};
use schema::{Column, Schema};
use std::boxed::Box;
use std::ops;
use types::{DataTy, HasDataTy, HasTy, result_data_ty, Ty};

// Unary Expressions
pub struct Not {child: Box<Eval>}
pub struct IsNull {child: Box<Eval>}

// Binary Comparison Expressions
pub struct And {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Or {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Equal {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct NotEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}

// Binary Arithmetic Evalessions
pub struct Plus {data_ty: DataTy, pub lhs: Box<MapEval>, pub rhs: Box<MapEval>}
pub struct Minus {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Multiply {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Divide {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Modular {lhs: Box<Eval>, rhs: Box<Eval>}

// String operators or pattern matching predicates
pub struct Concatenate {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Like {pattern: String, child: Box<Eval>}
pub struct SimilarTo {pattern: String, child: Box<Eval>}
pub struct RegexMatch {pattern: String, child: Box<Eval>}

pub struct Between {pred: Box<Eval>, begin: Box<Eval>, end: Box<Eval>}
pub struct In {pred: Box<Eval>, row: Box<Row>}

pub struct Row {values: Vec<Box<Eval>>}
pub struct Field {column: Column, field_id: Option<usize>}
pub struct Const {datum: Datum, res_type: DataTy}


impl Eval for Plus {
  fn bind(&mut self, schema: &Schema) -> Void {
    self.data_ty = result_data_ty(self.lhs.data_ty(), self.rhs.data_ty());
    void_ok()
  }  
  
  fn is_const(&self) -> bool { false }
}

impl MapEval for Plus {
  fn eval(&self, r: &RowBlock) -> TResult<&Vector> {
    let l: &Vector = try!(self.lhs.eval(r));
    let r: &Vector = try!(self.rhs.eval(r));

    Err(Error::InvalidExpression)
  }
}

impl HasDataTy for Plus {
  #[inline]
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}


fn eval<T: ops::Add>(res: &mut [T], l: &[T], r: &[T]) where T : Copy + ops::Add<T, Output=T> {
  unsafe {
    for i in 0..VECTOR_SIZE {
       *res.get_unchecked_mut(i) = *l.get_unchecked(i) + *r.get_unchecked(i);
    }  
  }
}

fn eval2<T: ops::Add>(res: &mut Vector, lhs: &Vector, rhs: &Vector) where T : Copy + ops::Add<T, Output=T> {
  let t: &mut [T] = as_mut_array(res);
  let l: &[T] = as_array(lhs);
  let r: &[T] = as_array(rhs);

  unsafe {
    for i in 0..VECTOR_SIZE {
      *t.get_unchecked_mut(i) = *l.get_unchecked(i) + *r.get_unchecked(i);
    }  
  }
}

// trait MapPrimitive {
//   fn map_plus_vec_vec<T: ops::Add, L, R>(res: &mut Vector, lhs: &Vector, rhs: &Vector);
// }

// struct MapPlus;

// impl MapPrimitive for MapPlus {
//   fn map_plus_vec_vec<T: ops::Add, L, R>(res: &mut Vector, lhs: &Vector, rhs: &Vector) {
//     let t: &mut [T] = as_mut_array(res);
//     let l: &[L] = as_array(lhs);
//     let r: &[R] = as_array(rhs);

//     for i in 0..r.len() {
//       t[i] = (l[i] as T) + (r[i] as T);
//     }
//   }
// }

#[test]
fn test_generic_trait() {
  //let p: Box<Primitive> = Box::new(Primitive<INT4_T, INT4_T, INT4_T> {});
}

impl Field {
  pub fn new(column: &Column) -> Field {
    Field {
      column: column.clone(),
      field_id: None
    }
  }
}

impl HasDataTy for Field {
  fn data_ty(&self) -> &DataTy {
    &self.column.data_ty
  }
}

impl Eval for Field {
  
  fn bind(&mut self, schema: &Schema) -> Void {
      
    match schema.column_id(&self.column.name) {
        <commit_msg>Implemented the protytype for virtual operator.<commit_after>//!
//! Interpreter Compiler for Expressions
//!

use common::constant::VECTOR_SIZE;
use common::err::{Error, TResult, Void, void_ok};
use eval::{Eval, MapEval};
use expr::{Datum, Expr, Visitor};
use rows::RowBlock;
use rows::vector::{Vector, as_mut_array, as_array};
use schema::{Column, Schema};
use std::boxed::Box;
use std::ops;
use types::{DataTy, HasDataTy, HasTy, result_data_ty, Ty};

// Unary Expressions
pub struct Not {child: Box<Eval>}
pub struct IsNull {child: Box<Eval>}

// Binary Comparison Expressions
pub struct And {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Or {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Equal {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct NotEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}

// Binary Arithmetic Evalessions
pub struct Plus {data_ty: DataTy, pub lhs: Box<MapEval>, pub rhs: Box<MapEval>}
pub struct Minus {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Multiply {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Divide {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Modular {lhs: Box<Eval>, rhs: Box<Eval>}

// String operators or pattern matching predicates
pub struct Concatenate {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Like {pattern: String, child: Box<Eval>}
pub struct SimilarTo {pattern: String, child: Box<Eval>}
pub struct RegexMatch {pattern: String, child: Box<Eval>}

pub struct Between {pred: Box<Eval>, begin: Box<Eval>, end: Box<Eval>}
pub struct In {pred: Box<Eval>, row: Box<Row>}

pub struct Row {values: Vec<Box<Eval>>}
pub struct Field {column: Column, field_id: Option<usize>}
pub struct Const {datum: Datum, res_type: DataTy}


impl Eval for Plus {
  fn bind(&mut self, schema: &Schema) -> Void {
    self.data_ty = result_data_ty(self.lhs.data_ty(), self.rhs.data_ty());
    void_ok()
  }  
  
  fn is_const(&self) -> bool { false }
}

impl MapEval for Plus {
  fn eval(&self, r: &RowBlock) -> TResult<&Vector> {
    let l: &Vector = try!(self.lhs.eval(r));
    let r: &Vector = try!(self.rhs.eval(r));

    let f: Option<fn(&mut Vector, &Vector, &Vector)> = Some(if true {
      eval2::<i32>
    } else {
      eval2::<i64>
    });

    Err(Error::InvalidExpression)
  }
}

impl HasDataTy for Plus {
  #[inline]
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}


fn eval<T: ops::Add>(res: &mut [T], l: &[T], r: &[T]) where T : Copy + ops::Add<T, Output=T> {
  unsafe {
    for i in 0..VECTOR_SIZE {
       *res.get_unchecked_mut(i) = *l.get_unchecked(i) + *r.get_unchecked(i);
    }  
  }
}

fn eval_i32(res: &mut Vector, lhs: &Vector, rhs: &Vector) {
  eval2::<i32>(res, lhs, rhs);
}

fn eval_i64(res: &mut Vector, lhs: &Vector, rhs: &Vector) {
  eval2::<i64>(res, lhs, rhs);
}

#[inline]
fn eval2<T: ops::Add>(res: &mut Vector, lhs: &Vector, rhs: &Vector) where T : Copy + ops::Add<T, Output=T> {
  let t: &mut [T] = as_mut_array(res);
  let l: &[T] = as_array(lhs);
  let r: &[T] = as_array(rhs);

  unsafe {
    for i in 0..VECTOR_SIZE {
      *t.get_unchecked_mut(i) = *l.get_unchecked(i) + *r.get_unchecked(i);
    }  
  }
}

// trait MapPrimitive {
//   fn map_plus_vec_vec<T: ops::Add, L, R>(res: &mut Vector, lhs: &Vector, rhs: &Vector);
// }

// struct MapPlus;

// impl MapPrimitive for MapPlus {
//   fn map_plus_vec_vec<T: ops::Add, L, R>(res: &mut Vector, lhs: &Vector, rhs: &Vector) {
//     let t: &mut [T] = as_mut_array(res);
//     let l: &[L] = as_array(lhs);
//     let r: &[R] = as_array(rhs);

//     for i in 0..r.len() {
//       t[i] = (l[i] as T) + (r[i] as T);
//     }
//   }
// }

#[test]
fn test_generic_trait() {
  let y = eval2;
}

impl Field {
  pub fn new(column: &Column) -> Field {
    Field {
      column: column.clone(),
      field_id: None
    }
  }
}

impl HasDataTy for Field {
  fn data_ty(&self) -> &DataTy {
    &self.column.data_ty
  }
}

impl Eval for Field {
  
  fn bind(&mut self, schema: &Schema) -> Void {
      
    match schema.column_id(&self.column.name) {
        
{'fraction_non_alphanumeric': 0.17632460603052488, 'fraction_numerical': 0.0034743764735078795, 'mean_word_length': 3.8119402985074626, 'pattern_counts': {'":': 0, '<': 106, '<?xml version=': 0, '>': 120, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '321179', 'n_tokens_mistral': 3160, 'n_tokens_neox': 3155, 'n_words': 870}