Skip to content

Commit 31344aa

Browse files
committed
HPCC4J-657 DFSClient: Reading indices with blobs fails
- Updated RecordDefinitionTranslator to maintain blob information - Added isBlob property to FieldDef - Added translation test for indices with blobs - Added index read test for indices with blobs - Updated data generation to create an index with blobs Signed-off-by: James McMullan [email protected]
1 parent 6fdaf72 commit 31344aa

File tree

7 files changed

+171
-26
lines changed

7 files changed

+171
-26
lines changed

commons-hpcc/src/main/java/org/hpccsystems/commons/ecl/FieldDef.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class FieldDef implements Serializable
3535
private long len = 0;
3636
private boolean fixedLength = false;
3737
private boolean isUnsigned = false;
38+
private boolean isBlob = false;
3839
private int additionalFlags = 0;
3940

4041
/**
@@ -59,6 +60,7 @@ public FieldDef(FieldDef rhs)
5960
this.len = rhs.len;
6061
this.fixedLength = rhs.fixedLength;
6162
this.isUnsigned = rhs.isUnsigned;
63+
this.isBlob = rhs.isBlob;
6264
this.additionalFlags = rhs.additionalFlags;
6365
}
6466

@@ -330,6 +332,24 @@ public boolean isBiased()
330332
return isNonStandardInt();
331333
}
332334

335+
/**
336+
* Is the field stored in a blob?
337+
*
338+
* @return true when blob
339+
*/
340+
public boolean isBlob()
341+
{
342+
return this.isBlob;
343+
}
344+
345+
/**
346+
* Sets the blob flag.
347+
*/
348+
public void setIsBlob(boolean blob)
349+
{
350+
this.isBlob = blob;
351+
}
352+
333353
/**
334354
*
335355
*

commons-hpcc/src/main/java/org/hpccsystems/commons/ecl/RecordDefinitionTranslator.java

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class RecordDefinitionTranslator
3232
private static final String NAME_KEY = "name";
3333
private static final String TYPE_KEY = "type";
3434
private static final String CHILD_KEY = "child";
35+
private static final String XPATH_KEY = "xpath";
3536
private static final String FLAGS_KEY = "flags";
3637

3738
private static final String ESP_TYPE_NAME_PREFIX = "ty";
@@ -48,6 +49,7 @@ public class RecordDefinitionTranslator
4849
final private static int type_keyedint = 10; // Convert to integer
4950
final private static int type_record = 13;
5051
final private static int type_varstring = 14;
52+
final private static int type_blob = 15;
5153
final private static int type_data = 16;
5254
final private static int type_table = 20;
5355
final private static int type_set = 21;
@@ -264,28 +266,32 @@ public static String toECLRecord(FieldDef field) throws Exception
264266
*/
265267
private static String getEClTypeDefinition(FieldDef field, HashMap<String, String> recordDefinitionMap) throws Exception
266268
{
269+
String type = "";
267270
switch (field.getFieldType())
268271
{
269272
case SET:
270273
{
271-
return "SET OF " + getEClTypeDefinition(field.getDef(0), recordDefinitionMap);
274+
type = "SET OF " + getEClTypeDefinition(field.getDef(0), recordDefinitionMap);
275+
break;
272276
}
273277
case DATASET:
274278
{
275-
return "DATASET(" + getEClTypeDefinition(field.getDef(0), recordDefinitionMap) + ")";
279+
type = "DATASET(" + getEClTypeDefinition(field.getDef(0), recordDefinitionMap) + ")";
280+
break;
276281
}
277282
case BINARY:
278283
{
284+
type = "DATA";
279285
if (field.isFixed())
280286
{
281-
return "DATA" + field.getDataLen();
287+
type += field.getDataLen();
282288
}
283-
284-
return "DATA";
289+
break;
285290
}
286291
case BOOLEAN:
287292
{
288-
return "BOOLEAN";
293+
type = "BOOLEAN";
294+
break;
289295
}
290296
case INTEGER:
291297
{
@@ -300,7 +306,8 @@ private static String getEClTypeDefinition(FieldDef field, HashMap<String, Strin
300306
throw new Exception("Error: Unsupported integer size: " + field.getDataLen() + " must 1-8.");
301307
}
302308

303-
return root + field.getDataLen();
309+
type = root + field.getDataLen();
310+
break;
304311
}
305312
case FILEPOS:
306313
{
@@ -314,7 +321,8 @@ private static String getEClTypeDefinition(FieldDef field, HashMap<String, Strin
314321
throw new Exception("Error: Unsupported filepos size: " + field.getDataLen() + " must be 8.");
315322
}
316323

317-
return "UNSIGNED8";
324+
type = "UNSIGNED8";
325+
break;
318326
}
319327
case DECIMAL:
320328
{
@@ -323,28 +331,33 @@ private static String getEClTypeDefinition(FieldDef field, HashMap<String, Strin
323331
{
324332
root = "U" + root;
325333
}
326-
return root + field.getPrecision() + "_" + field.getScale();
334+
type = root + field.getPrecision() + "_" + field.getScale();
335+
break;
327336
}
328337
case REAL:
329338
{
330339
if (field.getDataLen() == 4)
331340
{
332-
return "REAL4";
341+
type = "REAL4";
333342
}
334343
else if (field.getDataLen() == 8)
335344
{
336-
return "REAL8";
345+
type = "REAL8";
337346
}
347+
else
348+
{
349+
throw new Exception("Error: Unsupported real size: " + field.getDataLen() + " must 4 or 8.");
350+
}
351+
break;
338352

339-
throw new Exception("Error: Unsupported real size: " + field.getDataLen() + " must 4 or 8.");
340353
}
341354
case CHAR:
342355
{
343-
return "STRING1";
356+
type = "STRING1";
357+
break;
344358
}
345359
case STRING:
346360
{
347-
String type = "";
348361
HpccSrcType srcType = field.getSourceType();
349362
if (srcType == HpccSrcType.SINGLE_BYTE_CHAR)
350363
{
@@ -371,11 +384,10 @@ else if (srcType == HpccSrcType.QSTRING)
371384
{
372385
type += field.getDataLen();
373386
}
374-
return type;
387+
break;
375388
}
376389
case VAR_STRING:
377390
{
378-
String type = "";
379391
HpccSrcType srcType = field.getSourceType();
380392
if (srcType == HpccSrcType.SINGLE_BYTE_CHAR)
381393
{
@@ -394,7 +406,7 @@ else if (srcType == HpccSrcType.UTF16LE || srcType == HpccSrcType.UTF16BE)
394406
{
395407
type += field.getDataLen();
396408
}
397-
return type;
409+
break;
398410
}
399411
case RECORD:
400412
{
@@ -416,13 +428,21 @@ else if (srcType == HpccSrcType.UTF16LE || srcType == HpccSrcType.UTF16BE)
416428
String recordDefnName = "##" + hash + "##";
417429

418430
recordDefinitionMap.put(recordDefnName, definition);
419-
return recordDefnName;
431+
type = recordDefnName;
432+
break;
420433
}
421434
default:
422435
{
423436
throw new Exception("Unable to generate ECL unknown field type: " + field.getFieldType().description());
424437
}
425438
}
439+
440+
if (field.isBlob())
441+
{
442+
type += " {blob}";
443+
}
444+
445+
return type;
426446
}
427447

428448
/**
@@ -648,7 +668,7 @@ else if (srcType == HpccSrcType.UTF16LE || srcType == HpccSrcType.UTF16BE)
648668
*/
649669
private static int getTypeHash(FieldDef field) throws Exception
650670
{
651-
int numHashComponents = 4 + field.getNumDefs();
671+
int numHashComponents = 5 + field.getNumDefs();
652672
if (field.getFieldType() == FieldType.DECIMAL)
653673
{
654674
numHashComponents += 2;
@@ -659,8 +679,9 @@ private static int getTypeHash(FieldDef field) throws Exception
659679
hashComponents[1] = field.getDataLen();
660680
hashComponents[2] = field.getSourceType().ordinal();
661681
hashComponents[3] = field.getAdditionalFlags();
682+
hashComponents[4] = field.isBlob() ? 1 : 0;
662683

663-
int hashCompIndex = 4;
684+
int hashCompIndex = 5;
664685
for (int i = 0; i < field.getNumDefs(); i++, hashCompIndex++)
665686
{
666687
hashComponents[hashCompIndex] = getTypeHash(field.getDef(i));
@@ -698,6 +719,26 @@ private static int getJsonTypeDefinition(FieldDef field, HashMap<Integer, Intege
698719
return typeHash;
699720
}
700721

722+
if (field.isBlob())
723+
{
724+
FieldDef nonBlobField = new FieldDef(field);
725+
nonBlobField.setIsBlob(false);
726+
727+
int nonBlobTypeHash = getJsonTypeDefinition(nonBlobField, typeDefinitionMap, typeDefinitions);
728+
int nonBlobTypeIndex = typeDefinitionMap.get(nonBlobTypeHash);
729+
String nonBlobTypeName = ESP_TYPE_NAME_PREFIX + (nonBlobTypeIndex + 1);
730+
731+
JSONObject typeDef = new JSONObject();
732+
typeDef.put("fieldType", type_blob);
733+
typeDef.put("length", 8);
734+
typeDef.put("child", nonBlobTypeName);
735+
736+
int newTypeIndex = typeDefinitions.size();
737+
typeDefinitions.add(typeDef);
738+
typeDefinitionMap.put(typeHash, newTypeIndex);
739+
return typeHash;
740+
}
741+
701742
JSONObject typeDef = new JSONObject();
702743
int typeID = getTypeID(field);
703744
switch (field.getFieldType())
@@ -753,25 +794,30 @@ private static int getJsonTypeDefinition(FieldDef field, HashMap<Integer, Intege
753794
int childTypeHash = getJsonTypeDefinition(childField, typeDefinitionMap, typeDefinitions);
754795
int childTypeIndex = typeDefinitionMap.get(childTypeHash);
755796
String childTypeName = ESP_TYPE_NAME_PREFIX + (childTypeIndex + 1);
797+
756798
int childTypeID = getTypeID(childField);
799+
if (childField.isBlob())
800+
{
801+
childTypeID = type_blob;
802+
}
757803

758804
JSONObject childJson = new JSONObject();
759-
childJson.put("name", childField.getFieldName());
760-
childJson.put("type", childTypeName);
805+
childJson.put(NAME_KEY, childField.getFieldName());
806+
childJson.put(TYPE_KEY, childTypeName);
761807

762808
int flags = childTypeID | childField.getAdditionalFlags();
763809
if (flags > 0)
764810
{
765-
childJson.put("flags", flags);
811+
childJson.put(FLAGS_KEY, flags);
766812
}
767813

768814
if (childField.getFieldType() == FieldType.DATASET)
769815
{
770-
childJson.put("xpath", childField.getFieldName() + XPATH_DELIMITER + "Row");
816+
childJson.put(XPATH_KEY, childField.getFieldName() + XPATH_DELIMITER + "Row");
771817
}
772818
else if (childField.getFieldType() == FieldType.SET)
773819
{
774-
childJson.put("xpath", childField.getFieldName() + XPATH_DELIMITER + "Item");
820+
childJson.put(XPATH_KEY, childField.getFieldName() + XPATH_DELIMITER + "Item");
775821
}
776822

777823
fields.put(childJson);
@@ -954,6 +1000,14 @@ private static FieldDef parseJsonTypeDefinition(JSONObject jsonTypeDefinitions,
9541000
int typeID = typeDef.getInt(FIELD_TYPE_KEY);
9551001
long length = typeDef.getLong(LENGTH_KEY);
9561002

1003+
if (typeID == type_blob)
1004+
{
1005+
String blobType = typeDef.getString(CHILD_KEY);
1006+
FieldDef def = getOrParseJsonTypeDefintion(blobType, jsonTypeDefinitions, protoTypeDefs);
1007+
def.setIsBlob(true);
1008+
return def;
1009+
}
1010+
9571011
FieldType fieldType = getFieldType(typeID);
9581012
switch (fieldType)
9591013
{

commons-hpcc/src/main/java/org/hpccsystems/commons/ecl/TestFieldDefinitions.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ public class TestFieldDefinitions
6464
+ " \"name\": \"isactive\",\r\n \"type\": \"ty15\",\r\n \"flags\": 65536\r\n },\r\n {\r\n \"name\": \"__internal_fpos__\",\r\n \"type\": \"ty16\",\r\n"
6565
+ " \"flags\": 65821\r\n }\r\n ]\r\n}";
6666

67+
private static final String blobIndexDefinitionStr = "{\n \"ty6\": { \"vinit\": 2, \"length\": 8, \"fieldType\": 285 },\n"
68+
+ " \"ty5\": { \"length\": 8, \"fieldType\": 15, \"child\": \"ty4\" },\n"
69+
+ " \"length\": 36,\n"
70+
+ " \"ty2\": { \"length\": 0, \"fieldType\": 1028 },\n"
71+
+ " \"fields\": [\n"
72+
+ " { \"name\": \"str12\", \"flags\": 4, \"type\": \"ty1\" },\n"
73+
+ " { \"name\": \"content_string\", \"flags\": 65551, \"type\": \"ty3\" },\n"
74+
+ " { \"name\": \"content_data\", \"flags\": 65551, \"type\": \"ty5\" },\n"
75+
+ " { \"name\": \"__internal_fpos__\", \"flags\": 65821, \"type\": \"ty6\" }\n"
76+
+ " ],\n"
77+
+ " \"ty1\": { \"length\": 12, \"fieldType\": 4 },\n"
78+
+ " \"fieldType\": 13,\n"
79+
+ " \"ty4\": { \"length\": 0, \"fieldType\": 1040 },\n"
80+
+ " \"ty3\": { \"length\": 8, \"fieldType\": 15, \"child\": \"ty2\" }\n"
81+
+ "}\n";
82+
6783
/**
6884
* Gets the complex record definition json.
6985
*
@@ -79,6 +95,11 @@ public static String getAllTypesIndexRecordDefinitionJson()
7995
return allTypesIndexRecordDefinitionStr;
8096
}
8197

98+
public static String getBlobIndexDefinitionJson()
99+
{
100+
return blobIndexDefinitionStr;
101+
}
102+
82103
/**
83104
* Gets the complex record definition.
84105
*

commons-hpcc/src/test/java/org/hpccsystems/commons/ecl/RecordDefinitionTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public void setup()
3939
public void testJsonRecordParsing() throws Exception
4040
{
4141
String[] recordDefStrs = new String[] { TestFieldDefinitions.getComplexRecordDefinitionJson(),
42-
TestFieldDefinitions.getAllTypesIndexRecordDefinitionJson() };
42+
TestFieldDefinitions.getAllTypesIndexRecordDefinitionJson(),
43+
TestFieldDefinitions.getBlobIndexDefinitionJson() };
4344
for (String recordDefStr : recordDefStrs)
4445
{
4546
try

dfsclient/src/main/java/org/hpccsystems/dfs/client/HPCCFile.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ private void updateProjectedRecordDef() throws Exception
250250
field.setSourceType(HpccSrcType.LITTLE_ENDIAN);
251251
}
252252

253+
// if (field.isBlob())
254+
// {
255+
// field.setIsBlob(false);
256+
// }
253257
}
254258
}
255259

dfsclient/src/test/java/org/hpccsystems/dfs/client/DFSIndexTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,27 @@ public void biasedIntTest() throws Exception
260260
}
261261
}
262262

263+
@Test
264+
public void indexBlobTest() throws Exception
265+
{
266+
HPCCFile file = new HPCCFile("~test::index::blobs::key", connString , hpccUser, hpccPass);
267+
268+
DataPartition[] fileParts = file.getFileParts();
269+
270+
List<HPCCRecord> records = new ArrayList<HPCCRecord>();
271+
FieldDef originalRD = file.getRecordDefinition();
272+
for (int j = 0; j < fileParts.length; j++)
273+
{
274+
HPCCRecordBuilder recordBuilder = new HPCCRecordBuilder(file.getProjectedRecordDefinition());
275+
HpccRemoteFileReader<HPCCRecord> fileReader = new HpccRemoteFileReader<HPCCRecord>(fileParts[j], originalRD, recordBuilder);
276+
while (fileReader.hasNext())
277+
{
278+
records.add(fileReader.next());
279+
}
280+
fileReader.close();
281+
}
282+
}
283+
263284
private String partitionListToString(List<DataPartition> partitions)
264285
{
265286
String matchedPartitionStr = "[ ";

0 commit comments

Comments
 (0)