[
https://issues.apache.org/jira/browse/PHOENIX-626?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Gabriel Reid resolved PHOENIX-626.
----------------------------------
Resolution: Fixed
Bulk resolve of closed issues imported from GitHub. This status was reached by
first re-opening all closed imported issues and then resolving them in bulk.
> Incompatible columns data types - data column and index column
> --------------------------------------------------------------
>
> Key: PHOENIX-626
> URL: https://issues.apache.org/jira/browse/PHOENIX-626
> Project: Phoenix
> Issue Type: Task
> Reporter: Dmitry Salychev
>
> There are table like that
> ```sql
> CREATE TABLE IF NOT EXISTS tableName (
> id BINARY(16) NOT NULL PRIMARY KEY DESC,
> t BINARY(16) NOT NULL,
> e BINARY(16) NOT NULL,
> y BINARY(16) NOT NULL,
> d DATE NOT NULL,
> v VARBINARY NULL) IMMUTABLE_ROWS=true
> ```
> and index like that
> ```sql
> CREATE INDEX IF NOT EXISTS indexName ON tableName(t DESC,e,d)
> ```
> When I try to UPSERT value in the table, I've got
> ```
> com.salesforce.phoenix.schema.IllegalDataException: Cannot convert from DATE
> to DECIMAL
> at com.salesforce.phoenix.schema.PDataType.toObject(PDataType.java:4549)
> at
> com.salesforce.phoenix.schema.PDataType$9.toObject(PDataType.java:1349)
> at com.salesforce.phoenix.schema.PDataType.toObject(PDataType.java:4565)
> at com.salesforce.phoenix.schema.PDataType.toObject(PDataType.java:4573)
> at
> com.salesforce.phoenix.schema.PDataType.coerceBytes(PDataType.java:4519)
> at
> com.salesforce.phoenix.index.IndexMaintainer.buildRowKey(IndexMaintainer.java:301)
> at
> com.salesforce.phoenix.index.IndexMaintainer.buildUpdateMutation(IndexMaintainer.java:338)
> at
> com.salesforce.phoenix.util.IndexUtil.generateIndexData(IndexUtil.java:178)
> at
> com.salesforce.phoenix.execute.MutationState$1.next(MutationState.java:206)
> at
> com.salesforce.phoenix.execute.MutationState$1.next(MutationState.java:189)
> at
> com.salesforce.phoenix.execute.MutationState.commit(MutationState.java:339)
> at
> com.salesforce.phoenix.jdbc.PhoenixConnection.commit(PhoenixConnection.java:249)
> at
> com.salesforce.phoenix.jdbc.PhoenixStatement.executeMutation(PhoenixStatement.java:249)
> at
> com.salesforce.phoenix.jdbc.PhoenixStatement.access$600(PhoenixStatement.java:138)
> at
> com.salesforce.phoenix.jdbc.PhoenixStatement$ExecutableUpsertStatement.executeUpdate(PhoenixStatement.java:279)
> at
> com.salesforce.phoenix.jdbc.PhoenixPreparedStatement.executeUpdate(PhoenixPreparedStatement.java:125)
> at
> com.jolbox.bonecp.PreparedStatementHandle.executeUpdate(PreparedStatementHandle.java:205)
> at
> org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:824)
> at
> org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:818)
> at
> org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589)
> at
> org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:818)
> at
> org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:874)
> at com.something.MyClass.create(MyClass.java:45)
> ```
> I am investigating a bit into the trouble and explore that place in the
> com.salesforce.phoenix.index.IndexMaintainer (start from line 370)
> ```java
> PDataType indexColumnType = IndexUtil.getIndexColumnDataType(isNullable,
> dataColumnType);
> boolean isBytesComparable =
> dataColumnType.isBytesComparableWith(indexColumnType);
> if (isBytesComparable && isDataColumnInverted ==
> descIndexColumnBitSet.get(i)) {
> output.write(ptr.get(), ptr.getOffset(), ptr.getLength());
> } else {
> if (!isBytesComparable) {
> // FIXME Is it valid state?
> // dataColumnType = DATE
> // indexColumnType = DECIMAL
> indexColumnType.coerceBytes(ptr, dataColumnType,
> dataColumnModifier, null);
> }
> ...
> ```
> Looks like the "IndexUtil.getIndexColumnDataType" return an illegal value
> (DECIMAL), but it must be DATE. Check the
> com.salesforce.phoenix.util.IndexUtil for the problem place and get
> ```java
> public static PDataType getIndexColumnDataType(boolean isNullable, PDataType
> dataType) {
> if (dataType == null || !isNullable || !dataType.isFixedWidth() ||
> dataType == PDataType.BINARY) {
> // In that case for NON NULLABLE dataType = DATE return value is DATE.
> // But it seems to return the PDataType.DECIMAL
> return dataType;
> }
> // for INT, BIGINT
> if (dataType.isCoercibleTo(PDataType.TIMESTAMP) ||
> dataType.isCoercibleTo(PDataType.DECIMAL)) {
> return PDataType.DECIMAL;
> }
> // for CHAR
> if (dataType.isCoercibleTo(PDataType.VARCHAR)) {
> return PDataType.VARCHAR;
> }
> throw new IllegalArgumentException("Unsupported non nullable index type "
> + dataType);
> }
> ```
--
This message was sent by Atlassian JIRA
(v6.2#6252)