diff --git a/src/assemble.js b/src/assemble.js index a317866..373fda0 100644 --- a/src/assemble.js +++ b/src/assemble.js @@ -49,13 +49,21 @@ export function assembleObjects( // Add value or null based on definition level if (def === maxDefinitionLevel) { + if (!currentContainer) { + throw new Error('parquet assembleObjects: currentContainer is undefined') + } currentContainer.push(values[valueIndex++]) - } else if (isNull && def < maxDefinitionLevel) { - // Go up one level to add null + } else if (isNull) { if (def) { - containerStack.pop() - // @ts-expect-error won't be empty - currentContainer = containerStack.at(-1) + // TODO: Go up maxDefinitionLevel - def - 1 levels to add null + for (let j = def; j < maxDefinitionLevel - 1; j++) { + containerStack.pop() + // @ts-expect-error won't be empty + currentContainer = containerStack.at(-1) + } + if (def > 1) { + currentContainer.push(undefined) + } } else { currentContainer.push(undefined) } diff --git a/test/assemble.test.js b/test/assemble.test.js index 4ac0ccd..ae2a8eb 100644 --- a/test/assemble.test.js +++ b/test/assemble.test.js @@ -83,9 +83,25 @@ describe('assembleObjects', () => { expect(result).toEqual([[[]]]) }) - it('should handle isNull correctly', () => { + it('should handle isNull', () => { // from nonnullable.impala.parquet const result = assembleObjects([2], [0], [-1], false, 2, 2) expect(result).toEqual([[[-1]]]) }) + + it('should handle nullable int_array', () => { + // from nullable.impala.parquet + // [1 2 3][N 1 2 N 3 N][ ] N N + const definitionLevels = [3, 3, 3, 2, 3, 3, 2, 3, 2, 1, 0, 0] + const repetitionLevels = [0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0] + const values = [1, 2, 3, 1, 2, 3] + const result = assembleObjects(definitionLevels, repetitionLevels, values, true, 3, 1) + expect(result).toEqual([ + [1, 2, 3], + [undefined, 1, 2, undefined, 3, undefined], + [], + undefined, + undefined, + ]) + }) })