Skip to content

Commit 06a2daf

Browse files
committed
feat: Implement logical expressions (math, bools).
This commit introduces support for the following logical expressions : [x] Literal values: "domo", 3.14, 65536 [x] Column references: named (user_id, dept_id..) and index: (1, 2...) [x] Math expressions: salary * raise_pct [x] Comparison expressions: salary > 3000, dept != "antimemetics" [x] Cast expressions : "(id AS INT64)" [x] Alias expressions: "(user_name AS name)" With aggregate, scalar functions left for later; tests are also included for the relevant functionality that we currently support here.
1 parent 65aaf9a commit 06a2daf

File tree

12 files changed

+811
-33
lines changed

12 files changed

+811
-33
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.Field;
4+
5+
/**
6+
* Aliased expression e.g `expr AS alias`.
7+
*
8+
* AliasExpr
9+
*/
10+
public class AliasExpr implements LogicalExpr {
11+
private String alias;
12+
private LogicalExpr expr;
13+
14+
public AliasExpr(LogicalExpr expr, String alias) {
15+
this.expr = expr;
16+
this.alias = alias;
17+
}
18+
19+
@Override
20+
public Field toField(LogicalPlan plan) {
21+
return new Field(expr.toField(plan).name(), expr.toField(plan).dataType());
22+
}
23+
24+
@Override
25+
public String toString() {
26+
return String.format("%s AS %s", this.expr, this.alias);
27+
}
28+
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
public abstract class BinaryExpr {
4+
private String name;
5+
private String operator;
6+
private LogicalExpr lhs;
7+
private LogicalExpr rhs;
8+
9+
public BinaryExpr(String name, String operator, LogicalExpr lhs, LogicalExpr rhs) {
10+
this.name = name;
11+
this.operator = operator;
12+
this.lhs = lhs;
13+
this.rhs = rhs;
14+
}
15+
16+
@Override
17+
public String toString() {
18+
return String.format("%s %s %s", lhs.toString(), this.operator, rhs.toString());
19+
}
20+
21+
public String getName() {
22+
return name;
23+
}
24+
25+
public String getOperator() {
26+
return operator;
27+
}
28+
29+
public LogicalExpr getLhs() {
30+
return lhs;
31+
}
32+
33+
public LogicalExpr getRhs() {
34+
return rhs;
35+
}
36+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.ArrowTypes;
4+
import co.clflushopt.glint.types.Field;
5+
6+
/**
7+
* Binary expressions that return a boolean value.
8+
*
9+
* BooleanBinaryExpr
10+
*/
11+
public class BooleanExpr extends BinaryExpr implements LogicalExpr {
12+
13+
public BooleanExpr(String name, String operator, LogicalExpr lhs, LogicalExpr rhs) {
14+
super(name, operator, lhs, rhs);
15+
}
16+
17+
@Override
18+
public Field toField(LogicalPlan plan) {
19+
return new Field(this.getName(), ArrowTypes.BooleanType);
20+
}
21+
22+
/**
23+
* Returns an instance of `BooleanBinaryExpr` specialized for equality.
24+
*
25+
* @param lhs
26+
* @param rhs
27+
* @return
28+
*/
29+
public static BooleanExpr Eq(LogicalExpr lhs, LogicalExpr rhs) {
30+
return new BooleanExpr("eq", "=", lhs, rhs);
31+
}
32+
33+
/**
34+
* Returns an instance of `BooleanBinaryExpr` specialized for inequality.
35+
*
36+
* @param lhs
37+
* @param rhs
38+
* @return
39+
*/
40+
public static BooleanExpr Neq(LogicalExpr lhs, LogicalExpr rhs) {
41+
return new BooleanExpr("neq", "!=", lhs, rhs);
42+
}
43+
44+
/**
45+
* Returns an instance of `BooleanBinaryExpr` specialized for greater-than.
46+
*
47+
* @param lhs
48+
* @param rhs
49+
* @return
50+
*/
51+
public static BooleanExpr Gt(LogicalExpr lhs, LogicalExpr rhs) {
52+
return new BooleanExpr("gt", ">", lhs, rhs);
53+
}
54+
55+
/**
56+
* Returns an instance of `BooleanBinaryExpr` specialized for greater-than or
57+
* equal.
58+
*
59+
* @param lhs
60+
* @param rhs
61+
* @return
62+
*/
63+
public static BooleanExpr Gte(LogicalExpr lhs, LogicalExpr rhs) {
64+
return new BooleanExpr("gte", ">=", lhs, rhs);
65+
}
66+
67+
/**
68+
* Returns an instance of `BooleanBinaryExpr` specialized for lesser-than.
69+
*
70+
* @param lhs
71+
* @param rhs
72+
* @return
73+
*/
74+
public static BooleanExpr Lt(LogicalExpr lhs, LogicalExpr rhs) {
75+
return new BooleanExpr("lt", "<", lhs, rhs);
76+
}
77+
78+
/**
79+
* Returns an instance of `BooleanBinaryExpr` specialized for lesser-than or
80+
* equal.
81+
*
82+
* @param lhs
83+
* @param rhs
84+
* @return
85+
*/
86+
public static BooleanExpr Lte(LogicalExpr lhs, LogicalExpr rhs) {
87+
return new BooleanExpr("lte", "<=", lhs, rhs);
88+
}
89+
90+
/**
91+
* Returns an instance of `BooleanBinaryExpr` specialized for boolean AND.
92+
*
93+
* @param lhs
94+
* @param rhs
95+
* @return
96+
*/
97+
public static BooleanExpr And(LogicalExpr lhs, LogicalExpr rhs) {
98+
return new BooleanExpr("and", "AND", lhs, rhs);
99+
}
100+
101+
/**
102+
* Returns an instance of `BooleanBinaryExpr` specialized for boolean OR.
103+
*
104+
* @param lhs
105+
* @param rhs
106+
* @return
107+
*/
108+
public static BooleanExpr Or(LogicalExpr lhs, LogicalExpr rhs) {
109+
return new BooleanExpr("or", "OR", lhs, rhs);
110+
}
111+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import org.apache.arrow.vector.types.pojo.ArrowType;
4+
5+
import co.clflushopt.glint.types.ArrowTypes;
6+
import co.clflushopt.glint.types.Field;
7+
8+
/**
9+
* Cast expression represents explicit type casts `CAST(i AS TYPE)`.
10+
*
11+
* CastExpr
12+
*/
13+
public class CastExpr implements LogicalExpr {
14+
private LogicalExpr expr;
15+
private ArrowType dataType;
16+
17+
public CastExpr(LogicalExpr expr, ArrowType dataType) {
18+
this.expr = expr;
19+
this.dataType = dataType;
20+
}
21+
22+
@Override
23+
public Field toField(LogicalPlan plan) {
24+
return new Field(expr.toField(plan).name(), dataType);
25+
}
26+
27+
@Override
28+
public String toString() {
29+
return String.format("CAST(%s AS %s)", this.expr, ArrowTypes.toString(dataType));
30+
}
31+
32+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.Field;
4+
5+
/**
6+
* Logical expression representing a referenced column by an index. ColumnIndex
7+
*/
8+
public class ColumnIndex implements LogicalExpr {
9+
private Integer index;
10+
11+
public ColumnIndex(Integer index) {
12+
this.index = index;
13+
}
14+
15+
@Override
16+
public Field toField(LogicalPlan plan) {
17+
return plan.getSchema().getFields().get(this.index);
18+
}
19+
20+
@Override
21+
public String toString() {
22+
return "#" + index.toString();
23+
}
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.ArrowTypes;
4+
import co.clflushopt.glint.types.Field;
5+
6+
/**
7+
* Logical expression representing a Double literal.
8+
*/
9+
public class LiteralDouble implements LogicalExpr {
10+
private Double value;
11+
12+
public LiteralDouble(Double value) {
13+
this.value = value;
14+
}
15+
16+
@Override
17+
public Field toField(LogicalPlan plan) {
18+
return new Field(value.toString(), ArrowTypes.DoubleType);
19+
}
20+
21+
@Override
22+
public String toString() {
23+
return value.toString();
24+
}
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.ArrowTypes;
4+
import co.clflushopt.glint.types.Field;
5+
6+
/**
7+
* Logical expression representing a Long literal.
8+
*/
9+
public class LiteralLong implements LogicalExpr {
10+
private Long value;
11+
12+
public LiteralLong(Long value) {
13+
this.value = value;
14+
}
15+
16+
@Override
17+
public Field toField(LogicalPlan plan) {
18+
return new Field(value.toString(), ArrowTypes.Int64Type);
19+
}
20+
21+
@Override
22+
public String toString() {
23+
return value.toString();
24+
}
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.ArrowTypes;
4+
import co.clflushopt.glint.types.Field;
5+
6+
/**
7+
* Logical expression representing a string literal.
8+
*/
9+
public class LiteralString implements LogicalExpr {
10+
private String literal;
11+
12+
public LiteralString(String literal) {
13+
this.literal = literal;
14+
}
15+
16+
@Override
17+
public Field toField(LogicalPlan plan) {
18+
return new Field(literal, ArrowTypes.StringType);
19+
}
20+
21+
@Override
22+
public String toString() {
23+
return "'" + literal + "'";
24+
}
25+
26+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package co.clflushopt.glint.query.plan.logical;
2+
3+
import co.clflushopt.glint.types.Field;
4+
5+
/**
6+
* Mathematical expressions that return a numerical value.
7+
*
8+
* MathExpr
9+
*/
10+
public class MathExpr extends BinaryExpr implements LogicalExpr {
11+
12+
public MathExpr(String name, String operator, LogicalExpr lhs, LogicalExpr rhs) {
13+
super(name, operator, lhs, rhs);
14+
}
15+
16+
@Override
17+
public Field toField(LogicalPlan plan) {
18+
return new Field(this.getName(), this.getLhs().toField(plan).dataType());
19+
}
20+
21+
/**
22+
* Returns an instance of `BinaryExpr` specialized for addition.
23+
*
24+
* @param lhs
25+
* @param rhs
26+
* @return
27+
*/
28+
public static MathExpr Add(LogicalExpr lhs, LogicalExpr rhs) {
29+
return new MathExpr("add", "+", lhs, rhs);
30+
}
31+
32+
/**
33+
* Returns an instance of `BinaryExpr` specialized for substraction.
34+
*
35+
* @param lhs
36+
* @param rhs
37+
* @return
38+
*/
39+
public static MathExpr Sub(LogicalExpr lhs, LogicalExpr rhs) {
40+
return new MathExpr("sub", "-", lhs, rhs);
41+
}
42+
43+
/**
44+
* Returns an instance of `BinaryExpr` specialized for multiplication.
45+
*
46+
* @param lhs
47+
* @param rhs
48+
* @return
49+
*/
50+
public static MathExpr Mul(LogicalExpr lhs, LogicalExpr rhs) {
51+
return new MathExpr("mul", "*", lhs, rhs);
52+
}
53+
54+
/**
55+
* Returns an instance of `BinaryExpr` specialized for division.
56+
*
57+
* @param lhs
58+
* @param rhs
59+
* @return
60+
*/
61+
public static MathExpr Div(LogicalExpr lhs, LogicalExpr rhs) {
62+
return new MathExpr("div", "/", lhs, rhs);
63+
}
64+
}

0 commit comments

Comments
 (0)