Turn a parsed scratch into a statement.
| 231 | |
| 232 | // Turn a parsed scratch into a statement. |
| 233 | Statement* Statement::makeStatement(thread_db* tdbb, CompilerScratch* csb, bool internalFlag, |
| 234 | std::function<void ()> beforeCsbRelease) |
| 235 | { |
| 236 | DEV_BLKCHK(csb, type_csb); |
| 237 | SET_TDBB(tdbb); |
| 238 | |
| 239 | const auto dbb = tdbb->getDatabase(); |
| 240 | fb_assert(dbb); |
| 241 | |
| 242 | const auto attachment = tdbb->getAttachment(); |
| 243 | |
| 244 | const auto old_request = tdbb->getRequest(); |
| 245 | tdbb->setRequest(nullptr); |
| 246 | |
| 247 | Statement* statement = nullptr; |
| 248 | |
| 249 | try |
| 250 | { |
| 251 | // Once any expansion required has been done, make a pass to assign offsets |
| 252 | // into the impure area and throw away any unnecessary crude. Execution |
| 253 | // optimizations can be performed here. |
| 254 | |
| 255 | DmlNode::doPass1(tdbb, csb, &csb->csb_node); |
| 256 | |
| 257 | // CVC: I'm going to preallocate the map before the loop to avoid alloc/dealloc calls. |
| 258 | StreamMap localMap; |
| 259 | StreamType* const map = localMap.getBuffer(STREAM_MAP_LENGTH); |
| 260 | |
| 261 | // Copy and compile (pass1) domains DEFAULT and constraints. |
| 262 | MapFieldInfo::Accessor accessor(&csb->csb_map_field_info); |
| 263 | |
| 264 | for (bool found = accessor.getFirst(); found; found = accessor.getNext()) |
| 265 | { |
| 266 | FieldInfo& fieldInfo = accessor.current()->second; |
| 267 | |
| 268 | AutoSetRestore<USHORT> autoRemapVariable(&csb->csb_remap_variable, |
| 269 | (csb->csb_variables ? csb->csb_variables->count() : 0) + 1); |
| 270 | |
| 271 | fieldInfo.defaultValue = NodeCopier::copy(tdbb, csb, fieldInfo.defaultValue, map); |
| 272 | |
| 273 | csb->csb_remap_variable = (csb->csb_variables ? csb->csb_variables->count() : 0) + 1; |
| 274 | |
| 275 | if (fieldInfo.validationExpr) |
| 276 | { |
| 277 | NodeCopier copier(csb->csb_pool, csb, map); |
| 278 | fieldInfo.validationExpr = copier.copy(tdbb, fieldInfo.validationExpr); |
| 279 | } |
| 280 | |
| 281 | DmlNode::doPass1(tdbb, csb, fieldInfo.defaultValue.getAddress()); |
| 282 | DmlNode::doPass1(tdbb, csb, fieldInfo.validationExpr.getAddress()); |
| 283 | } |
| 284 | |
| 285 | if (csb->csb_node) |
| 286 | { |
| 287 | if (csb->csb_node->getKind() == DmlNode::KIND_STATEMENT) |
| 288 | StmtNode::doPass2(tdbb, csb, reinterpret_cast<StmtNode**>(&csb->csb_node), NULL); |
| 289 | else |
| 290 | ExprNode::doPass2(tdbb, csb, &csb->csb_node); |
nothing calls this directly
no test coverage detected