Interface SearchSqlRenderer

Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

The SQL callback an application supplies for a custom search operator (design ยง5.3) so a SQL context can render it into a WHERE clause.

The renderer receives the target SqlDialect, the already-quoted column reference, the column's value type (so it can bind values as the right JDBC type), and the operator's arguments (typed values when the operator asks for them, otherwise the literal strings; see SearchOperator.Builder#typedArgs(boolean)), and returns a SqlFragment (a boolean SQL expression plus its ordered bind values). It is the SQL-side analog of SearchPredicate (the in-memory evaluator): built-in operators do not use it — their SQL comes from SqlDialect.builtinRenderer(String).

A renderer is attached to a SearchOperator as a typed extension keyed by this interface, with extension(SearchSqlRenderer.class, renderer); the context retrieves it with SearchOperator.extension(Class), so commons never depends on SQL dialect types. A renderer that does not support the supplied dialect returns null; the context then fails with a clear error rather than emitting wrong SQL. Values must be returned as SqlFragment binds, never concatenated into the SQL text.

For the built-in value operators, and for a custom operator built with typedArgs(true), each argument arrives already parsed by SearchType.parse(String) during query resolution: a BigDecimal for a NUMERIC column, a Boolean for BOOLEAN, and an OffsetDateTime, LocalDateTime or LocalDate for TIMESTAMP. Text-like types (TEXT, ID, ENUM, VERSION) are always String. A malformed value never reaches a renderer; it fails resolution with code BAD_VALUE.

Example:

// A custom "$even" operator rendered as a modulo check (one bind-free fragment). SearchSqlRenderer renderer = (dialect, col, type, args) -> SqlFragment.of("(" + col + " % 2 = 0)"); // A typed-args operator: args.get(0) is a BigDecimal on a NUMERIC column, bound as-is. SearchSqlRenderer divisibleBy = (dialect, col, type, args) -> SqlFragment.of("(" + col + " % ? = 0)", args.get(0)); SearchOperator even = SearchOperator .create("$even", "Matches even numbers. Example: $even()") .minArgs(0).maxArgs(0) .extension(SearchSqlRenderer.class, renderer) .build();

Since:
10.0.0
  • Method Details

    • render

      SqlFragment render(SqlDialect dialect, String columnSql, SearchType type, List<Object> args)
      Renders this custom operator into a SQL predicate fragment.
      Parameters:
      dialect - The target SQL dialect. Never null.
      columnSql - The dialect-quoted column reference the predicate applies to (for example "\"age\""). Never null.
      type - The column's value type, so the renderer can bind values as the right JDBC type. Never null.
      args - The operator's arguments (never null; may be empty): typed values (BigDecimal, Boolean, OffsetDateTime, LocalDateTime, LocalDate, or String for text-like types) for a built-in value operator or a custom operator with typedArgs(true); plain String literals otherwise.
      Returns:
      The predicate fragment, or null if this renderer does not support dialect.