| 229 | } |
| 230 | |
| 231 | TableFunction Binder::getScanFunction(const FileTypeInfo& typeInfo, |
| 232 | const FileScanInfo& fileScanInfo) const { |
| 233 | Function* func = nullptr; |
| 234 | std::vector<LogicalType> inputTypes; |
| 235 | inputTypes.push_back(LogicalType::STRING()); |
| 236 | auto catalog = Catalog::Get(*clientContext); |
| 237 | auto transaction = transaction::Transaction::Get(*clientContext); |
| 238 | switch (typeInfo.fileType) { |
| 239 | case FileType::PARQUET: { |
| 240 | auto entry = catalog->getFunctionEntry(transaction, ParquetScanFunction::name); |
| 241 | func = BuiltInFunctionsUtils::matchFunction(ParquetScanFunction::name, inputTypes, |
| 242 | entry->ptrCast<FunctionCatalogEntry>()); |
| 243 | } break; |
| 244 | case FileType::NPY: { |
| 245 | auto entry = catalog->getFunctionEntry(transaction, NpyScanFunction::name); |
| 246 | func = BuiltInFunctionsUtils::matchFunction(NpyScanFunction::name, inputTypes, |
| 247 | entry->ptrCast<FunctionCatalogEntry>()); |
| 248 | } break; |
| 249 | case FileType::CSV: { |
| 250 | bool containCompressedCSV = std::any_of(fileScanInfo.filePaths.begin(), |
| 251 | fileScanInfo.filePaths.end(), [&](const auto& file) { |
| 252 | return VirtualFileSystem::GetUnsafe(*clientContext)->isCompressedFile(file); |
| 253 | }); |
| 254 | auto csvConfig = CSVReaderConfig::construct(fileScanInfo.options); |
| 255 | // Parallel CSV scanning is only allowed: |
| 256 | // 1. No newline character inside the csv body. |
| 257 | // 2. The CSV file to scan is not compressed (because we couldn't perform seek in such |
| 258 | // case). |
| 259 | // 3. Not explicitly set by the user to use the serial csv reader. |
| 260 | auto name = (csvConfig.parallel && !containCompressedCSV) ? ParallelCSVScan::name : |
| 261 | SerialCSVScan::name; |
| 262 | auto entry = catalog->getFunctionEntry(transaction, name); |
| 263 | func = BuiltInFunctionsUtils::matchFunction(name, inputTypes, |
| 264 | entry->ptrCast<FunctionCatalogEntry>()); |
| 265 | } break; |
| 266 | case FileType::UNKNOWN: { |
| 267 | try { |
| 268 | auto name = std::format("{}_SCAN", typeInfo.fileTypeStr); |
| 269 | auto entry = catalog->getFunctionEntry(transaction, name); |
| 270 | func = BuiltInFunctionsUtils::matchFunction(name, inputTypes, |
| 271 | entry->ptrCast<FunctionCatalogEntry>()); |
| 272 | } catch (...) { |
| 273 | if (typeInfo.fileTypeStr == "") { |
| 274 | throw BinderException{"Cannot infer the format of the given file. Please " |
| 275 | "set the file format explicitly by (file_format=<type>)."}; |
| 276 | } |
| 277 | throw BinderException{ |
| 278 | std::format("Cannot load from file type {}. If this file type is part of a lbug " |
| 279 | "extension please load the extension then try again.", |
| 280 | typeInfo.fileTypeStr)}; |
| 281 | } |
| 282 | } break; |
| 283 | default: |
| 284 | UNREACHABLE_CODE; |
| 285 | } |
| 286 | return *func->ptrCast<TableFunction>(); |
| 287 | } |
| 288 |
no test coverage detected