Translate a map block into a format. If the format is missing or incomplete, extend it.
| 3861 | |
| 3862 | // Translate a map block into a format. If the format is missing or incomplete, extend it. |
| 3863 | static void processMap(thread_db* tdbb, CompilerScratch* csb, MapNode* map, Format** inputFormat) |
| 3864 | { |
| 3865 | SET_TDBB(tdbb); |
| 3866 | |
| 3867 | Format* format = *inputFormat; |
| 3868 | if (!format) |
| 3869 | format = *inputFormat = Format::newFormat(*tdbb->getDefaultPool(), map->sourceList.getCount()); |
| 3870 | |
| 3871 | // process alternating rse and map blocks |
| 3872 | dsc desc2; |
| 3873 | NestConst<ValueExprNode>* source = map->sourceList.begin(); |
| 3874 | NestConst<ValueExprNode>* target = map->targetList.begin(); |
| 3875 | |
| 3876 | for (const NestConst<ValueExprNode>* const sourceEnd = map->sourceList.end(); |
| 3877 | source != sourceEnd; |
| 3878 | ++source, ++target) |
| 3879 | { |
| 3880 | FieldNode* field = nodeAs<FieldNode>(*target); |
| 3881 | const USHORT id = field->fieldId; |
| 3882 | |
| 3883 | if (id >= format->fmt_count) |
| 3884 | format->fmt_desc.resize(id + 1); |
| 3885 | |
| 3886 | dsc* desc = &format->fmt_desc[id]; |
| 3887 | (*source)->getDesc(tdbb, csb, &desc2); |
| 3888 | const USHORT min = MIN(desc->dsc_dtype, desc2.dsc_dtype); |
| 3889 | const USHORT max = MAX(desc->dsc_dtype, desc2.dsc_dtype); |
| 3890 | |
| 3891 | if (!min) // eg: dtype_unknown |
| 3892 | *desc = desc2; |
| 3893 | else if (max == dtype_blob) |
| 3894 | { |
| 3895 | USHORT subtype = DataTypeUtil::getResultBlobSubType(desc, &desc2); |
| 3896 | USHORT ttype = DataTypeUtil::getResultTextType(desc, &desc2); |
| 3897 | desc->makeBlob(subtype, ttype); |
| 3898 | } |
| 3899 | else if (min <= dtype_any_text) |
| 3900 | { |
| 3901 | // either field a text field? |
| 3902 | const USHORT len1 = DSC_string_length(desc); |
| 3903 | const USHORT len2 = DSC_string_length(&desc2); |
| 3904 | desc->dsc_dtype = dtype_varying; |
| 3905 | desc->dsc_length = MAX(len1, len2) + sizeof(USHORT); |
| 3906 | |
| 3907 | // pick the max text type, so any transparent casts from ints are |
| 3908 | // not left in ASCII format, but converted to the richer text format |
| 3909 | |
| 3910 | desc->setTextType(MAX(INTL_TEXT_TYPE(*desc), INTL_TEXT_TYPE(desc2))); |
| 3911 | desc->dsc_scale = 0; |
| 3912 | desc->dsc_flags = 0; |
| 3913 | } |
| 3914 | else if (DTYPE_IS_DATE(max) && !DTYPE_IS_DATE(min)) |
| 3915 | { |
| 3916 | desc->dsc_dtype = dtype_varying; |
| 3917 | desc->dsc_length = DSC_convert_to_text_length(max) + sizeof(USHORT); |
| 3918 | desc->dsc_ttype() = ttype_ascii; |
| 3919 | desc->dsc_scale = 0; |
| 3920 | desc->dsc_flags = 0; |
no test coverage detected