void PreparedStatement::parseDsqlMessage(const dsql_msg* dsqlMsg, Array<dsc>& values, MsgMetadata* msgMetadata, UCharBuffer& msg) { // hvlad: Parameters in dsqlMsg->msg_parameters almost always linked in descending // order by par_index. The only known exception is EXECUTE BLOCK statement. // To generate correct metadata we must walk params in ascending par_index order. // So store all params in array in an ascending par_index order despite of // order in linked list. // ASF: Input parameters don't come necessarily in ascending or descending order, // so I changed the code to use a SortedArray. // AP: removed assertions for correct parameters order - useless with SortedArray. SortedArray<const dsql_par*, InlineStorage<const dsql_par*, 16>, const dsql_par*, DefaultKeyValue<const dsql_par*>, ParamCmp> params; for (size_t i = 0; i < dsqlMsg->msg_parameters.getCount(); ++i) { dsql_par* par = dsqlMsg->msg_parameters[i]; if (par->par_index) params.add(par); } size_t paramCount = params.getCount(); values.resize(paramCount * 2); msgMetadata->setItemsCount(paramCount); for (size_t i = 0; i < paramCount; ++i) dscToMetaItem(¶ms[i]->par_desc, msgMetadata->getItem(i)); msgMetadata->makeOffsets(); msg.resize(msgMetadata->getMessageLength()); dsc* value = values.begin(); for (size_t i = 0; i < paramCount; ++i) { // value *value = params[i]->par_desc; value->dsc_address = msg.begin() + msgMetadata->getItem(i).offset; ++value; // NULL indicator value->makeShort(0); value->dsc_address = msg.begin() + msgMetadata->getItem(i).nullInd; // set NULL indicator value *((SSHORT*) value->dsc_address) = -1; ++value; } }
// Parse routine BLR. void Routine::parseBlr(thread_db* tdbb, CompilerScratch* csb, bid* blob_id) { Jrd::Attachment* attachment = tdbb->getAttachment(); UCharBuffer tmp; if (blob_id) { blb* blob = blb::open(tdbb, attachment->getSysTransaction(), blob_id); ULONG length = blob->blb_length + 10; UCHAR* temp = tmp.getBuffer(length); length = blob->BLB_get_data(tdbb, temp, length); tmp.resize(length); } parseMessages(tdbb, csb, BlrReader(tmp.begin(), (unsigned) tmp.getCount())); JrdStatement* statement = getStatement(); PAR_blr(tdbb, NULL, tmp.begin(), (ULONG) tmp.getCount(), NULL, &csb, &statement, false, 0); setStatement(statement); if (!blob_id) setImplemented(false); }
// We store in CS_METADATA. void Jrd::Attachment::storeMetaDataBlob(thread_db* tdbb, jrd_tra* transaction, bid* blobId, const string& text, USHORT fromCharSet) { UCharBuffer bpb; if (fromCharSet != CS_METADATA) BLB_gen_bpb(isc_blob_text, isc_blob_text, fromCharSet, CS_METADATA, bpb); blb* blob = blb::create2(tdbb, transaction, blobId, bpb.getCount(), bpb.begin()); try { blob->BLB_put_data(tdbb, (const UCHAR*) text.c_str(), text.length()); } catch (const Exception&) { blob->BLB_close(tdbb); throw; } blob->BLB_close(tdbb); }
bool IntlUtil::initUnicodeCollation(texttype* tt, charset* cs, const ASCII* name, USHORT attributes, const UCharBuffer& specificAttributes, const string& configInfo) { memset(tt, 0, sizeof(*tt)); // name comes from stack. Copy it. ASCII* nameCopy = FB_NEW ASCII[strlen(name) + 1]; strcpy(nameCopy, name); tt->texttype_name = nameCopy; tt->texttype_version = TEXTTYPE_VERSION_1; tt->texttype_country = CC_INTL; tt->texttype_canonical_width = 4; // UTF-32 tt->texttype_fn_destroy = unicodeDestroy; tt->texttype_fn_compare = unicodeCompare; tt->texttype_fn_key_length = unicodeKeyLength; tt->texttype_fn_string_to_key = unicodeStrToKey; tt->texttype_fn_canonical = unicodeCanonical; IntlUtil::SpecificAttributesMap map; Jrd::CharSet* charSet = NULL; try { charSet = Jrd::CharSet::createInstance(*getDefaultMemoryPool(), 0, cs); IntlUtil::parseSpecificAttributes(charSet, specificAttributes.getCount(), specificAttributes.begin(), &map); delete charSet; } catch (...) { delete charSet; gds__log("initUnicodeCollation failed - unexpected exception caught"); return false; } IntlUtil::SpecificAttributesMap map16; SpecificAttributesMap::Accessor accessor(&map); bool found = accessor.getFirst(); while (found) { UCharBuffer s1, s2; USHORT errCode; ULONG errPosition; s1.resize(cs->charset_to_unicode.csconvert_fn_convert( &cs->charset_to_unicode, accessor.current()->first.length(), NULL, 0, NULL, &errCode, &errPosition)); s1.resize(cs->charset_to_unicode.csconvert_fn_convert( &cs->charset_to_unicode, accessor.current()->first.length(), (UCHAR*) accessor.current()->first.c_str(), s1.getCapacity(), s1.begin(), &errCode, &errPosition)); s2.resize(cs->charset_to_unicode.csconvert_fn_convert( &cs->charset_to_unicode, accessor.current()->second.length(), NULL, 0, NULL, &errCode, &errPosition)); s2.resize(cs->charset_to_unicode.csconvert_fn_convert( &cs->charset_to_unicode, accessor.current()->second.length(), (UCHAR*) accessor.current()->second.c_str(), s2.getCapacity(), s2.begin(), &errCode, &errPosition)); map16.put(string((char*) s1.begin(), s1.getCount()), string((char*) s2.begin(), s2.getCount())); found = accessor.getNext(); } UnicodeUtil::Utf16Collation* collation = UnicodeUtil::Utf16Collation::create(tt, attributes, map16, configInfo); if (!collation) { gds__log("initUnicodeCollation failed - UnicodeUtil::Utf16Collation::create failed"); return false; } tt->texttype_impl = FB_NEW TextTypeImpl(cs, collation); return true; }