evalBinary evaluates binary expressions.
(expr *entql.BinaryExpr)
| 204 | |
| 205 | // evalBinary evaluates binary expressions. |
| 206 | func (e *state) evalBinary(expr *entql.BinaryExpr) *sql.Predicate { |
| 207 | switch expr.Op { |
| 208 | case entql.OpOr: |
| 209 | return sql.Or(e.evalExpr(expr.X), e.evalExpr(expr.Y)) |
| 210 | case entql.OpAnd: |
| 211 | return sql.And(e.evalExpr(expr.X), e.evalExpr(expr.Y)) |
| 212 | case entql.OpEQ, entql.OpNEQ: |
| 213 | if expr.Y == (*entql.Value)(nil) { |
| 214 | f, ok := expr.X.(*entql.Field) |
| 215 | expect(ok, "*entql.Field, got %T", expr.Y) |
| 216 | return nullFunc[expr.Op](e.field(f)) |
| 217 | } |
| 218 | fallthrough |
| 219 | default: |
| 220 | field, ok := expr.X.(*entql.Field) |
| 221 | expect(ok, "expr.X to be *entql.Field (got %T)", expr.X) |
| 222 | _, ok = expr.Y.(*entql.Field) |
| 223 | if !ok { |
| 224 | _, ok = expr.Y.(*entql.Value) |
| 225 | } |
| 226 | expect(ok, "expr.Y to be *entql.Field or *entql.Value (got %T)", expr.X) |
| 227 | switch x := expr.Y.(type) { |
| 228 | case *entql.Field: |
| 229 | return sql.ColumnsOp(e.field(field), e.field(x), binary[expr.Op]) |
| 230 | case *entql.Value: |
| 231 | c := e.field(field) |
| 232 | return sql.P(func(b *sql.Builder) { |
| 233 | b.Ident(c).WriteOp(binary[expr.Op]) |
| 234 | args(b, x) |
| 235 | }) |
| 236 | default: |
| 237 | panic("unreachable") |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | // evalEdge evaluates has-edge and has-edge-with calls. |
| 243 | func (e *state) evalEdge(name string, exprs ...entql.Expr) *sql.Predicate { |