blob: f2ca6be376a06165de8cc3e744445caa7fbb0711 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "orc/ColumnPrinter.hh"
#include "orc/Exceptions.hh"
#include "wrap/gtest-wrapper.h"
namespace orc {
TEST(TestColumnPrinter, BooleanColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(BOOLEAN);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
LongVectorBatch batch(1024, *getDefaultPool());
const char *expected[] = {"true", "false", "true"};
batch.numElements = 3;
batch.hasNulls = false;
batch.data[0] = 1;
batch.data[1] = 0;
batch.data[2] = 1;
printer->reset(batch);
for(uint64_t i=0; i < 3; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line);
}
const char *expected2[] = {"null", "null", "true", "false"};
batch.numElements = 4;
batch.data[3] = false;
batch.hasNulls = true;
batch.notNull[0] = false;
batch.notNull[1] = false;
batch.notNull[2] = true;
batch.notNull[3] = true;
printer->reset(batch);
for(uint64_t i=0; i < 4; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected2[i], line);
}
}
TEST(TestColumnPrinter, LongColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(LONG);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
LongVectorBatch batch(1024, *getDefaultPool());
batch.numElements = 2;
batch.hasNulls = false;
batch.data[0] = 9223372036854775807LL;
batch.data[1] = -9223372036854775807LL;
printer->reset(batch);
const char *expected[] = {"9223372036854775807", "-9223372036854775807"};
for(uint64_t i=0; i < 2; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line);
}
batch.numElements = 3;
batch.hasNulls = true;
batch.data[0] = 127;
batch.data[1] = -127;
batch.data[2] = 123;
batch.notNull[0] = true;
batch.notNull[1] = true;
batch.notNull[2] = false;
printer->reset(batch);
const char *expected2[] = {"127", "-127", "null"};
for(uint64_t i=0; i < 3; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected2[i], line);
}
}
TEST(TestColumnPrinter, DoubleColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(DOUBLE);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
DoubleVectorBatch batch(1024, *getDefaultPool());
batch.numElements = 2;
batch.hasNulls = false;
batch.data[0] = 1234.5;
batch.data[1] = -1234.5;
printer->reset(batch);
const char *expected[] = {"1234.5", "-1234.5"};
for(uint64_t i=0; i < 2; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line);
}
batch.numElements = 3;
batch.hasNulls = true;
batch.data[0] = 9999.125;
batch.data[1] = -9999.125;
batch.data[2] = 100000;
batch.notNull[0] = true;
batch.notNull[1] = true;
batch.notNull[2] = false;
printer->reset(batch);
const char *expected2[] = {"9999.125", "-9999.125", "null"};
for(uint64_t i=0; i < 3; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected2[i], line);
}
}
TEST(TestColumnPrinter, TimestampColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(TIMESTAMP);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
TimestampVectorBatch batch(1024, *getDefaultPool());
batch.numElements = 12;
batch.hasNulls = false;
batch.data[0] = 1420070400;
batch.data[1] = 963273600;
batch.data[2] = 1426172459;
batch.data[3] = 1426172459;
batch.data[4] = 1426172459;
batch.data[5] = 1426172459;
batch.data[6] = 1426172459;
batch.data[7] = 1426172459;
batch.data[8] = 1426172459;
batch.data[9] = 1426172459;
batch.data[10] = 1426172459;
batch.data[11] = 1426172459;
batch.nanoseconds[0] = 0;
batch.nanoseconds[1] = 0;
batch.nanoseconds[2] = 0;
batch.nanoseconds[3] = 1;
batch.nanoseconds[4] = 10;
batch.nanoseconds[5] = 100;
batch.nanoseconds[6] = 1000;
batch.nanoseconds[7] = 10000;
batch.nanoseconds[8] = 100000;
batch.nanoseconds[9] = 1000000;
batch.nanoseconds[10] = 10000000;
batch.nanoseconds[11] = 100000000;
const char *expected[] = {"\"2015-01-01 00:00:00.0\"",
"\"2000-07-11 00:00:00.0\"",
"\"2015-03-12 15:00:59.0\"",
"\"2015-03-12 15:00:59.000000001\"",
"\"2015-03-12 15:00:59.00000001\"",
"\"2015-03-12 15:00:59.0000001\"",
"\"2015-03-12 15:00:59.000001\"",
"\"2015-03-12 15:00:59.00001\"",
"\"2015-03-12 15:00:59.0001\"",
"\"2015-03-12 15:00:59.001\"",
"\"2015-03-12 15:00:59.01\"",
"\"2015-03-12 15:00:59.1\""};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, DateColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(DATE);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
LongVectorBatch batch(1024, *getDefaultPool());
batch.numElements = 10;
batch.hasNulls = false;
batch.data[0] = 0;
batch.data[1] = 11738;
batch.data[2] = -165;
batch.data[3] = -33165;
batch.data[4] = 10489;
batch.data[5] = -5171;
batch.data[6] = 11016;
batch.data[7] = 5763;
batch.data[8] = 16729;
batch.data[9] = 12275;
const char *expected[] = {"\"1970-01-01\"",
"\"2002-02-20\"",
"\"1969-07-20\"",
"\"1879-03-14\"",
"\"1998-09-20\"",
"\"1955-11-05\"",
"\"2000-02-29\"",
"\"1985-10-12\"",
"\"2015-10-21\"",
"\"2003-08-11\""};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
#ifndef HAS_PRE_1970
if (batch.data[i] < 0) continue;
#endif
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
#ifndef HAS_PRE_1970
if (batch.data[i] < 0) continue;
#endif
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, Decimal64ColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createDecimalType(16, 5);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
Decimal64VectorBatch batch(1024, *getDefaultPool());
batch.numElements = 10;
batch.hasNulls = false;
batch.scale = 5;
batch.values[0] = 0;
batch.values[1] = 1;
batch.values[2] = -10;
batch.values[3] = 100;
batch.values[4] = 1000;
batch.values[5] = 10000;
batch.values[6] = 100000;
batch.values[7] = 1000000;
batch.values[8] = -10000000;
batch.values[9] = 100000000;
const char *expected[] = { "0.00000",
"0.00001",
"-0.00010",
"0.00100",
"0.01000",
"0.10000",
"1.00000",
"10.00000",
"-100.00000",
"1000.00000"};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, Decimal128ColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createDecimalType(30, 5);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
Decimal128VectorBatch batch(1024, *getDefaultPool());
batch.numElements = 10;
batch.hasNulls = false;
batch.scale = 5;
batch.values[0] = 0;
batch.values[1] = 1;
batch.values[2] = -10;
batch.values[3] = 100;
batch.values[4] = 1000;
batch.values[5] = 10000;
batch.values[6] = 100000;
batch.values[7] = 1000000;
batch.values[8] = -10000000;
batch.values[9] = 100000000;
const char *expected[] = { "0.00000",
"0.00001",
"-0.00010",
"0.00100",
"0.01000",
"0.10000",
"1.00000",
"10.00000",
"-100.00000",
"1000.00000"};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, StringColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(STRING);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
StringVectorBatch batch(1024, *getDefaultPool());
const char *blob= "thisisatest\b\f\n\r\t\\\"'";
batch.numElements = 5;
batch.hasNulls = false;
batch.data[0] = const_cast<char *>(blob);
batch.length[0] = 4;
batch.length[1] = 2;
batch.length[2] = 1;
batch.length[3] = 4;
batch.length[4] = 8;
for(size_t i=1; i < 5; ++i) {
batch.data[i] = batch.data.data()[i - 1] +
static_cast<size_t>(batch.length[i - 1]);
}
const char *expected[] = {"\"this\"", "\"is\"", "\"a\"", "\"test\"",
"\"\\b\\f\\n\\r\\t\\\\\\\"'\""};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, BinaryColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createPrimitiveType(BINARY);
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
StringVectorBatch batch(1024, *getDefaultPool());
char blob[45];
for(size_t i=0; i < sizeof(blob); ++i) {
blob[i] = static_cast<char>(i);
}
batch.numElements = 10;
batch.hasNulls = false;
batch.data[0] = blob;
batch.length[0] = 0;
for(size_t i=1; i < batch.numElements; ++i) {
batch.length[i] = static_cast<int64_t>(i);
batch.data[i] = batch.data.data()[i - 1] + batch.length[i - 1];
}
printer->reset(batch);
const char* expected[] = {"[]",
"[0]",
"[1, 2]",
"[3, 4, 5]",
"[6, 7, 8, 9]",
"[10, 11, 12, 13, 14]",
"[15, 16, 17, 18, 19, 20]",
"[21, 22, 23, 24, 25, 26, 27]",
"[28, 29, 30, 31, 32, 33, 34, 35]",
"[36, 37, 38, 39, 40, 41, 42, 43, 44]"};
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, ListColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createListType(createPrimitiveType(LONG));
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
ListVectorBatch batch(1024, *getDefaultPool());
LongVectorBatch* longBatch = new LongVectorBatch(1024, *getDefaultPool());
batch.elements = std::unique_ptr<ColumnVectorBatch>(longBatch);
batch.numElements = 10;
batch.hasNulls = false;
batch.offsets[0] = 0;
for(size_t i = 1; i <= batch.numElements; ++i) {
batch.offsets[i] = batch.offsets[i-1] + static_cast<int64_t>(i-1);
}
longBatch->numElements = 45;
longBatch->hasNulls = false;
for(size_t i = 0; i < longBatch->numElements; ++i) {
longBatch->data[i] = static_cast<int64_t>(i);
}
const char* expected[] = {"[]",
"[0]",
"[1, 2]",
"[3, 4, 5]",
"[6, 7, 8, 9]",
"[10, 11, 12, 13, 14]",
"[15, 16, 17, 18, 19, 20]",
"[21, 22, 23, 24, 25, 26, 27]",
"[28, 29, 30, 31, 32, 33, 34, 35]",
"[36, 37, 38, 39, 40, 41, 42, 43, 44]"};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, MapColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createMapType(createPrimitiveType(LONG),
createPrimitiveType(LONG));
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
MapVectorBatch batch(1024, *getDefaultPool());
LongVectorBatch* keyBatch = new LongVectorBatch(1024, *getDefaultPool());
LongVectorBatch* valueBatch = new LongVectorBatch(1024, *getDefaultPool());
batch.keys = std::unique_ptr<ColumnVectorBatch>(keyBatch);
batch.elements = std::unique_ptr<ColumnVectorBatch>(valueBatch);
batch.numElements = 4;
batch.hasNulls = false;
batch.offsets[0] = 0;
for(size_t i = 1; i <= batch.numElements; ++i) {
batch.offsets[i] = batch.offsets[i-1] + static_cast<int64_t>(i-1);
}
keyBatch->numElements = 6;
keyBatch->hasNulls = false;
valueBatch->numElements = 6;
valueBatch->hasNulls = false;
for(size_t i = 0; i < keyBatch->numElements; ++i) {
keyBatch->data[i] = static_cast<int64_t>(i);
valueBatch->data[i] = static_cast<int64_t>(2 * i);
}
const char* expected[] = {"[]",
"[{\"key\": 0, \"value\": 0}]",
("[{\"key\": 1, \"value\": 2},"
" {\"key\": 2, \"value\": 4}]"),
("[{\"key\": 3, \"value\": 6},"
" {\"key\": 4, \"value\": 8},"
" {\"key\": 5, \"value\": 10}]")};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
TEST(TestColumnPrinter, StructColumnPrinter) {
std::string line;
std::unique_ptr<Type> type = createStructType();
type->addStructField("first", createPrimitiveType(LONG));
type->addStructField("second", createPrimitiveType(LONG));
std::unique_ptr<ColumnPrinter> printer =
createColumnPrinter(line, type.get());
StructVectorBatch batch(1024, *getDefaultPool());
LongVectorBatch* firstBatch = new LongVectorBatch(1024, *getDefaultPool());
LongVectorBatch* secondBatch =
new LongVectorBatch(1024, *getDefaultPool());
batch.fields.push_back(firstBatch);
batch.fields.push_back(secondBatch);
batch.numElements = 10;
batch.hasNulls = false;
firstBatch->numElements = 10;
firstBatch->hasNulls = false;
secondBatch->numElements = 10;
secondBatch->hasNulls = false;
for(size_t i = 0; i < firstBatch->numElements; ++i) {
firstBatch->data[i] = static_cast<int64_t>(i);
secondBatch->data[i] = static_cast<int64_t>(2 * i);
}
const char* expected[] = {"{\"first\": 0, \"second\": 0}",
"{\"first\": 1, \"second\": 2}",
"{\"first\": 2, \"second\": 4}",
"{\"first\": 3, \"second\": 6}",
"{\"first\": 4, \"second\": 8}",
"{\"first\": 5, \"second\": 10}",
"{\"first\": 6, \"second\": 12}",
"{\"first\": 7, \"second\": 14}",
"{\"first\": 8, \"second\": 16}",
"{\"first\": 9, \"second\": 18}"};
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
EXPECT_EQ(expected[i], line) << "for i = " << i;
}
batch.hasNulls = true;
for(size_t i = 0; i < batch.numElements; ++i) {
batch.notNull[i] = i % 2;
}
printer->reset(batch);
for(uint64_t i=0; i < batch.numElements; ++i) {
line.clear();
printer->printRow(i);
if (i % 2) {
EXPECT_EQ(expected[i], line) << "for i = " << i;
} else {
EXPECT_EQ("null", line) << "for i = " << i;
}
}
}
} // namespace orc