Skip to main content

6.7.2 Basic Type Handlers

Built-in handlers are in subpackages of net.hasor.dataql.sqlproc.types. Standard mappings work automatically; optional conversions use typeHandler or application registration.

Strings​

HandlerJDBC typesScript result
string.StringTypeHandlerCHAR, VARCHAR, LONGVARCHARFull string
string.NStringTypeHandlerNCHAR, NVARCHAR, LONGNVARCHARUnicode string
string.ClobAsStringTypeHandlerCLOBFull text
string.NClobAsStringTypeHandlerNCLOBFull Unicode text
string.SqlXmlTypeHandlerSQLXMLXML text

CHAR and NCHAR return the full field. Fixed-width padding and empty-string storage follow database behavior. SQL NULL becomes null.

var query = @@selectSql(text)<%
SELECT CAST(#{text, jdbcType=NCHAR} AS NCHAR(4))
%>;
return query('中文测试');

H2 returns "中文测试". CLOB, NCLOB and SQLXML are materialized before the query finishes; scripts do not receive JDBC Readers.

Numbers and booleans​

HandlerDefault JDBC typesBehavior
bool.BooleanTypeHandlerBIT, BOOLEANBoolean
number.ByteTypeHandler / ShortTypeHandlerTINYINT, SMALLINTSmall integer
number.IntegerTypeHandler / LongTypeHandlerINTEGER, BIGINTInteger
number.FloatTypeHandler / DoubleTypeHandlerFLOAT, REAL / DOUBLEFloating point
number.BigDecimalTypeHandlerNUMERIC, DECIMALDecimal
number.BigIntegerTypeHandlerLarge integer parametersBigDecimal binding
number.NumberTypeHandlerOther Number parametersBigDecimal binding

SQL NULL reads are checked rather than becoming zero or false. The column range and precision still limit stored values.

var query = @@selectSql(amount, enabled)<%
SELECT CAST(#{amount} AS DECIMAL(12, 2)) AS "amount",
CAST(#{enabled, jdbcType=BOOLEAN} AS BOOLEAN) AS "enabled"
%>;
return query(123.45, true);

H2 returns {"amount":123.45,"enabled":true}.

Optional handlers:

  • number.IntegerAsBooleanTypeHandler writes true/false as 1/0 and reads nonzero integers as true.
  • number.StringAsBigIntegerTypeHandler and number.StringAsBigDecimalTypeHandler store large numbers as text and read them back as numbers. Non-null input is BigInteger or BigDecimal respectively.
  • number.PgMoneyAsBigDecimalTypeHandler converts PostgreSQL money text and BigDecimal. Money formatting depends on the database locale.
var query = @@selectSql(enabled)<%
SELECT CAST(#{enabled, typeHandler=net.hasor.dataql.sqlproc.types.number.IntegerAsBooleanTypeHandler} AS INTEGER)
%>;
return query(true);

The result is 1. The explicit handler changes parameter binding; the result column is still read as INTEGER.

Dates and times​

jdbcTypeInputScript result
DATEEpoch milliseconds or yyyy-MM-dd textEpoch milliseconds
TIMEEpoch milliseconds or HH:mm:ss textEpoch milliseconds
TIMESTAMPEpoch milliseconds or yyyy-MM-dd HH:mm:ss with optional fractional secondsEpoch milliseconds
TIME_WITH_TIMEZONEEpoch milliseconds or 12:34:56+08:00ISO text with offset
TIMESTAMP_WITH_TIMEZONEEpoch milliseconds or 2026-10-05T12:34:56+08:00ISO text with offset

DATE, TIME and TIMESTAMP use time.SqlDateTypeHandler, time.SqlTimeTypeHandler and time.SqlTimestampTypeHandler. Offset types use time.OffsetTimeTypeHandler and time.OffsetDateTimeTypeHandler.

Timestamp text also accepts a T separator. Values without an offset follow JDBC and application local-time semantics. Offset handlers interpret numeric input as UTC. DataQL date results have millisecond precision and do not retain extra JDBC Timestamp nanoseconds.

var query = @@selectSql(createdAt)<%
SELECT CAST(#{createdAt, jdbcType=TIMESTAMP_WITH_TIMEZONE} AS TIMESTAMP WITH TIME ZONE)
%>;
return query('2026-10-05T12:34:56+08:00');

H2 returns "2026-10-05T12:34:56+08:00". SQL NULL returns null; invalid date text fails the query.

The optional PostgreSQL time.PgDateTypeHandler accepts ISO date strings, supports BC-year conversion and returns ISO strings. It does not automatically replace DATE handling.

XML text​

SqlXmlTypeHandler creates SQLXML for binding, reads XML as text, and releases SQLXML resources:

var save = @@insertSql(xml)<%
INSERT INTO documents(xml_content)
VALUES (#{xml, jdbcType=SQLXML})
%>;
return save('<person><name>Alice</name></person>');

The driver must support SQLXML and documents.xml_content must have a suitable type. For a normal text column, use string binding.