[ 
https://issues.apache.org/jira/browse/PHOENIX-2684?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Julian Eberius updated PHOENIX-2684:
------------------------------------
    Description: 
I'm using Phoenix 4.5.2 for HBase 1.0 on CDH 5.4.7 using the 
Cloudera-distributed packages of Phoenix and 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));


  was:
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));



> 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 and 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)

Reply via email to