| 998 | |
| 999 | |
| 1000 | void ExtEngineManager::Trigger::setupComputedFields(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb) |
| 1001 | { |
| 1002 | SET_TDBB(tdbb); |
| 1003 | |
| 1004 | USHORT varId = 0; |
| 1005 | |
| 1006 | static_assert(NEW_CONTEXT_VALUE == OLD_CONTEXT_VALUE + 1, "OLD/NEW context assumption."); |
| 1007 | |
| 1008 | for (unsigned context = OLD_CONTEXT_VALUE; context <= NEW_CONTEXT_VALUE; ++context) // OLD (0), NEW (1) |
| 1009 | { |
| 1010 | for (FB_SIZE_T i = 0; i < trg->relation->rel_fields->count(); ++i) |
| 1011 | { |
| 1012 | jrd_fld* field = (*trg->relation->rel_fields)[i]; |
| 1013 | if (!field || !field->fld_computation) |
| 1014 | continue; |
| 1015 | |
| 1016 | if (context == OLD_CONTEXT_VALUE) // count once |
| 1017 | ++computedCount; |
| 1018 | |
| 1019 | DeclareVariableNode* declareNode = FB_NEW_POOL(pool) DeclareVariableNode(pool); |
| 1020 | declareNode->varId = varId; |
| 1021 | |
| 1022 | declareNode->varDesc = trg->relation->rel_current_format->fmt_desc[i]; |
| 1023 | |
| 1024 | // For CHAR fields, change variable type to VARCHAR to avoid manual INTL adjustments for multi-byte. |
| 1025 | if (declareNode->varDesc.isText()) |
| 1026 | { |
| 1027 | declareNode->varDesc.dsc_dtype = dtype_varying; |
| 1028 | declareNode->varDesc.dsc_length += sizeof(USHORT); |
| 1029 | } |
| 1030 | |
| 1031 | varDecls.push(declareNode); |
| 1032 | |
| 1033 | csb->csb_variables = vec<DeclareVariableNode*>::newVector( |
| 1034 | *tdbb->getDefaultPool(), csb->csb_variables, varId); |
| 1035 | |
| 1036 | ValueExprNode* exprNode = FB_NEW_POOL(*tdbb->getDefaultPool()) FieldNode(*tdbb->getDefaultPool(), context, i, true); |
| 1037 | |
| 1038 | VariableNode* varNode = FB_NEW_POOL(pool) VariableNode(pool); |
| 1039 | varNode->varId = varId; |
| 1040 | |
| 1041 | AssignmentNode* assignNode = FB_NEW_POOL(pool) AssignmentNode(pool); |
| 1042 | assignNode->asgnFrom = exprNode; |
| 1043 | assignNode->asgnTo = varNode; |
| 1044 | |
| 1045 | // Do not run the assignment for invalid RPBs (NEW in DELETE, OLD in INSERT). |
| 1046 | |
| 1047 | SLONG* actionPtr = FB_NEW_POOL(pool) SLONG(INFO_TYPE_TRIGGER_ACTION); |
| 1048 | |
| 1049 | LiteralNode* actionLiteral = FB_NEW_POOL(pool) LiteralNode(pool); |
| 1050 | actionLiteral->litDesc.dsc_dtype = dtype_long; |
| 1051 | actionLiteral->litDesc.dsc_length = sizeof(SLONG); |
| 1052 | actionLiteral->litDesc.dsc_scale = 0; |
| 1053 | actionLiteral->litDesc.dsc_sub_type = 0; |
| 1054 | actionLiteral->litDesc.dsc_address = reinterpret_cast<UCHAR*>(actionPtr); |
| 1055 | |
| 1056 | InternalInfoNode* internalInfo = FB_NEW_POOL(pool) InternalInfoNode(pool, actionLiteral); |
| 1057 |
nothing calls this directly
no test coverage detected