| 6557 | |
| 6558 | |
| 6559 | StmtNode* ModifyNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool updateOrInsert) |
| 6560 | { |
| 6561 | auto& pool = dsqlScratch->getPool(); |
| 6562 | |
| 6563 | // Separate old and new context references. |
| 6564 | |
| 6565 | Array<NestConst<ValueExprNode>> orgValues, newValues; |
| 6566 | |
| 6567 | const auto assignments = nodeAs<CompoundStmtNode>(statement); |
| 6568 | fb_assert(assignments); |
| 6569 | |
| 6570 | for (FB_SIZE_T i = 0; i < assignments->statements.getCount(); ++i) |
| 6571 | { |
| 6572 | AssignmentNode* const assign = nodeAs<AssignmentNode>(assignments->statements[i]); |
| 6573 | fb_assert(assign); |
| 6574 | orgValues.add(assign->asgnFrom); |
| 6575 | newValues.add(assign->asgnTo); |
| 6576 | } |
| 6577 | |
| 6578 | NestConst<RelationSourceNode> relation = nodeAs<RelationSourceNode>(dsqlRelation); |
| 6579 | fb_assert(relation); |
| 6580 | |
| 6581 | NestConst<ValueExprNode>* ptr; |
| 6582 | |
| 6583 | const auto node = FB_NEW_POOL(pool) ModifyNode(pool); |
| 6584 | |
| 6585 | if (dsqlReturning && !dsqlScratch->isPsql() && dsqlCursorName.isEmpty()) |
| 6586 | { |
| 6587 | node->dsqlReturningLocalTableNumber = updateOrInsert ? |
| 6588 | dsqlReturningLocalTableNumber.value : |
| 6589 | dsqlScratch->localTableNumber++; |
| 6590 | } |
| 6591 | |
| 6592 | node->dsqlCursorName = dsqlCursorName; |
| 6593 | node->dsqlSkipLocked = dsqlSkipLocked; |
| 6594 | |
| 6595 | if (dsqlCursorName.hasData() && dsqlScratch->isPsql()) |
| 6596 | { |
| 6597 | node->dsqlContext = dsqlPassCursorContext(dsqlScratch, dsqlCursorName, relation); |
| 6598 | node->marks |= StmtNode::MARK_POSITIONED; |
| 6599 | |
| 6600 | // Process old context values. |
| 6601 | dsqlScratch->context->push(node->dsqlContext); |
| 6602 | ++dsqlScratch->scopeLevel; |
| 6603 | |
| 6604 | for (ptr = orgValues.begin(); ptr != orgValues.end(); ++ptr) |
| 6605 | *ptr = doDsqlPass(dsqlScratch, *ptr, false); |
| 6606 | |
| 6607 | --dsqlScratch->scopeLevel; |
| 6608 | dsqlScratch->context->pop(); |
| 6609 | |
| 6610 | // Process relation. |
| 6611 | doDsqlPass(dsqlScratch, node->dsqlRelation, relation, false); |
| 6612 | |
| 6613 | // Process new context values. |
| 6614 | for (ptr = newValues.begin(); ptr != newValues.end(); ++ptr) |
| 6615 | *ptr = doDsqlPass(dsqlScratch, *ptr, false); |
| 6616 |
no test coverage detected