You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@phoenix.apache.org by "Julian Eberius (JIRA)" <ji...@apache.org> on 2016/02/15 14:40:18 UTC

[jira] [Updated] (PHOENIX-2684) LiteralExpression.getBooleanLiteralExpression should compare with .equals()

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