duckdb 0.3.2-dev984.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +2849 -1856
- package/src/duckdb.hpp +1255 -1159
- package/src/parquet-amalgamation.cpp +30856 -30746
- package/src/parquet-amalgamation.hpp +165 -37
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright 2018 DuckDB
|
|
2
|
+
Copyright 2018-2022 Stichting DuckDB Foundation
|
|
3
3
|
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
5
|
|
|
@@ -7069,6 +7069,57 @@ private:
|
|
|
7069
7069
|
|
|
7070
7070
|
|
|
7071
7071
|
|
|
7072
|
+
|
|
7073
|
+
|
|
7074
|
+
namespace duckdb {
|
|
7075
|
+
class ParquetDecodeUtils {
|
|
7076
|
+
|
|
7077
|
+
public:
|
|
7078
|
+
template <class T>
|
|
7079
|
+
static T ZigzagToInt(const T n) {
|
|
7080
|
+
return (n >> 1) ^ -(n & 1);
|
|
7081
|
+
}
|
|
7082
|
+
|
|
7083
|
+
static const uint32_t BITPACK_MASKS[];
|
|
7084
|
+
static const uint8_t BITPACK_DLEN;
|
|
7085
|
+
|
|
7086
|
+
template <typename T>
|
|
7087
|
+
static uint32_t BitUnpack(ByteBuffer &buffer, uint8_t &bitpack_pos, T *dest, uint32_t count, uint8_t width) {
|
|
7088
|
+
auto mask = BITPACK_MASKS[width];
|
|
7089
|
+
|
|
7090
|
+
for (uint32_t i = 0; i < count; i++) {
|
|
7091
|
+
T val = (buffer.get<uint8_t>() >> bitpack_pos) & mask;
|
|
7092
|
+
bitpack_pos += width;
|
|
7093
|
+
while (bitpack_pos > BITPACK_DLEN) {
|
|
7094
|
+
buffer.inc(1);
|
|
7095
|
+
val |= (buffer.get<uint8_t>() << (BITPACK_DLEN - (bitpack_pos - width))) & mask;
|
|
7096
|
+
bitpack_pos -= BITPACK_DLEN;
|
|
7097
|
+
}
|
|
7098
|
+
dest[i] = val;
|
|
7099
|
+
}
|
|
7100
|
+
return count;
|
|
7101
|
+
}
|
|
7102
|
+
|
|
7103
|
+
template <class T>
|
|
7104
|
+
static T VarintDecode(ByteBuffer &buf) {
|
|
7105
|
+
T result = 0;
|
|
7106
|
+
uint8_t shift = 0;
|
|
7107
|
+
while (true) {
|
|
7108
|
+
auto byte = buf.read<uint8_t>();
|
|
7109
|
+
result |= (byte & 127) << shift;
|
|
7110
|
+
if ((byte & 128) == 0)
|
|
7111
|
+
break;
|
|
7112
|
+
shift += 7;
|
|
7113
|
+
if (shift > sizeof(T) * 8) {
|
|
7114
|
+
throw std::runtime_error("Varint-decoding found too large number");
|
|
7115
|
+
}
|
|
7116
|
+
}
|
|
7117
|
+
return result;
|
|
7118
|
+
}
|
|
7119
|
+
};
|
|
7120
|
+
} // namespace duckdb
|
|
7121
|
+
|
|
7122
|
+
|
|
7072
7123
|
namespace duckdb {
|
|
7073
7124
|
|
|
7074
7125
|
class RleBpDecoder {
|
|
@@ -7098,7 +7149,8 @@ public:
|
|
|
7098
7149
|
values_read += repeat_batch;
|
|
7099
7150
|
} else if (literal_count_ > 0) {
|
|
7100
7151
|
uint32_t literal_batch = MinValue(batch_size - values_read, static_cast<uint32_t>(literal_count_));
|
|
7101
|
-
uint32_t actual_read = BitUnpack<T>(values + values_read,
|
|
7152
|
+
uint32_t actual_read = ParquetDecodeUtils::BitUnpack<T>(buffer_, bitpack_pos, values + values_read,
|
|
7153
|
+
literal_batch, bit_width_);
|
|
7102
7154
|
if (literal_batch != actual_read) {
|
|
7103
7155
|
throw std::runtime_error("Did not find enough values");
|
|
7104
7156
|
}
|
|
@@ -7140,26 +7192,7 @@ private:
|
|
|
7140
7192
|
uint8_t byte_encoded_len;
|
|
7141
7193
|
uint32_t max_val;
|
|
7142
7194
|
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
// this is slow but whatever, calls are rare
|
|
7146
|
-
uint32_t VarintDecode() {
|
|
7147
|
-
uint32_t result = 0;
|
|
7148
|
-
uint8_t shift = 0;
|
|
7149
|
-
uint8_t len = 0;
|
|
7150
|
-
while (true) {
|
|
7151
|
-
auto byte = buffer_.read<uint8_t>();
|
|
7152
|
-
len++;
|
|
7153
|
-
result |= (byte & 127) << shift;
|
|
7154
|
-
if ((byte & 128) == 0)
|
|
7155
|
-
break;
|
|
7156
|
-
shift += 7;
|
|
7157
|
-
if (shift > 32) {
|
|
7158
|
-
throw std::runtime_error("Varint-decoding found too large number");
|
|
7159
|
-
}
|
|
7160
|
-
}
|
|
7161
|
-
return result;
|
|
7162
|
-
}
|
|
7195
|
+
uint8_t bitpack_pos = 0;
|
|
7163
7196
|
|
|
7164
7197
|
/// Fills literal_count_ and repeat_count_ with next values. Returns false if there
|
|
7165
7198
|
/// are no more.
|
|
@@ -7171,7 +7204,7 @@ private:
|
|
|
7171
7204
|
buffer_.inc(1);
|
|
7172
7205
|
bitpack_pos = 0;
|
|
7173
7206
|
}
|
|
7174
|
-
auto indicator_value = VarintDecode();
|
|
7207
|
+
auto indicator_value = ParquetDecodeUtils::VarintDecode<uint32_t>(buffer_);
|
|
7175
7208
|
|
|
7176
7209
|
// lsb indicates if it is a literal run or repeated run
|
|
7177
7210
|
bool is_literal = indicator_value & 1;
|
|
@@ -7192,28 +7225,121 @@ private:
|
|
|
7192
7225
|
// TODO complain if we run out of buffer
|
|
7193
7226
|
return true;
|
|
7194
7227
|
}
|
|
7228
|
+
};
|
|
7229
|
+
} // namespace duckdb
|
|
7230
|
+
|
|
7195
7231
|
|
|
7196
|
-
// somewhat optimized implementation that avoids non-alignment
|
|
7197
7232
|
|
|
7198
|
-
|
|
7199
|
-
|
|
7233
|
+
|
|
7234
|
+
namespace duckdb {
|
|
7235
|
+
class DbpDecoder {
|
|
7236
|
+
public:
|
|
7237
|
+
DbpDecoder(const uint8_t *buffer, uint32_t buffer_len) : buffer_((char *)buffer, buffer_len) {
|
|
7238
|
+
|
|
7239
|
+
//<block size in values> <number of miniblocks in a block> <total value count> <first value>
|
|
7240
|
+
// overall header
|
|
7241
|
+
block_value_count = ParquetDecodeUtils::VarintDecode<uint64_t>(buffer_);
|
|
7242
|
+
miniblocks_per_block = ParquetDecodeUtils::VarintDecode<uint64_t>(buffer_);
|
|
7243
|
+
total_value_count = ParquetDecodeUtils::VarintDecode<uint64_t>(buffer_);
|
|
7244
|
+
start_value = ParquetDecodeUtils::ZigzagToInt(ParquetDecodeUtils::VarintDecode<int64_t>(buffer_));
|
|
7245
|
+
|
|
7246
|
+
// some derivatives
|
|
7247
|
+
values_per_miniblock = block_value_count / miniblocks_per_block;
|
|
7248
|
+
miniblock_bit_widths = std::unique_ptr<uint8_t[]>(new data_t[miniblocks_per_block]);
|
|
7249
|
+
|
|
7250
|
+
// init state to something sane
|
|
7251
|
+
values_left_in_block = 0;
|
|
7252
|
+
values_left_in_miniblock = 0;
|
|
7253
|
+
miniblock_offset = 0;
|
|
7254
|
+
min_delta = 0;
|
|
7255
|
+
bitpack_pos = 0;
|
|
7256
|
+
is_first_value = true;
|
|
7257
|
+
};
|
|
7258
|
+
|
|
7259
|
+
ByteBuffer BufferPtr() {
|
|
7260
|
+
if (bitpack_pos != 0) {
|
|
7261
|
+
buffer_.inc(1);
|
|
7262
|
+
bitpack_pos = 0;
|
|
7263
|
+
}
|
|
7264
|
+
return buffer_;
|
|
7265
|
+
}
|
|
7200
7266
|
|
|
7201
7267
|
template <typename T>
|
|
7202
|
-
|
|
7203
|
-
auto
|
|
7268
|
+
void GetBatch(char *values_target_ptr, uint32_t batch_size) {
|
|
7269
|
+
auto values = (T *)values_target_ptr;
|
|
7204
7270
|
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7271
|
+
if (batch_size == 0) {
|
|
7272
|
+
return;
|
|
7273
|
+
}
|
|
7274
|
+
idx_t value_offset = 0;
|
|
7275
|
+
|
|
7276
|
+
if (is_first_value) {
|
|
7277
|
+
values[0] = start_value;
|
|
7278
|
+
value_offset++;
|
|
7279
|
+
is_first_value = false;
|
|
7280
|
+
}
|
|
7281
|
+
|
|
7282
|
+
if (total_value_count == 1) { // I guess it's a special case
|
|
7283
|
+
if (batch_size > 1) {
|
|
7284
|
+
throw std::runtime_error("DBP decode did not find enough values (have 1)");
|
|
7212
7285
|
}
|
|
7213
|
-
|
|
7286
|
+
return;
|
|
7214
7287
|
}
|
|
7215
|
-
|
|
7288
|
+
|
|
7289
|
+
while (value_offset < batch_size) {
|
|
7290
|
+
if (values_left_in_block == 0) { // need to open new block
|
|
7291
|
+
if (bitpack_pos > 0) { // have to eat the leftovers if any
|
|
7292
|
+
buffer_.inc(1);
|
|
7293
|
+
}
|
|
7294
|
+
min_delta = ParquetDecodeUtils::ZigzagToInt(ParquetDecodeUtils::VarintDecode<uint64_t>(buffer_));
|
|
7295
|
+
for (idx_t miniblock_idx = 0; miniblock_idx < miniblocks_per_block; miniblock_idx++) {
|
|
7296
|
+
miniblock_bit_widths[miniblock_idx] = buffer_.read<uint8_t>();
|
|
7297
|
+
// TODO what happens if width is 0?
|
|
7298
|
+
}
|
|
7299
|
+
values_left_in_block = block_value_count;
|
|
7300
|
+
miniblock_offset = 0;
|
|
7301
|
+
bitpack_pos = 0;
|
|
7302
|
+
values_left_in_miniblock = values_per_miniblock;
|
|
7303
|
+
}
|
|
7304
|
+
if (values_left_in_miniblock == 0) {
|
|
7305
|
+
miniblock_offset++;
|
|
7306
|
+
values_left_in_miniblock = values_per_miniblock;
|
|
7307
|
+
}
|
|
7308
|
+
|
|
7309
|
+
auto read_now = MinValue(values_left_in_miniblock, (idx_t)batch_size - value_offset);
|
|
7310
|
+
ParquetDecodeUtils::BitUnpack<T>(buffer_, bitpack_pos, &values[value_offset], read_now,
|
|
7311
|
+
miniblock_bit_widths[miniblock_offset]);
|
|
7312
|
+
for (idx_t i = value_offset; i < value_offset + read_now; i++) {
|
|
7313
|
+
values[i] = ((i == 0) ? start_value : values[i - 1]) + min_delta + values[i];
|
|
7314
|
+
}
|
|
7315
|
+
value_offset += read_now;
|
|
7316
|
+
values_left_in_miniblock -= read_now;
|
|
7317
|
+
values_left_in_block -= read_now;
|
|
7318
|
+
}
|
|
7319
|
+
|
|
7320
|
+
if (value_offset != batch_size) {
|
|
7321
|
+
throw std::runtime_error("DBP decode did not find enough values");
|
|
7322
|
+
}
|
|
7323
|
+
start_value = values[batch_size - 1];
|
|
7216
7324
|
}
|
|
7325
|
+
|
|
7326
|
+
private:
|
|
7327
|
+
ByteBuffer buffer_;
|
|
7328
|
+
idx_t block_value_count;
|
|
7329
|
+
idx_t miniblocks_per_block;
|
|
7330
|
+
idx_t total_value_count;
|
|
7331
|
+
int64_t start_value;
|
|
7332
|
+
idx_t values_per_miniblock;
|
|
7333
|
+
|
|
7334
|
+
std::unique_ptr<uint8_t[]> miniblock_bit_widths;
|
|
7335
|
+
idx_t values_left_in_block;
|
|
7336
|
+
idx_t values_left_in_miniblock;
|
|
7337
|
+
idx_t miniblock_offset;
|
|
7338
|
+
int64_t min_delta;
|
|
7339
|
+
|
|
7340
|
+
bool is_first_value;
|
|
7341
|
+
|
|
7342
|
+
uint8_t bitpack_pos;
|
|
7217
7343
|
};
|
|
7218
7344
|
} // namespace duckdb
|
|
7219
7345
|
|
|
@@ -7325,6 +7451,7 @@ private:
|
|
|
7325
7451
|
void PrepareRead(parquet_filter_t &filter);
|
|
7326
7452
|
void PreparePage(idx_t compressed_page_size, idx_t uncompressed_page_size);
|
|
7327
7453
|
void PrepareDataPage(PageHeader &page_hdr);
|
|
7454
|
+
void PreparePageV2(PageHeader &page_hdr);
|
|
7328
7455
|
|
|
7329
7456
|
const duckdb_parquet::format::ColumnChunk *chunk;
|
|
7330
7457
|
|
|
@@ -7340,6 +7467,7 @@ private:
|
|
|
7340
7467
|
unique_ptr<RleBpDecoder> dict_decoder;
|
|
7341
7468
|
unique_ptr<RleBpDecoder> defined_decoder;
|
|
7342
7469
|
unique_ptr<RleBpDecoder> repeated_decoder;
|
|
7470
|
+
unique_ptr<DbpDecoder> dbp_decoder;
|
|
7343
7471
|
|
|
7344
7472
|
// dummies for Skip()
|
|
7345
7473
|
parquet_filter_t none_filter;
|