| 261 | } |
| 262 | |
| 263 | std::unique_ptr<BoundBaseScanSource> Binder::bindObjectScanSource(const BaseScanSource& scanSource, |
| 264 | const options_t& options, const std::vector<std::string>& columnNames, |
| 265 | const std::vector<LogicalType>& columnTypes) { |
| 266 | auto objectSource = scanSource.constPtrCast<ObjectScanSource>(); |
| 267 | TableFunction func; |
| 268 | std::unique_ptr<TableFuncBindData> bindData; |
| 269 | std::string objectName; |
| 270 | auto bindInput = TableFuncBindInput(); |
| 271 | bindInput.binder = this; |
| 272 | if (objectSource->objectNames.size() == 1) { |
| 273 | // Bind external object as table |
| 274 | objectName = objectSource->objectNames[0]; |
| 275 | auto replacementData = clientContext->tryReplaceByName(objectName); |
| 276 | if (replacementData != nullptr) { // Replace as python object |
| 277 | func = replacementData->func; |
| 278 | auto replaceExtraInput = std::make_unique<ExtraScanTableFuncBindInput>(); |
| 279 | replaceExtraInput->fileScanInfo.options = bindParsingOptions(options); |
| 280 | auto localBindInput = std::move(replacementData->bindInput); |
| 281 | localBindInput.extraInput = std::move(replaceExtraInput); |
| 282 | localBindInput.binder = this; |
| 283 | bindData = func.bindFunc(clientContext, &localBindInput); |
| 284 | } else if (main::DatabaseManager::Get(*clientContext)->hasDefaultDatabase()) { |
| 285 | auto dbName = main::DatabaseManager::Get(*clientContext)->getDefaultDatabase(); |
| 286 | func = getObjectScanFunc(dbName, objectSource->objectNames[0], clientContext); |
| 287 | bindData = func.bindFunc(clientContext, &bindInput); |
| 288 | } else { |
| 289 | throw BinderException(ExceptionMessage::variableNotInScope(objectName)); |
| 290 | } |
| 291 | } else if (objectSource->objectNames.size() == 2) { |
| 292 | // Bind external database table |
| 293 | objectName = objectSource->objectNames[0] + "." + objectSource->objectNames[1]; |
| 294 | func = getObjectScanFunc(objectSource->objectNames[0], objectSource->objectNames[1], |
| 295 | clientContext); |
| 296 | bindData = func.bindFunc(clientContext, &bindInput); |
| 297 | } else { |
| 298 | // LCOV_EXCL_START |
| 299 | throw BinderException(std::format("Cannot find object {}.", |
| 300 | StringUtils::join(objectSource->objectNames, ","))); |
| 301 | // LCOV_EXCL_STOP |
| 302 | } |
| 303 | auto info = bindTableScanSourceInfo(*this, func, objectName, std::move(bindData), columnNames, |
| 304 | columnTypes); |
| 305 | return std::make_unique<BoundTableScanSource>(ScanSourceType::OBJECT, std::move(info)); |
| 306 | } |
| 307 | |
| 308 | std::unique_ptr<BoundBaseScanSource> Binder::bindTableFuncScanSource( |
| 309 | const BaseScanSource& scanSource, const options_t& options, |
nothing calls this directly
no test coverage detected