@@ -143,6 +143,8 @@ enum UndoDataRet
143143 udNone // record was not changed under current savepoint, use it as is
144144};
145145
146+ static void gbak_put_search_system_schema_flag (thread_db* tdbb, record_param* rpb, jrd_tra* transaction);
147+
146148static UndoDataRet get_undo_data (thread_db* tdbb, jrd_tra* transaction,
147149 record_param* rpb, MemoryPool* pool);
148150
@@ -3354,6 +3356,7 @@ bool VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
33543356 SET_TDBB (tdbb);
33553357
33563358 QualifiedName object_name;
3359+ const auto attachment = tdbb->getAttachment ();
33573360 jrd_rel* relation = org_rpb->rpb_relation ;
33583361
33593362#ifdef VIO_DEBUG
@@ -3410,6 +3413,13 @@ bool VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
34103413
34113414 check_gbak_cheating_insupd (tdbb, relation, " UPDATE" );
34123415
3416+ if (attachment->isGbak () &&
3417+ !(attachment->att_flags & ATT_gbak_restore_has_schema) &&
3418+ !(attachment->att_database ->dbb_flags & DBB_creating))
3419+ {
3420+ gbak_put_search_system_schema_flag (tdbb, new_rpb, transaction);
3421+ }
3422+
34133423 // If we're about to modify a system relation, check to make sure
34143424 // everything is completely kosher.
34153425
@@ -4109,7 +4119,9 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
41094119
41104120 check_gbak_cheating_insupd (tdbb, relation, " INSERT" );
41114121
4112- if (attachment->isGbak () && !(attachment->att_flags & ATT_gbak_restore_has_schema))
4122+ if (attachment->isGbak () &&
4123+ !(attachment->att_flags & ATT_gbak_restore_has_schema) &&
4124+ !(attachment->att_database ->dbb_flags & DBB_creating))
41134125 {
41144126 struct ObjTypeFieldId
41154127 {
@@ -4297,82 +4309,7 @@ void VIO_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
42974309 desc2.setNull ();
42984310 }
42994311
4300- static const std::unordered_map<USHORT, std::vector<USHORT>> schemaBlrFields = {
4301- {rel_args, {f_arg_default}},
4302- {rel_fields, {f_fld_v_blr, f_fld_computed, f_fld_default, f_fld_missing}},
4303- {rel_funs, {f_fun_blr}},
4304- {rel_indices, {f_idx_exp_blr, f_idx_cond_blr}},
4305- {rel_prc_prms, {f_prm_default}},
4306- {rel_procedures, {f_prc_blr}},
4307- {rel_relations, {f_rel_blr}},
4308- {rel_rfr, {f_rfr_default}},
4309- {rel_triggers, {f_trg_blr}}
4310- };
4311-
4312- static const UCHAR bpb[] = {
4313- isc_bpb_version1,
4314- isc_bpb_type, 1 , isc_bpb_type_stream
4315- };
4316-
4317- if (const auto relBlrFields = schemaBlrFields.find (relation->rel_id ); relBlrFields != schemaBlrFields.end ())
4318- {
4319- UCHAR buffer[BUFFER_MEDIUM];
4320-
4321- for (const auto field : relBlrFields->second )
4322- {
4323- if (EVL_field (0 , rpb->rpb_record , field, &desc))
4324- {
4325- AutoBlb blob (tdbb, blb::open (tdbb, transaction, reinterpret_cast <bid*>(desc.dsc_address )));
4326- bid newBid;
4327- const auto newBlob = blb::create2 (tdbb, transaction, &newBid, sizeof (bpb), bpb);
4328- bool firstSegment = true ;
4329- UCHAR newHeader[] = {
4330- 0 ,
4331- blr_flags,
4332- blr_flags_search_system_schema,
4333- 0 , 0 ,
4334- blr_end
4335- };
4336-
4337- while (!(blob->blb_flags & BLB_eof))
4338- {
4339- const auto len = blob->BLB_get_data (tdbb, buffer, sizeof (buffer), false );
4340-
4341- if (len > 1 && firstSegment)
4342- {
4343- newHeader[0 ] = buffer[0 ];
4344- fb_assert (newHeader[0 ] == blr_version4 || newHeader[0 ] == blr_version5);
4345-
4346- if ((newHeader[0 ] == blr_version4 || newHeader[0 ] == blr_version5) &&
4347- buffer[1 ] != blr_flags)
4348- {
4349- newBlob->BLB_put_data (tdbb, newHeader, sizeof (newHeader));
4350- newBlob->BLB_put_data (tdbb, buffer + 1 , len - 1 );
4351-
4352- firstSegment = false ;
4353- }
4354- else
4355- {
4356- newBid.clear ();
4357- break ;
4358- }
4359- }
4360- else
4361- newBlob->BLB_put_data (tdbb, buffer, len);
4362- }
4363-
4364- newBlob->BLB_close (tdbb);
4365-
4366- if (!newBid.isEmpty ())
4367- {
4368- desc2.makeBlob (isc_blob_untyped, 0 , reinterpret_cast <ISC_QUAD*>(&newBid));
4369- blb::move (tdbb, &desc2, &desc, relation, rpb->rpb_record , field);
4370- }
4371- }
4372- }
4373- }
4374-
4375- desc2.setNull ();
4312+ gbak_put_search_system_schema_flag (tdbb, rpb, transaction);
43764313 }
43774314
43784315 desc.setNull ();
@@ -5973,6 +5910,90 @@ void Database::exceptionHandler(const Firebird::Exception& ex,
59735910}
59745911
59755912
5913+ static void gbak_put_search_system_schema_flag (thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
5914+ {
5915+ static const std::unordered_map<USHORT, std::vector<USHORT>> schemaBlrFields = {
5916+ {rel_args, {f_arg_default}},
5917+ {rel_fields, {f_fld_v_blr, f_fld_computed, f_fld_default, f_fld_missing}},
5918+ {rel_funs, {f_fun_blr}},
5919+ {rel_indices, {f_idx_exp_blr, f_idx_cond_blr}},
5920+ {rel_prc_prms, {f_prm_default}},
5921+ {rel_procedures, {f_prc_blr}},
5922+ {rel_relations, {f_rel_blr}},
5923+ {rel_rfr, {f_rfr_default}},
5924+ {rel_triggers, {f_trg_blr}}
5925+ };
5926+
5927+ static const UCHAR bpb[] = {
5928+ isc_bpb_version1,
5929+ isc_bpb_type, 1 , isc_bpb_type_stream
5930+ };
5931+
5932+ SET_TDBB (tdbb);
5933+
5934+ const auto relation = rpb->rpb_relation ;
5935+ dsc desc, desc2;
5936+
5937+ if (const auto relBlrFields = schemaBlrFields.find (relation->rel_id ); relBlrFields != schemaBlrFields.end ())
5938+ {
5939+ UCHAR buffer[BUFFER_MEDIUM];
5940+
5941+ for (const auto field : relBlrFields->second )
5942+ {
5943+ if (EVL_field (0 , rpb->rpb_record , field, &desc))
5944+ {
5945+ AutoBlb blob (tdbb, blb::open (tdbb, transaction, reinterpret_cast <bid*>(desc.dsc_address )));
5946+ bid newBid;
5947+ const auto newBlob = blb::create2 (tdbb, transaction, &newBid, sizeof (bpb), bpb);
5948+ bool firstSegment = true ;
5949+ UCHAR newHeader[] = {
5950+ 0 ,
5951+ blr_flags,
5952+ blr_flags_search_system_schema,
5953+ 0 , 0 ,
5954+ blr_end
5955+ };
5956+
5957+ while (!(blob->blb_flags & BLB_eof))
5958+ {
5959+ const auto len = blob->BLB_get_data (tdbb, buffer, sizeof (buffer), false );
5960+
5961+ if (len > 1 && firstSegment)
5962+ {
5963+ newHeader[0 ] = buffer[0 ];
5964+ fb_assert (newHeader[0 ] == blr_version4 || newHeader[0 ] == blr_version5);
5965+
5966+ if ((newHeader[0 ] == blr_version4 || newHeader[0 ] == blr_version5) &&
5967+ buffer[1 ] != blr_flags)
5968+ {
5969+ newBlob->BLB_put_data (tdbb, newHeader, sizeof (newHeader));
5970+ newBlob->BLB_put_data (tdbb, buffer + 1 , len - 1 );
5971+
5972+ firstSegment = false ;
5973+ }
5974+ else
5975+ {
5976+ newBid.clear ();
5977+ break ;
5978+ }
5979+ }
5980+ else
5981+ newBlob->BLB_put_data (tdbb, buffer, len);
5982+ }
5983+
5984+ newBlob->BLB_close (tdbb);
5985+
5986+ if (!newBid.isEmpty ())
5987+ {
5988+ desc2.makeBlob (isc_blob_untyped, 0 , reinterpret_cast <ISC_QUAD*>(&newBid));
5989+ blb::move (tdbb, &desc2, &desc, relation, rpb->rpb_record , field);
5990+ }
5991+ }
5992+ }
5993+ }
5994+ }
5995+
5996+
59765997static UndoDataRet get_undo_data (thread_db* tdbb, jrd_tra* transaction,
59775998 record_param* rpb, MemoryPool* pool)
59785999/* *********************************************************
0 commit comments