parquet 0.7.3 → 0.9.0
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.
- checksums.yaml +4 -4
- data/Cargo.lock +125 -72
- data/Gemfile +1 -0
- data/README.md +134 -6
- data/ext/parquet/Cargo.toml +6 -6
- data/ext/parquet/src/adapter_ffi.rs +175 -34
- data/ext/parquet/src/lib.rs +2 -1
- data/ext/parquet-core/Cargo.toml +8 -8
- data/ext/parquet-core/src/arrow_conversion.rs +234 -290
- data/ext/parquet-core/src/error.rs +28 -2
- data/ext/parquet-core/src/lib.rs +4 -1
- data/ext/parquet-core/src/reader.rs +104 -52
- data/ext/parquet-core/src/schema.rs +171 -4
- data/ext/parquet-core/src/streaming_file_writer.rs +672 -0
- data/ext/parquet-core/src/streaming_file_writer_test.rs +168 -0
- data/ext/parquet-core/src/test_utils.rs +1 -1
- data/ext/parquet-core/src/traits/schema.rs +46 -7
- data/ext/parquet-core/src/value.rs +201 -3
- data/ext/parquet-core/src/writer.rs +587 -264
- data/ext/parquet-core/tests/arrow_conversion_tests.rs +54 -35
- data/ext/parquet-core/tests/binary_data.rs +1 -1
- data/ext/parquet-core/tests/column_projection.rs +1 -1
- data/ext/parquet-core/tests/complex_types.rs +1 -1
- data/ext/parquet-core/tests/compression_tests.rs +1 -1
- data/ext/parquet-core/tests/concurrent_access.rs +10 -9
- data/ext/parquet-core/tests/decimal_tests.rs +7 -7
- data/ext/parquet-core/tests/edge_cases_corner_cases.rs +1 -1
- data/ext/parquet-core/tests/error_handling_comprehensive_tests.rs +18 -25
- data/ext/parquet-core/tests/null_handling_tests.rs +1 -1
- data/ext/parquet-core/tests/primitive_types.rs +1 -1
- data/ext/parquet-core/tests/real_world_patterns.rs +2 -2
- data/ext/parquet-core/tests/review_regressions.rs +787 -0
- data/ext/parquet-core/tests/roundtrip_correctness.rs +1 -1
- data/ext/parquet-core/tests/schema_comprehensive_tests.rs +8 -0
- data/ext/parquet-core/tests/streaming_writer.rs +391 -0
- data/ext/parquet-core/tests/temporal_tests.rs +1 -1
- data/ext/parquet-core/tests/test_helpers.rs +1 -1
- data/ext/parquet-core/tests/writer_tests.rs +1 -1
- data/ext/parquet-ruby-adapter/Cargo.toml +6 -5
- data/ext/parquet-ruby-adapter/src/converter.rs +20 -23
- data/ext/parquet-ruby-adapter/src/error.rs +14 -21
- data/ext/parquet-ruby-adapter/src/lib.rs +13 -9
- data/ext/parquet-ruby-adapter/src/logger.rs +5 -2
- data/ext/parquet-ruby-adapter/src/metadata.rs +15 -15
- data/ext/parquet-ruby-adapter/src/reader.rs +67 -52
- data/ext/parquet-ruby-adapter/src/repack/mod.rs +600 -0
- data/ext/parquet-ruby-adapter/src/repack/output.rs +550 -0
- data/ext/parquet-ruby-adapter/src/repack/plan.rs +492 -0
- data/ext/parquet-ruby-adapter/src/schema.rs +137 -102
- data/ext/parquet-ruby-adapter/src/string_cache.rs +72 -62
- data/ext/parquet-ruby-adapter/src/string_cache_test.rs +122 -0
- data/ext/parquet-ruby-adapter/src/string_storage.rs +632 -0
- data/ext/parquet-ruby-adapter/src/types.rs +27 -9
- data/ext/parquet-ruby-adapter/src/utils.rs +318 -78
- data/ext/parquet-ruby-adapter/src/writer.rs +703 -340
- data/lib/parquet/schema.rb +6 -2
- data/lib/parquet/version.rb +1 -1
- data/lib/parquet.rbi +115 -16
- metadata +25 -3
- data/ext/parquet-ruby-adapter/src/batch_manager.rs +0 -116
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d6e1c27061809c378723ba1917a02d427034cbcca336cb13018b6782f02a39f
|
|
4
|
+
data.tar.gz: 8682402a2c0007384c851a7a3d5f68f2b758f11ca3b6c196fbae3153f3751848
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 19075351b7cdc6616c896979d9b4d871aa599f8c8c0d13e52e48aa75d3df3f94f6a1824ae27b81b9321329183a5ad4b2db38647711583b0e8bf885f3f2ab0a3f
|
|
7
|
+
data.tar.gz: e3240b3224aac0e536a8c88e65cf022ded919afb6b8cd193f0f1e064934e1449a13d3ca0c36a9c559dc48a780b76e390dba45b313b4deb3a19ec4f764b61dffa
|
data/Cargo.lock
CHANGED
|
@@ -63,8 +63,9 @@ dependencies = [
|
|
|
63
63
|
|
|
64
64
|
[[package]]
|
|
65
65
|
name = "arrow"
|
|
66
|
-
version = "
|
|
67
|
-
source = "
|
|
66
|
+
version = "58.3.0"
|
|
67
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
68
|
+
checksum = "378530e55cd479eda3c14eb345310799717e6f76d0c332041e8487022166b471"
|
|
68
69
|
dependencies = [
|
|
69
70
|
"arrow-arith",
|
|
70
71
|
"arrow-array",
|
|
@@ -83,21 +84,23 @@ dependencies = [
|
|
|
83
84
|
|
|
84
85
|
[[package]]
|
|
85
86
|
name = "arrow-arith"
|
|
86
|
-
version = "
|
|
87
|
-
source = "
|
|
87
|
+
version = "58.3.0"
|
|
88
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
89
|
+
checksum = "a0ab212d2c1886e802f51c5212d78ebbcbb0bec980fff9dadc1eb8d45cd0b738"
|
|
88
90
|
dependencies = [
|
|
89
91
|
"arrow-array",
|
|
90
92
|
"arrow-buffer",
|
|
91
93
|
"arrow-data",
|
|
92
94
|
"arrow-schema",
|
|
93
95
|
"chrono",
|
|
94
|
-
"num",
|
|
96
|
+
"num-traits",
|
|
95
97
|
]
|
|
96
98
|
|
|
97
99
|
[[package]]
|
|
98
100
|
name = "arrow-array"
|
|
99
|
-
version = "
|
|
100
|
-
source = "
|
|
101
|
+
version = "58.3.0"
|
|
102
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
103
|
+
checksum = "cfd33d3e92f207444098c75b42de99d329562be0cf686b307b097cc52b4e999e"
|
|
101
104
|
dependencies = [
|
|
102
105
|
"ahash",
|
|
103
106
|
"arrow-buffer",
|
|
@@ -105,28 +108,34 @@ dependencies = [
|
|
|
105
108
|
"arrow-schema",
|
|
106
109
|
"chrono",
|
|
107
110
|
"half",
|
|
108
|
-
"hashbrown",
|
|
109
|
-
"num",
|
|
111
|
+
"hashbrown 0.17.1",
|
|
112
|
+
"num-complex",
|
|
113
|
+
"num-integer",
|
|
114
|
+
"num-traits",
|
|
110
115
|
]
|
|
111
116
|
|
|
112
117
|
[[package]]
|
|
113
118
|
name = "arrow-buffer"
|
|
114
|
-
version = "
|
|
115
|
-
source = "
|
|
119
|
+
version = "58.3.0"
|
|
120
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
121
|
+
checksum = "0c6cd424c2693bcdbc150d843dc9d4d137dd2de4782ce6df491ad11a3a0416c0"
|
|
116
122
|
dependencies = [
|
|
117
123
|
"bytes",
|
|
118
124
|
"half",
|
|
119
|
-
"num",
|
|
125
|
+
"num-bigint",
|
|
126
|
+
"num-traits",
|
|
120
127
|
]
|
|
121
128
|
|
|
122
129
|
[[package]]
|
|
123
130
|
name = "arrow-cast"
|
|
124
|
-
version = "
|
|
125
|
-
source = "
|
|
131
|
+
version = "58.3.0"
|
|
132
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
133
|
+
checksum = "4c5aefb56a2c02e9e2b30746241058b85f8983f0fcff2ba0c6d09006e1cded7f"
|
|
126
134
|
dependencies = [
|
|
127
135
|
"arrow-array",
|
|
128
136
|
"arrow-buffer",
|
|
129
137
|
"arrow-data",
|
|
138
|
+
"arrow-ord",
|
|
130
139
|
"arrow-schema",
|
|
131
140
|
"arrow-select",
|
|
132
141
|
"atoi",
|
|
@@ -134,14 +143,15 @@ dependencies = [
|
|
|
134
143
|
"chrono",
|
|
135
144
|
"half",
|
|
136
145
|
"lexical-core",
|
|
137
|
-
"num",
|
|
146
|
+
"num-traits",
|
|
138
147
|
"ryu",
|
|
139
148
|
]
|
|
140
149
|
|
|
141
150
|
[[package]]
|
|
142
151
|
name = "arrow-csv"
|
|
143
|
-
version = "
|
|
144
|
-
source = "
|
|
152
|
+
version = "58.3.0"
|
|
153
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
154
|
+
checksum = "e94e8cf7e517657a52b91ea1263acf38c4ca62a84655d72458a3359b12ab97de"
|
|
145
155
|
dependencies = [
|
|
146
156
|
"arrow-array",
|
|
147
157
|
"arrow-cast",
|
|
@@ -154,53 +164,62 @@ dependencies = [
|
|
|
154
164
|
|
|
155
165
|
[[package]]
|
|
156
166
|
name = "arrow-data"
|
|
157
|
-
version = "
|
|
158
|
-
source = "
|
|
167
|
+
version = "58.3.0"
|
|
168
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
169
|
+
checksum = "3c88210023a2bfee1896af366309a3028fc3bcbd6515fa29a7990ee1baa08ee0"
|
|
159
170
|
dependencies = [
|
|
160
171
|
"arrow-buffer",
|
|
161
172
|
"arrow-schema",
|
|
162
173
|
"half",
|
|
163
|
-
"num",
|
|
174
|
+
"num-integer",
|
|
175
|
+
"num-traits",
|
|
164
176
|
]
|
|
165
177
|
|
|
166
178
|
[[package]]
|
|
167
179
|
name = "arrow-ipc"
|
|
168
|
-
version = "
|
|
169
|
-
source = "
|
|
180
|
+
version = "58.3.0"
|
|
181
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
182
|
+
checksum = "238438f0834483703d88896db6fe5a7138b2230debc31b34c0336c2996e3c64f"
|
|
170
183
|
dependencies = [
|
|
171
184
|
"arrow-array",
|
|
172
185
|
"arrow-buffer",
|
|
173
186
|
"arrow-data",
|
|
174
187
|
"arrow-schema",
|
|
188
|
+
"arrow-select",
|
|
175
189
|
"flatbuffers",
|
|
176
190
|
"lz4_flex",
|
|
177
191
|
]
|
|
178
192
|
|
|
179
193
|
[[package]]
|
|
180
194
|
name = "arrow-json"
|
|
181
|
-
version = "
|
|
182
|
-
source = "
|
|
195
|
+
version = "58.3.0"
|
|
196
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
197
|
+
checksum = "205ca2119e6d679d5c133c6f30e68f027738d95ed948cf77677ea69c7800036b"
|
|
183
198
|
dependencies = [
|
|
184
199
|
"arrow-array",
|
|
185
200
|
"arrow-buffer",
|
|
186
201
|
"arrow-cast",
|
|
187
|
-
"arrow-
|
|
202
|
+
"arrow-ord",
|
|
188
203
|
"arrow-schema",
|
|
204
|
+
"arrow-select",
|
|
189
205
|
"chrono",
|
|
190
206
|
"half",
|
|
191
207
|
"indexmap",
|
|
208
|
+
"itoa",
|
|
192
209
|
"lexical-core",
|
|
193
210
|
"memchr",
|
|
194
|
-
"num",
|
|
195
|
-
"
|
|
211
|
+
"num-traits",
|
|
212
|
+
"ryu",
|
|
213
|
+
"serde_core",
|
|
196
214
|
"serde_json",
|
|
197
215
|
"simdutf8",
|
|
198
216
|
]
|
|
199
217
|
|
|
200
218
|
[[package]]
|
|
201
219
|
name = "arrow-ord"
|
|
202
|
-
version = "
|
|
203
|
-
source = "
|
|
220
|
+
version = "58.3.0"
|
|
221
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
222
|
+
checksum = "1bffd8fd2579286a5d63bac898159873e5094a79009940bcb42bbfce4f19f1d0"
|
|
204
223
|
dependencies = [
|
|
205
224
|
"arrow-array",
|
|
206
225
|
"arrow-buffer",
|
|
@@ -211,8 +230,9 @@ dependencies = [
|
|
|
211
230
|
|
|
212
231
|
[[package]]
|
|
213
232
|
name = "arrow-row"
|
|
214
|
-
version = "
|
|
215
|
-
source = "
|
|
233
|
+
version = "58.3.0"
|
|
234
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
235
|
+
checksum = "bab5994731204603c73ba69267616c50f80780774c6bb0476f1f830625115e0c"
|
|
216
236
|
dependencies = [
|
|
217
237
|
"arrow-array",
|
|
218
238
|
"arrow-buffer",
|
|
@@ -223,30 +243,33 @@ dependencies = [
|
|
|
223
243
|
|
|
224
244
|
[[package]]
|
|
225
245
|
name = "arrow-schema"
|
|
226
|
-
version = "
|
|
227
|
-
source = "
|
|
246
|
+
version = "58.3.0"
|
|
247
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
248
|
+
checksum = "f633dbfdf39c039ada1bf9e34c694816eb71fbb7dc78f613993b7245e078a1ed"
|
|
228
249
|
dependencies = [
|
|
229
|
-
"
|
|
250
|
+
"serde_core",
|
|
230
251
|
"serde_json",
|
|
231
252
|
]
|
|
232
253
|
|
|
233
254
|
[[package]]
|
|
234
255
|
name = "arrow-select"
|
|
235
|
-
version = "
|
|
236
|
-
source = "
|
|
256
|
+
version = "58.3.0"
|
|
257
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
258
|
+
checksum = "8cd065c54172ac787cf3f2f8d4107e0d3fdc26edba76fdf4f4cc170258942222"
|
|
237
259
|
dependencies = [
|
|
238
260
|
"ahash",
|
|
239
261
|
"arrow-array",
|
|
240
262
|
"arrow-buffer",
|
|
241
263
|
"arrow-data",
|
|
242
264
|
"arrow-schema",
|
|
243
|
-
"num",
|
|
265
|
+
"num-traits",
|
|
244
266
|
]
|
|
245
267
|
|
|
246
268
|
[[package]]
|
|
247
269
|
name = "arrow-string"
|
|
248
|
-
version = "
|
|
249
|
-
source = "
|
|
270
|
+
version = "58.3.0"
|
|
271
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
272
|
+
checksum = "29dd7cda3ab9692f43a2e4acc444d760cc17b12bb6d8232ddf64e9bab7c06b42"
|
|
250
273
|
dependencies = [
|
|
251
274
|
"arrow-array",
|
|
252
275
|
"arrow-buffer",
|
|
@@ -254,7 +277,7 @@ dependencies = [
|
|
|
254
277
|
"arrow-schema",
|
|
255
278
|
"arrow-select",
|
|
256
279
|
"memchr",
|
|
257
|
-
"num",
|
|
280
|
+
"num-traits",
|
|
258
281
|
"regex",
|
|
259
282
|
"regex-syntax",
|
|
260
283
|
]
|
|
@@ -551,6 +574,12 @@ version = "0.15.4"
|
|
|
551
574
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
552
575
|
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
|
553
576
|
|
|
577
|
+
[[package]]
|
|
578
|
+
name = "hashbrown"
|
|
579
|
+
version = "0.17.1"
|
|
580
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
581
|
+
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|
582
|
+
|
|
554
583
|
[[package]]
|
|
555
584
|
name = "iana-time-zone"
|
|
556
585
|
version = "0.1.63"
|
|
@@ -582,7 +611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
582
611
|
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
|
583
612
|
dependencies = [
|
|
584
613
|
"equivalent",
|
|
585
|
-
"hashbrown",
|
|
614
|
+
"hashbrown 0.15.4",
|
|
586
615
|
]
|
|
587
616
|
|
|
588
617
|
[[package]]
|
|
@@ -827,30 +856,30 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
|
|
827
856
|
|
|
828
857
|
[[package]]
|
|
829
858
|
name = "lz4_flex"
|
|
830
|
-
version = "0.
|
|
859
|
+
version = "0.13.1"
|
|
831
860
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
832
|
-
checksum = "
|
|
861
|
+
checksum = "7ef0d4ed8669f8f8826eb00dc878084aa8f253506c4fd5e8f58f5bce72ddb97e"
|
|
833
862
|
dependencies = [
|
|
834
863
|
"twox-hash",
|
|
835
864
|
]
|
|
836
865
|
|
|
837
866
|
[[package]]
|
|
838
867
|
name = "magnus"
|
|
839
|
-
version = "0.
|
|
868
|
+
version = "0.8.2"
|
|
840
869
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
841
|
-
checksum = "
|
|
870
|
+
checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
|
|
842
871
|
dependencies = [
|
|
843
872
|
"magnus-macros",
|
|
844
873
|
"rb-sys",
|
|
845
|
-
"rb-sys-env
|
|
874
|
+
"rb-sys-env",
|
|
846
875
|
"seq-macro",
|
|
847
876
|
]
|
|
848
877
|
|
|
849
878
|
[[package]]
|
|
850
879
|
name = "magnus-macros"
|
|
851
|
-
version = "0.
|
|
880
|
+
version = "0.8.0"
|
|
852
881
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
853
|
-
checksum = "
|
|
882
|
+
checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
|
|
854
883
|
dependencies = [
|
|
855
884
|
"proc-macro2",
|
|
856
885
|
"quote",
|
|
@@ -1013,11 +1042,11 @@ dependencies = [
|
|
|
1013
1042
|
"mimalloc",
|
|
1014
1043
|
"num",
|
|
1015
1044
|
"ordered-float 5.0.0",
|
|
1016
|
-
"parquet
|
|
1045
|
+
"parquet 58.3.0",
|
|
1017
1046
|
"parquet-ruby-adapter",
|
|
1018
1047
|
"rand",
|
|
1019
1048
|
"rb-sys",
|
|
1020
|
-
"rb-sys-env
|
|
1049
|
+
"rb-sys-env",
|
|
1021
1050
|
"simdutf8",
|
|
1022
1051
|
"tempfile",
|
|
1023
1052
|
"thiserror",
|
|
@@ -1026,13 +1055,13 @@ dependencies = [
|
|
|
1026
1055
|
|
|
1027
1056
|
[[package]]
|
|
1028
1057
|
name = "parquet"
|
|
1029
|
-
version = "
|
|
1030
|
-
source = "
|
|
1058
|
+
version = "58.3.0"
|
|
1059
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1060
|
+
checksum = "5dafa7d01085b62a47dd0c1829550a0a36710ea9c4fe358a05a85477cec8a908"
|
|
1031
1061
|
dependencies = [
|
|
1032
1062
|
"ahash",
|
|
1033
1063
|
"arrow-array",
|
|
1034
1064
|
"arrow-buffer",
|
|
1035
|
-
"arrow-cast",
|
|
1036
1065
|
"arrow-data",
|
|
1037
1066
|
"arrow-ipc",
|
|
1038
1067
|
"arrow-schema",
|
|
@@ -1043,10 +1072,11 @@ dependencies = [
|
|
|
1043
1072
|
"chrono",
|
|
1044
1073
|
"flate2",
|
|
1045
1074
|
"half",
|
|
1046
|
-
"hashbrown",
|
|
1075
|
+
"hashbrown 0.17.1",
|
|
1047
1076
|
"lz4_flex",
|
|
1048
|
-
"num",
|
|
1049
1077
|
"num-bigint",
|
|
1078
|
+
"num-integer",
|
|
1079
|
+
"num-traits",
|
|
1050
1080
|
"paste",
|
|
1051
1081
|
"seq-macro",
|
|
1052
1082
|
"serde_json",
|
|
@@ -1070,11 +1100,13 @@ dependencies = [
|
|
|
1070
1100
|
"jiff",
|
|
1071
1101
|
"num",
|
|
1072
1102
|
"ordered-float 5.0.0",
|
|
1073
|
-
"parquet
|
|
1103
|
+
"parquet 58.3.0",
|
|
1074
1104
|
"rand",
|
|
1075
1105
|
"serde",
|
|
1076
1106
|
"tempfile",
|
|
1077
1107
|
"thiserror",
|
|
1108
|
+
"thrift",
|
|
1109
|
+
"triomphe",
|
|
1078
1110
|
"uuid",
|
|
1079
1111
|
]
|
|
1080
1112
|
|
|
@@ -1090,12 +1122,13 @@ dependencies = [
|
|
|
1090
1122
|
"magnus",
|
|
1091
1123
|
"num",
|
|
1092
1124
|
"ordered-float 5.0.0",
|
|
1093
|
-
"parquet
|
|
1125
|
+
"parquet 58.3.0",
|
|
1094
1126
|
"parquet-core",
|
|
1095
1127
|
"rb-sys",
|
|
1096
|
-
"rb-sys-env
|
|
1128
|
+
"rb-sys-env",
|
|
1097
1129
|
"tempfile",
|
|
1098
1130
|
"thiserror",
|
|
1131
|
+
"triomphe",
|
|
1099
1132
|
"uuid",
|
|
1100
1133
|
]
|
|
1101
1134
|
|
|
@@ -1190,18 +1223,18 @@ dependencies = [
|
|
|
1190
1223
|
|
|
1191
1224
|
[[package]]
|
|
1192
1225
|
name = "rb-sys"
|
|
1193
|
-
version = "0.9.
|
|
1226
|
+
version = "0.9.124"
|
|
1194
1227
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1195
|
-
checksum = "
|
|
1228
|
+
checksum = "c85c4188462601e2aa1469def389c17228566f82ea72f137ed096f21591bc489"
|
|
1196
1229
|
dependencies = [
|
|
1197
1230
|
"rb-sys-build",
|
|
1198
1231
|
]
|
|
1199
1232
|
|
|
1200
1233
|
[[package]]
|
|
1201
1234
|
name = "rb-sys-build"
|
|
1202
|
-
version = "0.9.
|
|
1235
|
+
version = "0.9.124"
|
|
1203
1236
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1204
|
-
checksum = "
|
|
1237
|
+
checksum = "568068db4102230882e6d4ae8de6632e224ca75fe5970f6e026a04e91ed635d3"
|
|
1205
1238
|
dependencies = [
|
|
1206
1239
|
"bindgen",
|
|
1207
1240
|
"lazy_static",
|
|
@@ -1212,12 +1245,6 @@ dependencies = [
|
|
|
1212
1245
|
"syn",
|
|
1213
1246
|
]
|
|
1214
1247
|
|
|
1215
|
-
[[package]]
|
|
1216
|
-
name = "rb-sys-env"
|
|
1217
|
-
version = "0.1.2"
|
|
1218
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1219
|
-
checksum = "a35802679f07360454b418a5d1735c89716bde01d35b1560fc953c1415a0b3bb"
|
|
1220
|
-
|
|
1221
1248
|
[[package]]
|
|
1222
1249
|
name = "rb-sys-env"
|
|
1223
1250
|
version = "0.2.2"
|
|
@@ -1307,18 +1334,28 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
|
|
1307
1334
|
|
|
1308
1335
|
[[package]]
|
|
1309
1336
|
name = "serde"
|
|
1310
|
-
version = "1.0.
|
|
1337
|
+
version = "1.0.228"
|
|
1338
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1339
|
+
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
|
1340
|
+
dependencies = [
|
|
1341
|
+
"serde_core",
|
|
1342
|
+
"serde_derive",
|
|
1343
|
+
]
|
|
1344
|
+
|
|
1345
|
+
[[package]]
|
|
1346
|
+
name = "serde_core"
|
|
1347
|
+
version = "1.0.228"
|
|
1311
1348
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1312
|
-
checksum = "
|
|
1349
|
+
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
|
1313
1350
|
dependencies = [
|
|
1314
1351
|
"serde_derive",
|
|
1315
1352
|
]
|
|
1316
1353
|
|
|
1317
1354
|
[[package]]
|
|
1318
1355
|
name = "serde_derive"
|
|
1319
|
-
version = "1.0.
|
|
1356
|
+
version = "1.0.228"
|
|
1320
1357
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1321
|
-
checksum = "
|
|
1358
|
+
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|
1322
1359
|
dependencies = [
|
|
1323
1360
|
"proc-macro2",
|
|
1324
1361
|
"quote",
|
|
@@ -1361,6 +1398,12 @@ version = "1.1.1"
|
|
|
1361
1398
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1362
1399
|
checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
|
|
1363
1400
|
|
|
1401
|
+
[[package]]
|
|
1402
|
+
name = "stable_deref_trait"
|
|
1403
|
+
version = "1.2.1"
|
|
1404
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1405
|
+
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
|
1406
|
+
|
|
1364
1407
|
[[package]]
|
|
1365
1408
|
name = "static_assertions"
|
|
1366
1409
|
version = "1.1.0"
|
|
@@ -1431,6 +1474,16 @@ dependencies = [
|
|
|
1431
1474
|
"crunchy",
|
|
1432
1475
|
]
|
|
1433
1476
|
|
|
1477
|
+
[[package]]
|
|
1478
|
+
name = "triomphe"
|
|
1479
|
+
version = "0.1.15"
|
|
1480
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1481
|
+
checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39"
|
|
1482
|
+
dependencies = [
|
|
1483
|
+
"serde",
|
|
1484
|
+
"stable_deref_trait",
|
|
1485
|
+
]
|
|
1486
|
+
|
|
1434
1487
|
[[package]]
|
|
1435
1488
|
name = "twox-hash"
|
|
1436
1489
|
version = "2.1.1"
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -145,6 +145,33 @@ puts metadata["row_groups"].size # Number of row groups
|
|
|
145
145
|
|
|
146
146
|
## Writing Parquet Files
|
|
147
147
|
|
|
148
|
+
`write_rows` and `write_columns` stream an enumerable to a path or writable IO
|
|
149
|
+
and return `nil`. Each row is an array in schema order. For column writing, each
|
|
150
|
+
yielded batch contains one array per field, all of the same length.
|
|
151
|
+
|
|
152
|
+
Both methods require `schema:` and `write_to:`. `schema:` accepts the array form
|
|
153
|
+
shown below, a `Parquet::Schema` DSL result, or a `fields` schema hash. Use `nil`
|
|
154
|
+
or `[]` to infer string columns named `f0`, `f1`, ... from the first row or
|
|
155
|
+
batch. Empty input requires an explicit schema.
|
|
156
|
+
|
|
157
|
+
`compression:` accepts `"none"`, `"uncompressed"`, `"snappy"`, `"gzip"`,
|
|
158
|
+
`"lz4"`, `"zstd"`, and `"brotli"`; `nil` defaults to Snappy.
|
|
159
|
+
`flush_threshold:` defaults to 100 MiB. `logger:` accepts a Ruby logger with
|
|
160
|
+
`debug`, `info`, `warn`, and `error` methods.
|
|
161
|
+
|
|
162
|
+
`write_rows` also accepts `batch_size:`, `sample_size:`, and `string_cache:`.
|
|
163
|
+
Without `batch_size:`, sizing starts at 1,000 rows and adapts to row size; the
|
|
164
|
+
cap is 1,000,000 rows and lower for wide schemas. Sampling defaults to 100 rows
|
|
165
|
+
and is capped at 10,000. `string_cache: true` uses a capacity of 100, or you can
|
|
166
|
+
pass a capacity up to 65,536; `nil` and `false` disable it.
|
|
167
|
+
|
|
168
|
+
Path output is staged and atomically published only after the complete file has
|
|
169
|
+
been written. On Unix, replacing an existing path preserves its uid, gid, and
|
|
170
|
+
mode and uses standard last-committer-wins rename semantics; creating a path is
|
|
171
|
+
no-clobber. Extended attributes and ACLs are not preserved. IO output is first
|
|
172
|
+
staged on disk, then copied to the IO; a failed copy may leave the IO partially
|
|
173
|
+
written.
|
|
174
|
+
|
|
148
175
|
### Row-wise Writing
|
|
149
176
|
|
|
150
177
|
Best for: Streaming data, converting from other formats, memory-constrained environments
|
|
@@ -159,17 +186,109 @@ schema = [
|
|
|
159
186
|
]
|
|
160
187
|
|
|
161
188
|
# Stream data from any enumerable
|
|
162
|
-
rows = CSV.foreach("input.csv").map do |row|
|
|
189
|
+
rows = CSV.foreach("input.csv").lazy.map do |row|
|
|
163
190
|
[row[0].to_i, row[1], row[2] == "true", row[3].to_f]
|
|
164
191
|
end
|
|
165
192
|
|
|
166
193
|
Parquet.write_rows(rows,
|
|
167
194
|
schema: schema,
|
|
168
195
|
write_to: "output.parquet",
|
|
169
|
-
batch_size: 5000
|
|
196
|
+
batch_size: 5000
|
|
197
|
+
)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Repacking Existing Parquet Files
|
|
201
|
+
|
|
202
|
+
Concatenate Parquet files and re-split them into differently sized files without
|
|
203
|
+
translating rows through Ruby.
|
|
204
|
+
|
|
205
|
+
```ruby
|
|
206
|
+
Parquet.repack(
|
|
207
|
+
["input-0.parquet", "input-1.parquet"],
|
|
208
|
+
output_dir: "repacked",
|
|
209
|
+
rows_per_file: 100_000
|
|
170
210
|
)
|
|
211
|
+
# => [{ "path" => "repacked/batch-0.parquet", "num_rows" => 100_000 },
|
|
212
|
+
# { "path" => "repacked/batch-1.parquet", "num_rows" => 42_137 }]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The outputs hold exactly the input rows, in input order. Every output but the
|
|
216
|
+
last holds `rows_per_file` rows, and there is always at least one output even
|
|
217
|
+
when the inputs are empty. Omit `rows_per_file:` to concatenate everything into
|
|
218
|
+
a single file.
|
|
219
|
+
|
|
220
|
+
Each output's Parquet schema is identical to the first input's, and that input's
|
|
221
|
+
file-level key/value metadata (`ARROW:schema`, `pandas`, and so on) is carried
|
|
222
|
+
over. Inputs must agree on leaf column shape — path, physical and logical type,
|
|
223
|
+
nesting — but may differ in key/value metadata and Parquet field ids.
|
|
224
|
+
|
|
225
|
+
#### Compression and copying
|
|
226
|
+
|
|
227
|
+
With no `compression:`, each column keeps its own codec — Parquet records one
|
|
228
|
+
per column, and a file may legitimately use several. Naming a codec applies it
|
|
229
|
+
to every column instead:
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
Parquet.repack("input.parquet", output_dir: "out", compression: "zstd")
|
|
171
233
|
```
|
|
172
234
|
|
|
235
|
+
Keeping the inputs' codecs also lets repack copy whole row groups into the
|
|
236
|
+
output byte-for-byte, skipping decompression and re-encoding entirely. A row
|
|
237
|
+
group is copied when it fits the output's remaining row budget, is large enough
|
|
238
|
+
to be worth copying, and the request did not ask for a different codec;
|
|
239
|
+
otherwise its rows are decoded and re-encoded. Both routes produce the same
|
|
240
|
+
rows, so which one runs is not something callers need to reason about — but the
|
|
241
|
+
copy route is dramatically faster, so a plain concatenation is close to an
|
|
242
|
+
I/O-bound copy.
|
|
243
|
+
|
|
244
|
+
Small row groups are deliberately merged rather than copied: copying them
|
|
245
|
+
one-for-one would make a compaction of many small files reproduce exactly the
|
|
246
|
+
fragmentation it was meant to remove.
|
|
247
|
+
|
|
248
|
+
#### Output directory ownership
|
|
249
|
+
|
|
250
|
+
`repack` owns the `{output_file_prefix}-{n}.parquet` names in `output_dir`. If
|
|
251
|
+
any already exist it raises `ArgumentError` rather than mixing two runs' files
|
|
252
|
+
in one directory:
|
|
253
|
+
|
|
254
|
+
```ruby
|
|
255
|
+
Parquet.repack("input.parquet", output_dir: "out", rows_per_file: 1000, overwrite: true)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
`overwrite: true` replaces that set and deletes members left over from a longer
|
|
259
|
+
earlier run, so the returned list always equals what a reader finds in the
|
|
260
|
+
directory. Files outside the set are never touched.
|
|
261
|
+
|
|
262
|
+
#### Bounds
|
|
263
|
+
|
|
264
|
+
`max_read_rows_per_chunk:` (default 8192, reduced for wide schemas) bounds rows
|
|
265
|
+
buffered while reading; output row groups are bounded in rows by the same slot
|
|
266
|
+
budget. Both are resource controls: varying them cannot change the returned
|
|
267
|
+
list, the rows, the schema, or the codecs. They do shift compressed byte counts
|
|
268
|
+
and page boundaries, which are representation rather than contract.
|
|
269
|
+
|
|
270
|
+
Input metadata is read one file at a time, so peak memory is set by the widest
|
|
271
|
+
single file and its row-group size, not by how many files you pass or how many
|
|
272
|
+
rows they hold in total. Note that the row-group bound is in rows, not bytes: a
|
|
273
|
+
schema with very large values still buffers one row group's worth of encoded
|
|
274
|
+
data.
|
|
275
|
+
|
|
276
|
+
Reading and writing run with the GVL released, so other Ruby threads keep
|
|
277
|
+
running and `Interrupt` / `Timeout` are honoured. An interrupted call leaves no
|
|
278
|
+
output behind.
|
|
279
|
+
|
|
280
|
+
A repacked output is capped at 32,767 row groups. Merging small groups keeps
|
|
281
|
+
that limit out of reach in practice; if a single output would exceed it,
|
|
282
|
+
repack raises rather than writing an unreadable file, and `rows_per_file:` is
|
|
283
|
+
the way out.
|
|
284
|
+
|
|
285
|
+
#### Page indexes and other optional structures
|
|
286
|
+
|
|
287
|
+
Every row group in a Parquet file must agree on whether it carries a page index,
|
|
288
|
+
and a copied row group can only contribute the index its source had. So an
|
|
289
|
+
output carries one exactly when every contributing input does. Bloom filters are
|
|
290
|
+
not carried over on either route.
|
|
291
|
+
|
|
173
292
|
### Column-wise Writing
|
|
174
293
|
|
|
175
294
|
Best for: Pre-columnar data, better compression, higher performance
|
|
@@ -196,7 +315,7 @@ schema = [
|
|
|
196
315
|
Parquet.write_columns(batches.each,
|
|
197
316
|
schema: schema,
|
|
198
317
|
write_to: "output.parquet",
|
|
199
|
-
compression: "snappy"
|
|
318
|
+
compression: "snappy"
|
|
200
319
|
)
|
|
201
320
|
```
|
|
202
321
|
|
|
@@ -340,7 +459,7 @@ Parquet.write_rows(data.each, schema: schema, write_to: "complex.parquet")
|
|
|
340
459
|
|
|
341
460
|
### Timezone Handling in Parquet
|
|
342
461
|
|
|
343
|
-
|
|
462
|
+
The Parquet specification has a fundamental limitation with timezone storage:
|
|
344
463
|
|
|
345
464
|
1. **UTC-normalized**: Any timestamp with timezone info (including "+09:00" or "America/New_York") is converted to UTC
|
|
346
465
|
2. **Local/unzoned**: Timestamps without timezone info are stored as-is
|
|
@@ -382,11 +501,20 @@ Control memory usage with flush thresholds:
|
|
|
382
501
|
Parquet.write_rows(huge_dataset.each,
|
|
383
502
|
schema: schema,
|
|
384
503
|
write_to: "output.parquet",
|
|
385
|
-
batch_size:
|
|
386
|
-
flush_threshold: 32 * 1024**2
|
|
504
|
+
batch_size: 1_000,
|
|
505
|
+
flush_threshold: 32 * 1024**2 # 32 MiB
|
|
387
506
|
)
|
|
388
507
|
```
|
|
389
508
|
|
|
509
|
+
Writer-owned memory stays bounded as the file grows. `flush_threshold` controls
|
|
510
|
+
the converted-value buffer; a single larger row may exceed it temporarily. The
|
|
511
|
+
row-group target is at least 8 MiB, and each file may contain up to 32,768 row
|
|
512
|
+
groups.
|
|
513
|
+
|
|
514
|
+
Encoded data and completed row-group metadata are staged on disk, so large
|
|
515
|
+
writes need temporary disk space. Ruby still owns the current row or batch, and
|
|
516
|
+
an in-memory destination such as `StringIO` holds the output in memory.
|
|
517
|
+
|
|
390
518
|
## Architecture
|
|
391
519
|
|
|
392
520
|
This gem uses a modular architecture:
|