| 397 | } |
| 398 | |
| 399 | ExprPtr compileRewrittenExpression( |
| 400 | const TypedExprPtr& expr, |
| 401 | Scope* scope, |
| 402 | const core::QueryConfig& config, |
| 403 | memory::MemoryPool* pool, |
| 404 | const std::unordered_set<std::string>& flatteningCandidates, |
| 405 | bool enableConstantFolding) { |
| 406 | ExprPtr alreadyCompiled = getAlreadyCompiled(expr.get(), &scope->visited); |
| 407 | if (alreadyCompiled) { |
| 408 | if (!alreadyCompiled->isMultiplyReferenced()) { |
| 409 | scope->exprSet->addToReset(alreadyCompiled); |
| 410 | alreadyCompiled->setMultiplyReferenced(); |
| 411 | // A property of this expression changed, namely isMultiplyReferenced_, |
| 412 | // that affects metadata, so we re-compute it. |
| 413 | alreadyCompiled->clearMetaData(); |
| 414 | alreadyCompiled->computeMetadata(); |
| 415 | } |
| 416 | return alreadyCompiled; |
| 417 | } |
| 418 | |
| 419 | const bool trackCpuUsage = config.exprTrackCpuUsage(); |
| 420 | |
| 421 | ExprPtr result; |
| 422 | auto resultType = expr->type(); |
| 423 | auto compiledInputs = compileInputs( |
| 424 | expr, scope, config, pool, flatteningCandidates, enableConstantFolding); |
| 425 | auto inputTypes = getTypes(compiledInputs); |
| 426 | bool isConstantExpr = false; |
| 427 | if (dynamic_cast<const core::ConcatTypedExpr*>(expr.get())) { |
| 428 | result = getSpecialForm( |
| 429 | config, |
| 430 | RowConstructorCallToSpecialForm::kRowConstructor, |
| 431 | resultType, |
| 432 | std::move(compiledInputs), |
| 433 | trackCpuUsage); |
| 434 | } else if (auto cast = dynamic_cast<const core::CastTypedExpr*>(expr.get())) { |
| 435 | BOLT_CHECK(!compiledInputs.empty()); |
| 436 | if (FOLLY_UNLIKELY(*resultType == *compiledInputs[0]->type())) { |
| 437 | result = compiledInputs[0]; |
| 438 | } else { |
| 439 | result = getSpecialForm( |
| 440 | config, |
| 441 | cast->nullOnFailure() ? "try_cast" : "cast", |
| 442 | resultType, |
| 443 | std::move(compiledInputs), |
| 444 | trackCpuUsage); |
| 445 | } |
| 446 | } else if (auto call = dynamic_cast<const core::CallTypedExpr*>(expr.get())) { |
| 447 | if (auto specialForm = getSpecialForm( |
| 448 | config, |
| 449 | call->name(), |
| 450 | resultType, |
| 451 | std::move(compiledInputs), |
| 452 | trackCpuUsage)) { |
| 453 | result = specialForm; |
| 454 | } else if ( |
| 455 | auto func = getVectorFunction( |
| 456 | call->name(), |
no test coverage detected