Turn a cursor reference into a record selection expression.
| 10185 | |
| 10186 | // Turn a cursor reference into a record selection expression. |
| 10187 | static RseNode* dsqlPassCursorReference(DsqlCompilerScratch* dsqlScratch, const MetaName& cursor, |
| 10188 | RelationSourceNode* relation_name) |
| 10189 | { |
| 10190 | DEV_BLKCHK(dsqlScratch, dsql_type_req); |
| 10191 | |
| 10192 | thread_db* tdbb = JRD_get_thread_data(); |
| 10193 | MemoryPool& pool = *tdbb->getDefaultPool(); |
| 10194 | |
| 10195 | // Lookup parent dsqlScratch |
| 10196 | |
| 10197 | const auto* const symbol = dsqlScratch->getAttachment()->dbb_cursors.get(cursor.c_str()); |
| 10198 | |
| 10199 | if (!symbol) |
| 10200 | { |
| 10201 | // cursor is not found |
| 10202 | ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) << |
| 10203 | Arg::Gds(isc_dsql_cursor_err) << |
| 10204 | Arg::Gds(isc_dsql_cursor_not_found) << cursor); |
| 10205 | } |
| 10206 | |
| 10207 | auto parent = *symbol; |
| 10208 | |
| 10209 | // Verify that the cursor is appropriate and updatable |
| 10210 | |
| 10211 | dsql_par* source = dsqlFindDbKey(parent->getDsqlStatement(), relation_name); |
| 10212 | dsql_par* rv_source = dsqlFindRecordVersion(parent->getDsqlStatement(), relation_name); |
| 10213 | |
| 10214 | if (!source || !rv_source) |
| 10215 | { |
| 10216 | // cursor is not updatable |
| 10217 | ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-510) << |
| 10218 | Arg::Gds(isc_dsql_cursor_update_err) << cursor); |
| 10219 | } |
| 10220 | |
| 10221 | const auto statement = static_cast<DsqlDmlStatement*>(dsqlScratch->getDsqlStatement()); |
| 10222 | |
| 10223 | statement->setParentRequest(parent); |
| 10224 | statement->setParentDbKey(source); |
| 10225 | statement->setParentRecVersion(rv_source); |
| 10226 | parent->cursors.add(statement); |
| 10227 | |
| 10228 | // Build record selection expression |
| 10229 | |
| 10230 | RseNode* rse = FB_NEW_POOL(pool) RseNode(pool); |
| 10231 | rse->dsqlStreams = FB_NEW_POOL(pool) RecSourceListNode(pool, 1); |
| 10232 | RelationSourceNode* relation_node = nodeAs<RelationSourceNode>(PASS1_relation(dsqlScratch, relation_name)); |
| 10233 | rse->dsqlStreams->items[0] = relation_node; |
| 10234 | |
| 10235 | RecordKeyNode* dbKeyNode = FB_NEW_POOL(pool) RecordKeyNode(pool, blr_dbkey); |
| 10236 | dbKeyNode->dsqlRelation = relation_node; |
| 10237 | |
| 10238 | dsql_par* parameter = MAKE_parameter(statement->getSendMsg(), false, false, 0, NULL); |
| 10239 | statement->setDbKey(parameter); |
| 10240 | |
| 10241 | ParameterNode* paramNode = FB_NEW_POOL(pool) ParameterNode(pool); |
| 10242 | paramNode->dsqlParameterIndex = parameter->par_index; |
| 10243 | paramNode->dsqlParameter = parameter; |
| 10244 | parameter->par_desc = source->par_desc; |
no test coverage detected