Make a new schema consisting only of the top-level fields in the dataset schema that: (a) Have children that require materialization (b) Have children present in `physical_schema` The resulting schema can be used in reader instantiation to ignore unused fields. Note that `physical_schema` is only of structural importance and its data types are ignored when constructing the final schema.
| 203 | // that `physical_schema` is only of structural importance and its data types are ignored |
| 204 | // when constructing the final schema. |
| 205 | Result<std::shared_ptr<Schema>> GetPartialSchema(const ScanOptions& scan_options, |
| 206 | const Schema& physical_schema) { |
| 207 | auto dataset_schema = scan_options.dataset_schema; |
| 208 | DCHECK_NE(dataset_schema, nullptr); |
| 209 | const auto max_num_fields = static_cast<size_t>(dataset_schema->num_fields()); |
| 210 | |
| 211 | std::vector<bool> selected(max_num_fields, false); |
| 212 | std::vector<int> toplevel_indices; |
| 213 | toplevel_indices.reserve(max_num_fields); |
| 214 | |
| 215 | for (const auto& ref : scan_options.MaterializedFields()) { |
| 216 | auto index = TopLevelIndex(ref, *dataset_schema); |
| 217 | DCHECK_GE(index, 0); |
| 218 | if (selected[index]) continue; |
| 219 | |
| 220 | // Determine if the field exists in the physical schema before selecting it |
| 221 | bool found; |
| 222 | if (!ref.IsNested()) { |
| 223 | const auto& name = dataset_schema->field(index)->name(); |
| 224 | found = physical_schema.GetFieldIndex(name) != -1; |
| 225 | } else { |
| 226 | // Check if the nested field is present in the physical schema. If so, we load its |
| 227 | // entire top-level field |
| 228 | ARROW_ASSIGN_OR_RAISE(auto path, ref.FindOne(*dataset_schema)); |
| 229 | auto universal_ref = ToUniversalRef(path, *dataset_schema); |
| 230 | ARROW_ASSIGN_OR_RAISE(auto match, universal_ref.FindOneOrNone(physical_schema)); |
| 231 | found = !match.empty(); |
| 232 | } |
| 233 | |
| 234 | if (!found) continue; |
| 235 | |
| 236 | toplevel_indices.push_back(index); |
| 237 | selected[index] = true; |
| 238 | // All fields in the dataset schema require materialization, so return early |
| 239 | if (toplevel_indices.size() == max_num_fields) { |
| 240 | return dataset_schema; |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | FieldVector fields; |
| 245 | fields.reserve(toplevel_indices.size()); |
| 246 | std::sort(toplevel_indices.begin(), toplevel_indices.end()); |
| 247 | for (auto index : toplevel_indices) { |
| 248 | fields.push_back(dataset_schema->field(index)); |
| 249 | } |
| 250 | |
| 251 | return schema(std::move(fields)); |
| 252 | } |
| 253 | |
| 254 | Result<std::shared_ptr<JsonFragmentScanOptions>> GetJsonFormatOptions( |
| 255 | const JsonFileFormat& format, const ScanOptions* scan_options) { |
no test coverage detected