Phoenix doesn't display negative integer values correctly

泪湿孤枕 提交于 2019-12-03 14:46:09

http://phoenix.apache.org/language/datatypes.html

The binary representation is a 4 byte integer with the sign bit flipped (so that negative values sorts before positive values).

So to convert from HBase serialization format to Phoenix format:

(-17678)10 = (11111111111111111011101011110010)2
=> (01111111111111111011101011110010)2 = (2147465970)10

Thus the output is as expected. You need to be aware of the binary representation when inserting data using HBase.

Direct HBase toByte to Phoenix reads is only possible with CHAR and UNSIGNED_* data types. You'd have to serialize appropriately for other data types. ie. setting i = 2147465970 when you mean to insert -17678.

I recommend using Phoenix to insert data. If you are worried about keeping your application light on dependencies, Phoenix offers a "thin" jdbc driver (4mb instead of 86mb).

https://phoenix.apache.org/server.html


If you absolutely must use HBase, you can serialize signed numbers by using a bitwise XOR.

For integers, you would want to XOR your i with a bitmask to flip the sign bit.

The bitmask to apply to a 4-byte Integer is:

(10000000000000000000000000000000)2 = (-2147483648)10

From http://ideone.com/anhgs5 , we get 2147465970. If you insert that using HBase, when you read using Phoenix, you will read -17678).

You will need a different bitmask for Bigint (shared bitmask with the date-time types), Smallint, Float, and Double.

Jorge

Try something like :

//Add dependencies in your pom.xml
<dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>${phoenix.core.version}</version>
            <scope>provided</scope>
</dependency>

And than:

//Import these classes. More types available
import org.apache.phoenix.schema.types.{PDecimal, PInteger, PVarchar}
//and replace your addColumn method by this one:
p.addColumn(Bytes.toBytes("test"),Bytes.toBytes("test"),PInteger.INSTANCE.toBytes(i));
//Or if you wish a Decimal
p.addColumn(Bytes.toBytes("test"),Bytes.toBytes("test"),PDecimal.INSTANCE.toBytes(i));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!