Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot get composite column name (object) when more than one row is retrieved. #167

Closed
rabinnh opened this issue Dec 20, 2012 · 3 comments
Closed
Assignees

Comments

@rabinnh
Copy link

rabinnh commented Dec 20, 2012

If I have a composite column and I perform a simple MutationBatch.getRow(key) call to return a single row, the return type is a ThriftColumnOrSuperColumnListImpl object. If I do a "getResult()" on the object, I get a ColumnList object which is a list of all columns in the row.

For each ColumnFamily object in the list, I can then call "getName()", which returns an Object. In the case of a composite column this object is an instance of the class that I defined for my composite column. I can identify it by:

columnFamilyObject.getName().getClass().getName()

and I know exactly what to do with it. If my validation type is a long I simply do columnFamilyObject.getLongValue() and I'm all set. Note that MutationBatch.getRow() results in a RowQuery object.

However, if I do any sort of slice or range query that can return multiple rows, the return object is a ThriftAllRows object. Each object in the list is a Row<String, Object> and each column in that list is a ColumnList which contains a Column object instead of a ColumnFamily object. Calling "getName()" on these objects returns a String for a row. For a composite row the String is empty because the column "name" is not a String, but a different sort of object ( although inspecting the value in the String object artifacts from the composite class properties, for example if the first property was a string, you can see some of the text). Note that all slice and range queries result in a list of RowSliceQuery objects instead of RowQuery objects.

So it appears that the RowQuery object reasonably creates an object internal while the RowSliceObject forces an column name into a String, thus rendering it impossible to determine the original object type.

@rabinnh
Copy link
Author

rabinnh commented Dec 21, 2012

Additional testing notes:: when I have only composite columns in the row and I call "MutationBatch.getRow(key)" everything works. However, if the row has other columns, I get an IllegalArgumentException on non-composite rows:

Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException
at com.netflix.astyanax.serializers.AnnotatedCompositeSerializer.fromByteBuffer(AnnotatedCompositeSerializer.java:136)
at com.netflix.astyanax.serializers.AbstractSerializer.fromBytes(AbstractSerializer.java:44)
at com.netflix.astyanax.thrift.model.ThriftColumnOrSuperColumnListImpl$1IteratorImpl.next(ThriftColumnOrSuperColumnListImpl.java:86)
at com.netflix.astyanax.thrift.model.ThriftColumnOrSuperColumnListImpl$1IteratorImpl.next(ThriftColumnOrSuperColumnListImpl.java:57)
at dynCassandraExample.Main.compositeColumnTest(Main.java:213)
at dynCassandraExample.Main.main(Main.java:96)

The line in question is:

return fromByteBuffer(ByteBuffer.wrap(bytes));

"bytes" seems to be a valid HeapByteBuffer, but ThritColumnOrSuperColumn is trying to use the same AbstractCompositeSerializer on non composite columns that it used on the composite columns.

To be clear, it correctly processes a composite column and then throws the exception on the next non-composite column as I iterate throw the columns returned by getResult().

Digging further, the Buffer.class has the following code:

public final Buffer limit(int newLimit) {
    if ((newLimit > capacity) || (newLimit < 0))
        throw new IllegalArgumentException();
    limit = newLimit;
    if (position > limit) position = limit;
    if (mark > limit) mark = -1;
    return this;
}

The exception is thrown because newLimit is equal to 12597 and limit is equal to 10.

This is because:

private static int getShortLength(ByteBuffer bb) {
    int length = (bb.get() & 0xFF) << 8;
    return length | (bb.get() & 0xFF);
}

bb.get() returns 12597.

I'm frankly not sure what the logic is supposed to be, but it appears to me that Astyanax makes the assumption that a row will not have a mixture of composite and non-composite columns.

@ghost ghost assigned sagarl Dec 23, 2013
@sagarl
Copy link
Contributor

sagarl commented Dec 23, 2013

@rabinnh let me know if you are still seeing the issue and if yes, please print the code so that I can replicate it.

Thanks,

@sagarl
Copy link
Contributor

sagarl commented Jan 29, 2014

Looks like the issue is not seen anymore, hence closing it.

@sagarl sagarl closed this as completed Jan 29, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants