Netflix / astyanax

Cassandra Java Client
Apache License 2.0
1.04k stars 355 forks source link

ColumnFamilyQuery.getAllRows() Returns Rows with Null Columns #571

Open Kurt-von-Laven opened 9 years ago

Kurt-von-Laven commented 9 years ago

The following sample code sketches out how to reproduce the bug. The RuntimeException "baz is null" will be raised when this code is executed with astyanax-cassandra, astyanax-core, and astyanax-thrift at version 2.0.2, CQL version 3.1.1, Cassandra version 2.0.11, and Thrift version 19.39.0. My intuition is that this is related to https://github.com/Netflix/astyanax/issues/492#issue-28929439. Please let me know if more detail would be helpful.

import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.model.Row;
import com.netflix.astyanax.model.Rows;

// ...

String tableName = "my_table";
ColumnFamily<Foo, Bar> columnFamily = ColumnFamily.newColumnFamily(
    tableName,
    FooSerializer.get(),
    BarSerializer.get()
);
Rows<Foo, Bar> allRows = null;
try {
    OperationResult<Rows<Foo, Bar>> operationResult =
        context.getClient()
            .prepareQuery(columnFamily)
            .getAllRows()
            .execute();
    allRows = operationResult.getResult();
} catch (ConnectionException e) {
    // Handle error.
}

for (Row<UUID, String> row : allRows) {
    ColumnList<String> cols = row.getColumns();
    Integer baz = cols.getIntegerValue("baz", null);
    if (baz == null) {
        throw new RuntimeException("baz is null.");
    }
}

The following workaround suffices for now, so this is not an urgent issue.

import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.model.CqlResult;
import com.netflix.astyanax.model.Row;
import com.netflix.astyanax.model.Rows;

// ...

String tableName = "my_table";
ColumnFamily<Foo, Bar> columnFamily = ColumnFamily.newColumnFamily(
    tableName,
    FooSerializer.get(),
    BarSerializer.get()
);
Rows<Foo, Bar> allRows = null;
try {
    OperationResult<CqlResult<Foo, Bar>> operationResult =
        context.getClient()
            .prepareQuery(columnFamily)
            .withCql(String.format("SELECT * FROM %s", tableName))
            .execute();
    CqlResult<UUID, String> cqlResult = operationResult.getResult();
    allRows = cqlResult.getRows();
} catch (ConnectionException e) {
    // Handle error.
}

for (Row<UUID, String> row : allRows) {
    ColumnList<String> cols = row.getColumns();
    Integer baz = cols.getIntegerValue("baz", null);
    if (baz == null) {
        throw new RuntimeException("This exception doesn't get hit unless the " +
            "value of the column actually is null in the relevant Cassandra table.");
    }
}