Parse some procedure parameters.
| 1169 | |
| 1170 | // Parse some procedure parameters. |
| 1171 | void PAR_procedure_parms(thread_db* tdbb, CompilerScratch* csb, jrd_prc* procedure, |
| 1172 | MessageNode** message_ptr, ValueListNode** sourceList, ValueListNode** targetList, bool input_flag) |
| 1173 | { |
| 1174 | SET_TDBB(tdbb); |
| 1175 | SLONG count = csb->csb_blr_reader.getWord(); |
| 1176 | const SLONG inputCount = procedure->getInputFields().getCount(); |
| 1177 | |
| 1178 | // Check to see if the parameter count matches |
| 1179 | if (input_flag ? |
| 1180 | (count < (inputCount - procedure->getDefaultCount()) || (count > inputCount) ) : |
| 1181 | (count != SLONG(procedure->getOutputFields().getCount()))) |
| 1182 | { |
| 1183 | PAR_error(csb, Arg::Gds(input_flag ? isc_prcmismat : isc_prc_out_param_mismatch) << |
| 1184 | Arg::Str(procedure->getName().toString())); |
| 1185 | } |
| 1186 | |
| 1187 | if (count || input_flag && procedure->getDefaultCount()) |
| 1188 | { |
| 1189 | MemoryPool& pool = *tdbb->getDefaultPool(); |
| 1190 | |
| 1191 | // We have a few parameters. Get on with creating the message block |
| 1192 | // Outer messages map may start with 2, but they are always in the routine start. |
| 1193 | USHORT n = ++csb->csb_msg_number; |
| 1194 | if (n < 2) |
| 1195 | csb->csb_msg_number = n = 2; |
| 1196 | CompilerScratch::csb_repeat* tail = CMP_csb_element(csb, n); |
| 1197 | |
| 1198 | MessageNode* message = tail->csb_message = *message_ptr = FB_NEW_POOL(pool) MessageNode(pool); |
| 1199 | message->messageNumber = n; |
| 1200 | |
| 1201 | const Format* format = input_flag ? procedure->getInputFormat() : procedure->getOutputFormat(); |
| 1202 | /* dimitr: procedure (with its parameter formats) is allocated out of |
| 1203 | its own pool (prc_request->req_pool) and can be freed during |
| 1204 | the cache cleanup (MET_clear_cache). Since the current |
| 1205 | tdbb default pool is different from the procedure's one, |
| 1206 | it's dangerous to copy a pointer from one request to another. |
| 1207 | As an experiment, I've decided to copy format by value |
| 1208 | instead of copying the reference. Since Format structure |
| 1209 | doesn't contain any pointers, it should be safe to use a |
| 1210 | default assignment operator which does a simple byte copy. |
| 1211 | This change fixes one serious bug in the current codebase. |
| 1212 | I think that this situation can (and probably should) be |
| 1213 | handled by the metadata cache (via incrementing prc_use_count) |
| 1214 | to avoid unexpected cache cleanups, but that area is out of my |
| 1215 | knowledge. So this fix should be considered a temporary solution. |
| 1216 | |
| 1217 | message->format = format; |
| 1218 | */ |
| 1219 | Format* fmt_copy = Format::newFormat(pool, format->fmt_count); |
| 1220 | *fmt_copy = *format; |
| 1221 | message->format = fmt_copy; |
| 1222 | // --- end of fix --- |
| 1223 | |
| 1224 | n = format->fmt_count / 2; |
| 1225 | |
| 1226 | ValueListNode* sourceValues = *sourceList = FB_NEW_POOL(pool) ValueListNode(pool, n); |
| 1227 | ValueListNode* targetValues = *targetList = FB_NEW_POOL(pool) ValueListNode(pool, n); |
| 1228 |
no test coverage detected