Julian Eberius created PHOENIX-2684:
---------------------------------------
Summary: LiteralExpression.getBooleanLiteralExpression should
compare with .equals()
Key: PHOENIX-2684
URL: https://issues.apache.org/jira/browse/PHOENIX-2684
Project: Phoenix
Issue Type: Bug
Affects Versions: 4.5.2
Reporter: Julian Eberius
I'm using Phoenix 4.5.2 for HBase 1.0 on CDH 5.4.7 using the
Cloudera-distributed packages of Phoenix an the minimal client Jar in my
application, but as far as I can see, this should affect current versions as
well.
Setting a Boolean parameter via .setObject() in a prepared upsert statement to
a Java Boolean object that evaluates to false, but is not equal to
Boolean.FALSE, will lead to a value true (0x01) being inserted into
Phoenix/Hbase.
Such an object can be created, e.g., using new Boolean("false"). The problem is
that LiteralExpression.getBooleanLiteralExpression compares using "==", and not
using ".equals()".
A minimal example would create a table "create table test (a integer primary
key, b boolean)" and then create a PreparedStatement:
PreparedStatement ps = conn.prepareStatement("upsert into test values (1,
?)");
Finally, set a non-literal Java Boolean as a Object parameter:
ps.setObject(1, new Boolean("false"))
Execute and commit, and a value 0x01 will be inserted, because of the
comparison as described above. Using ps.setBoolean() instead of ps.setObject()
masks this problem due to unboxing. Obviously, the application should call
setBoolean(), but some more generic frameworks will pass parameters through
setObject, triggering to this bug (I used Spring's NamedParameterJdbcTemplate
and found this).
The underlying Java issue can be demonstrated with a simple program such as:
System.out.println(new Boolean("false") == Boolean.FALSE);
System.out.println(false == Boolean.FALSE);
System.out.println(new Boolean("false").equals(Boolean.FALSE));
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)