I've come across a problem with H2 (1.4.200) where an ALIAS'ed Java method 
that takes a java.lang.Number as a parameter is not being processed 
correctly - specifically, an error is thrown:

Hexadecimal string with odd number of characters: "1"; SQL statement:
SELECT valueOfNumber (1) [90003-200] 
<http://192.168.56.1:8082/query.do?jsessionid=c0d2c502e7df5e73bbb885b6e18bc7cc#>
 90003/90003 (Help) 
<https://h2database.com/javadoc/org/h2/api/ErrorCode.html#c90003>
org.h2.jdbc.JdbcSQLDataException: Hexadecimal string with odd number of 
characters: "1"; SQL statement:
SELECT valueOfNumber (1) [90003-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:590 
<https://h2database.com/html/source.html?file=org/h2/message/DbException.java&line=590&build=200>
)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:429 
<https://h2database.com/html/source.html?file=org/h2/message/DbException.java&line=429&build=200>
)
    at org.h2.message.DbException.get(DbException.java:205 
<https://h2database.com/html/source.html?file=org/h2/message/DbException.java&line=205&build=200>
)
    at org.h2.message.DbException.get(DbException.java:181 
<https://h2database.com/html/source.html?file=org/h2/message/DbException.java&line=181&build=200>
)
    at org.h2.util.StringUtils.convertHexToBytes(StringUtils.java:1040 
<https://h2database.com/html/source.html?file=org/h2/util/StringUtils.java&line=1040&build=200>
)
    at org.h2.value.Value.convertToJavaObject(Value.java:1262 
<https://h2database.com/html/source.html?file=org/h2/value/Value.java&line=1262&build=200>
)
    at org.h2.value.Value.convertTo(Value.java:834 
<https://h2database.com/html/source.html?file=org/h2/value/Value.java&line=834&build=200>
)
    at org.h2.value.Value.convertTo(Value.java:758 
<https://h2database.com/html/source.html?file=org/h2/value/Value.java&line=758&build=200>
)
    at 
org.h2.engine.FunctionAlias$JavaMethod.getValue(FunctionAlias.java:403 
<https://h2database.com/html/source.html?file=org/h2/engine/FunctionAlias.java&line=403&build=200>
)
    at org.h2.expression.function.JavaFunction.getValue(JavaFunction.java:40 
<https://h2database.com/html/source.html?file=org/h2/expression/function/JavaFunction.java&line=40&build=200>
)
    at 
org.h2.command.dml.Select$LazyResultQueryFlat.fetchNextRow(Select.java:1851 
<https://h2database.com/html/source.html?file=org/h2/command/dml/Select.java&line=1851&build=200>
)
    at org.h2.result.LazyResult.hasNext(LazyResult.java:101 
<https://h2database.com/html/source.html?file=org/h2/result/LazyResult.java&line=101&build=200>
)
    at org.h2.result.LazyResult.next(LazyResult.java:60 
<https://h2database.com/html/source.html?file=org/h2/result/LazyResult.java&line=60&build=200>
)
    at org.h2.command.dml.Select.queryFlat(Select.java:737 
<https://h2database.com/html/source.html?file=org/h2/command/dml/Select.java&line=737&build=200>
)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:844 
<https://h2database.com/html/source.html?file=org/h2/command/dml/Select.java&line=844&build=200>
)
    at org.h2.command.dml.Query.queryWithoutCacheLazyCheck(Query.java:201 
<https://h2database.com/html/source.html?file=org/h2/command/dml/Query.java&line=201&build=200>
)
    at org.h2.command.dml.Query.query(Query.java:489 
<https://h2database.com/html/source.html?file=org/h2/command/dml/Query.java&line=489&build=200>
)
    at org.h2.command.dml.Query.query(Query.java:451 
<https://h2database.com/html/source.html?file=org/h2/command/dml/Query.java&line=451&build=200>
)
    at org.h2.command.CommandContainer.query(CommandContainer.java:285 
<https://h2database.com/html/source.html?file=org/h2/command/CommandContainer.java&line=285&build=200>
)
    at org.h2.command.Command.executeQuery(Command.java:195 
<https://h2database.com/html/source.html?file=org/h2/command/Command.java&line=195&build=200>
)
    at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:222 
<https://h2database.com/html/source.html?file=org/h2/jdbc/JdbcStatement.java&line=222&build=200>
)
    at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:201 
<https://h2database.com/html/source.html?file=org/h2/jdbc/JdbcStatement.java&line=201&build=200>
)
    at org.h2.server.web.WebApp.getResult(WebApp.java:1459 
<https://h2database.com/html/source.html?file=org/h2/server/web/WebApp.java&line=1459&build=200>
)
    at org.h2.server.web.WebApp.query(WebApp.java:1116 
<https://h2database.com/html/source.html?file=org/h2/server/web/WebApp.java&line=1116&build=200>
)
    at org.h2.server.web.WebApp$1.next(WebApp.java:1078 
<https://h2database.com/html/source.html?file=org/h2/server/web/WebApp.java&line=1078&build=200>
)
    at org.h2.server.web.WebApp$1.next(WebApp.java:1065 
<https://h2database.com/html/source.html?file=org/h2/server/web/WebApp.java&line=1065&build=200>
)
    at org.h2.server.web.WebThread.process(WebThread.java:178 
<https://h2database.com/html/source.html?file=org/h2/server/web/WebThread.java&line=178&build=200>
)
    at org.h2.server.web.WebThread.run(WebThread.java:94 
<https://h2database.com/html/source.html?file=org/h2/server/web/WebThread.java&line=94&build=200>
)
    at java.lang.Thread.run(Thread.java:748)


As an example, take the following SQL - it creates an ALIAS function which 
takes in a parameter, and returns a toString() representation of it. 
Specifically, the parameter is an integer.
CREATE ALIAS valueOfInteger AS $$ String valueOfInteger(Integer number) { 
return number.toString(); } $$;
CALL valueOfInteger (1);

This outputs "1" as you would expect.

If you then modify it slightly to instead take in a Number:
CREATE ALIAS valueOfNumber AS $$ String valueOfNumber(Number number) { 
return number.toString(); } $$;
SELECT valueOfNumber (1);

You would expect an identical output - but instead the error above is 
thrown.

It appears that in org.h2.value.DataType.getTypeFromClass(Class<?>), there 
is no support for the Number type, as such it treats it as a 
"Value.JAVA_OBJECT" and then ultimately 
in org.h2.value.Value.convertToJavaObject() it falls through the switch and 
tries to parse it with StringUtils.convertHexToBytes which fails.

I don't know the scenario in which an object would need to be decoded from 
hex, but could support for this type be added?
And in addition, if the object is an unsupported type, could an exception 
to that effect be thrown, rather than the hexadecimal one?

Thanks in advance.

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/h2-database/c50334a3-bcc8-4a3d-810e-05fbba500bdf%40googlegroups.com.

Reply via email to