Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions javakdb/src/main/java/com/kx/c.java
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,19 @@ public static class Flip{
* Create a Flip (KDB+ table) from the values stored in a Dict.
* @param dict Values stored in the dict should be an array of Strings for the column names (keys), with an
* array of arrays for the column values
* @throws IllegalArgumentException if the dict values are not an array of column data (Object[]). This can be
* the case when a splayed/partitioned table stored on disk is received (kdb+ transmits a mapping of column names
* to an on-disk path symbol rather than the column data), or when the Dict was constructed with values that are
* not column arrays.
* @see <a href="https://code.kx.com/q/kb/splayed-tables/">Splayed tables</a>
*/
public Flip(Dict dict){
x=(String[])dict.x;
if(!(dict.y instanceof Object[]))
throw new IllegalArgumentException("A Flip requires the dictionary values to be an array of column data"
+" (Object[]) but received: "+dict.y+". This can occur when a splayed/partitioned table stored on disk is"
+" received (kdb+ transmits an on-disk path reference rather than the columns), or when the Dict was"
+" constructed with values that are not column arrays.");
y=(Object[])dict.y;
}
/**
Expand Down
35 changes: 35 additions & 0 deletions javakdb/src/test/java/com/kx/CTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,41 @@ public void testDeserializeEmptyTable()
}
}

@Test
public void testDeserializeSplayedTableReference()
{
// response from executing 'get `:test/ set ([] a:til 10)'
// A splayed (on-disk) table is transmitted as table(98) -> dict(99) whose value is the
// file-path symbol `:test/ (type -11) rather than the column data, so it cannot be
// represented as an in-memory Flip. This should surface as a clear IllegalArgumentException
// rather than an opaque ClassCastException (issue #51).
byte[] buff = {(byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x1b, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x62, (byte)0x00, (byte)0x63, (byte)0x0b, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x61, (byte)0x00, (byte)0xf5, (byte)0x3a, (byte)0x74, (byte)0x65, (byte)0x73, (byte)0x74, (byte)0x2f, (byte)0x00};
com.kx.c c=new com.kx.c();
try {
c.deserialize(buff);
Assert.fail("Expected an IllegalArgumentException to be thrown");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains(":test/"));
} catch (Exception e) {
Assert.fail(e.toString());
}
}

@Test
public void testFlipFromDictWithNonColumnValues()
{
// The same guard also protects against a Dict that was simply constructed with values that are
// not column arrays (i.e. a caller bug, not a splayed table); the message describes the actual
// condition rather than assuming a specific cause.
c.Dict dict = new c.Dict(new String[]{"a"}, "not-a-column-list");
try {
new c.Flip(dict);
Assert.fail("Expected an IllegalArgumentException to be thrown");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("Object[]"));
}
}

@Test
public void testMonthToString()
{
Expand Down