SQL Custom Value Processors – Overview
ON THIS PAGE
- What Is a Value Processor?
- The Problem: Legacy Data Encoding
- How Value Processors Work
- Built-In Value Processors
- When Should You Use a Value Processor?
- High-Level Usage Summary
What Is a Value Processor?
A Value Processor is a custom Java class that teaches the BBj SQL engine how to
interpret the raw bytes stored in a BBx/BBj data file and expose them as a well-typed, standard
SQL data type. Without a value processor, every column value is returned in the same native form
that it is physically stored on disk — usually a string or numeric value. With a value processor
in place, the SQL engine transparently converts those raw values on their way in and out of the
engine so that consumers always see a proper SQL type such as BOOLEAN or
DATE.
Value processors are implemented by extending the abstract base class
com.basis.startup.type.sql.ValueProcessor and packaging the resulting class in a
JAR that is made available to the BBj SQL engine.
The Problem: Legacy Data Encoding
The BBj SQL engine reads data from BBx string-template data files. Each record is stored as a
series of raw bytes interpreted by a string template — a schema definition that
describes the layout of each field as a sequence of typed slots. The native BBx types
(C, N, I, etc.) map directly to SQL types such as
CHAR, NUMERIC, and INTEGER.
Over the decades, many applications have used these available types creatively to represent domain values that have no direct native counterpart. Common examples include:
| Logical Meaning | Typical Raw Storage | Native SQL Type Returned Without a Processor |
|---|---|---|
| Boolean true/false | "Y" / "N" in a C(1) field |
CHAR(1)
|
| Boolean true/false | 1 / 0 in a numeric field |
NUMERIC
|
| Calendar date | Julian day number in a numeric field | NUMERIC
|
| Calendar date | "YYYYMMDD" string in a C(8) field |
CHAR(8)
|
Historically, developers had to retrieve these raw values and perform the interpretation in application code. This created several problems:
- Every application that touched the data had to embed its own conversion logic.
- SQL expressions such as
WHERE active = TRUEwere impossible; only raw-value comparisons likeWHERE active = 'Y'worked. - JDBC metadata reported inaccurate column types to client tools and ORMs.
- The semantic intent of the data was completely invisible to the SQL layer.
Value processors solve all of these problems in one place — at the SQL engine itself — so that every caller benefits automatically, with no changes to application code.
How Value Processors Work
A value processor sits between the raw data in the data file and the value returned to the SQL client. It also works in reverse when data is being written.
Reading (SELECT):
|
|
→ |
|
→ |
computeReturnedValue() |
→ |
|
Writing (INSERT / UPDATE):
|
|
→ |
computeRawValue() |
→ |
|
→ |
|
A value processor is linked to a Type Definition in the BBj data dictionary. A type definition is a named schema object that can be assigned to one or more columns in a table. When a column has a type definition that references a value processor class, the SQL engine automatically instantiates that processor class (using its public default constructor) and invokes it for every read and write operation on that column.
The ValueProcessor Abstract Class
Every value processor must extend com.basis.startup.type.sql.ValueProcessor and
implement the following abstract methods:
| Method | Direction | Purpose |
|---|---|---|
Object computeReturnedValue(Object p_value)
|
Read | Converts the raw value from the data file into the desired SQL type object. |
Object computeRawValue(BBjSQLLiteral p_value)
|
Write | Converts an SQL-typed value back into the raw form to be written to the data file. |
int getSqlType()
|
Metadata | Returns the java.sql.Types constant for the SQL type this processor produces (e.g., Types.BOOLEAN). |
String getDisplayName()
|
Metadata | A short, human-readable name shown in Enterprise Manager when selecting a processor for a column. |
String getDescription()
|
Metadata | A short description shown alongside the display name in Enterprise Manager. |
boolean isLexicallyOrdered()
|
Optimization | Return true if the raw values sort in the same order as the processed values, allowing the SQL engine to use indexes for range queries. |
Discovery and Loading
The SQL engine loads a value processor class by name at runtime using a class loader that is configured via the database's SQL Factory SSCP property. The class name is stored in the type definition record in the data dictionary. When the SQL engine opens a table whose columns reference a type definition, it instantiates the processor using the class's public default (no-argument) constructor.
READ and WRITE verbs. The raw bytes on disk are always unchanged;
only the SQL representation is transformed.Built-In Value Processors
BBj ships with the following value processors out of the box:
| Class Name | Display Name | Description | SQL Type Returned |
|---|---|---|---|
YNBooleanValueProcessor
|
Boolean Y/N Processor | Converts a C(1) string field whose value is "Y" or "T"
to SQL true, and "N", "F", or empty to SQL false. |
BOOLEAN
|
BaristaValueProcessor
|
Barista Element Type Processor | Processes Barista application element types. Handles checkbox boolean fields (converting
configurable true/false strings to true/false) and OEM date
formats such as Julian day numbers and YYYYMMDD strings, converting them to SQL
DATE values. |
BOOLEAN or DATE |
When Should You Use a Value Processor?
Consider writing a custom value processor when:
- You have boolean-like data not covered by the built-in processors.
For example, a numeric column that stores
1for true and0for false. - You have date or time data stored in a proprietary format. If your application encodes dates in a way not handled by BBj's built-in processors, a custom processor can decode them on the fly.
- You want to present type-accurate metadata to JDBC clients. Reporting tools, ORMs, and BI platforms read JDBC column metadata. Returning the correct SQL type helps these tools handle your data correctly without additional configuration.
- You want SQL expressions to use the logical type.
Once a column is processed as
BOOLEAN, SQL expressions likeWHERE active = TRUEwork as expected rather than requiring knowledge of the raw storage encoding. - You need a single, centralized conversion layer. Conversion logic in a value processor lives in one place rather than being duplicated across every application or report that reads the same table.
High-Level Usage Summary
Using a custom value processor involves four high-level steps:
-
Write the Java class — Extend
ValueProcessorand implement the six required methods. Your class must have a public default (no-argument) constructor.
-
Compile and package the class into a JAR file.
-
Register the JAR with BBj — Create a Session Specific Classpath (SSCP) entry in Enterprise Manager that points to your JAR, then set the target database's Scalar/Group Function SSCP property (
SQL_FACTORY_SSCP) to that SSCP name.
-
Assign the processor to a column — In Enterprise Manager, open the type definition for the target column and select your processor from the list.
For complete technical details on each step, see: Custom Value Processors – Reference. For a hands-on walkthrough, see: Tutorial: Creating a Numeric Boolean Value Processor.
See Also
Custom Value Processors – Reference
Tutorial: Creating a Numeric Boolean Value Processor