Class SqlSearchCompiler

java.lang.Object
org.apache.juneau.beanquery.sql.SqlSearchCompiler

public final class SqlSearchCompiler extends Object
Compiles a resolved Filter tree into a SQL WHERE predicate for a SqlDialect.

This is the dialect-agnostic core of the shared JDBC engine. The terms are already parsed, allow-listed and type-checked. The compiler walks each tree and:

The SQL result must match the in-memory result, so a built-in the dialect cannot faithfully express is rejected with a BeanQuerySyntaxException whose code is BAD_VALUE rather than rendered differently: an operator for which SqlDialect.builtinRenderer(String) returns null (for example $regex on a database without regex support), and a range/ordering operator ($gt, $gte, $lt, $lte, $between) on a VERSION column when SqlDialect.supportsVersionOrdering() is false. Equality on versions is unaffected. A custom operator with no usable renderer still raises IllegalStateException.

Example:

ResolvedQuery q = context.resolve(BeanQuery.create().gt("age", 21).eq("name", "Bob").build()); SqlFragment where = SqlSearchCompiler.create(dialect, context).compile(q.filter()); // where.sql(): "age" > ? AND "name" = ? // where.binds(): [21, Bob]

Since:
10.0.0
  • Method Details

    • create

      public static SqlSearchCompiler create(SqlDialect dialect, ColumnResolver columns)
      Creates a compiler for a dialect and column resolver.
      Parameters:
      dialect - The target dialect. Must not be null.
      columns - Maps validated column names to quoted SQL references.
      Returns:
      A new compiler.
    • compile

      public SqlFragment compile(Filter filter)
      Compiles an already-resolved Filter tree into a boolean WHERE predicate.

      Renders the full cross-column Filter.And/Filter.Or/Filter.Not tree, so a top-level $or across different columns (for example DataTables' global search) compiles correctly. Filter.And/Filter.Or with no items render as always-true/always-false (1=1/1=0) per their own contract — see SqlBeanQueryContext.appendWhere, which special-cases an empty top-level filter so an unfiltered query's WHERE clause does not pick up a spurious (1=1).

      Example:

      SqlFragment where = SqlSearchCompiler.create(dialect, columns) .compile(filter);

      Parameters:
      filter - The resolved filter, or null for no predicate.
      Returns:
      The predicate fragment, or null if filter is null.
      Throws:
      BeanQuerySyntaxException - (BAD_VALUE) If a built-in leaf is not supported by the dialect.
      IllegalStateException - If a custom-operator leaf cannot be rendered for the dialect.