Skip to content

Commit 8b4093c

Browse files
committed
Fixed rebuild indexes on alter field. ODS changed, full rebuild required.
1 parent ca35a17 commit 8b4093c

15 files changed

Lines changed: 89 additions & 25 deletions

File tree

src/burp/restore.epp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6756,6 +6756,7 @@ bool get_index(BurpGlobals* tdgbl, const burp_rel* relation)
67566756
X.RDB$CONDITION_BLR.NULL = TRUE;
67576757
X.RDB$SYSTEM_FLAG = 0;
67586758
X.RDB$SYSTEM_FLAG.NULL = FALSE;
6759+
X.RDB$FORMAT.NULL = TRUE;
67596760

67606761
if (relation->rel_name.schema.hasData())
67616762
{

src/dsql/DdlNodes.epp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5383,6 +5383,7 @@ void AlterDomainNode::modifyLocalFieldIndex(thread_db* tdbb, jrd_tra* transactio
53835383
INEW IN RDB$INDICES
53845384
{
53855385
INEW.RDB$INDEX_ID.NULL = TRUE;
5386+
INEW.RDB$FORMAT.NULL = TRUE; // Leave it till DFW_update_index()
53865387

53875388
if (IDX.RDB$INDEX_NAME.NULL) INEW.RDB$INDEX_NAME.NULL = TRUE;
53885389
else {INEW.RDB$INDEX_NAME.NULL = FALSE; strcpy(INEW.RDB$INDEX_NAME, IDX.RDB$INDEX_NAME);};
@@ -12659,12 +12660,11 @@ MetaId StoreIndexNode::create(thread_db* tdbb, jrd_tra* transaction)
1265912660
&idxId, transaction, selectivity);
1266012661
fb_assert(idxId == idx.idx_id);
1266112662
if (!tempConn)
12662-
DFW_update_index(indexName, idxId, selectivity, transaction);
12663+
DFW_update_index(indexName, idxId, selectivity, transaction, relation);
1266312664
}
1266412665
else
1266512666
fb_assert(idxId == dbb->dbb_max_idx);
1266612667

12667-
// Memleak when IDX_create_index() throws ????????????
1266812668
if (idx.idx_condition_statement)
1266912669
idx.idx_condition_statement->release(tdbb);
1267012670

@@ -12883,6 +12883,7 @@ ModifyIndexNode* CreateIndexNode::store(thread_db* tdbb, MemoryPool& p, jrd_tra*
1288312883
IDX IN RDB$INDICES
1288412884
{
1288512885
IDX.RDB$INDEX_ID.NULL = TRUE;
12886+
IDX.RDB$FORMAT.NULL = TRUE; // will be set in DFW_update_index
1288612887
IDX.RDB$UNIQUE_FLAG.NULL = TRUE;
1288712888
IDX.RDB$INDEX_INACTIVE.NULL = TRUE;
1288812889
IDX.RDB$INDEX_TYPE.NULL = TRUE;

src/isql/show.epp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4741,8 +4741,9 @@ static processing_state show_indices(const std::optional<QualifiedMetaString>& n
47414741
if (name)
47424742
{
47434743
FOR IDX IN RDB$INDICES
4744-
WITH IDX.RDB$RELATION_NAME EQ name->object.c_str() OR
4745-
IDX.RDB$INDEX_NAME EQ name->object.c_str()
4744+
WITH (IDX.RDB$RELATION_NAME EQ name->object.c_str() OR
4745+
IDX.RDB$INDEX_NAME EQ name->object.c_str()) AND
4746+
IDX.RDB$INDEX_NAME NOT STARTING TEMP_DEPEND
47464747
SORTED BY IDX.RDB$SCHEMA_NAME, IDX.RDB$INDEX_NAME
47474748
{
47484749
const QualifiedMetaString indexName(IDX.RDB$INDEX_NAME, IDX.RDB$SCHEMA_NAME);
@@ -4792,7 +4793,8 @@ static processing_state show_indices(const std::optional<QualifiedMetaString>& n
47924793
REL IN RDB$RELATIONS
47934794
WITH REL.RDB$SCHEMA_NAME EQUIV IDX.RDB$SCHEMA_NAME AND
47944795
REL.RDB$RELATION_NAME = IDX.RDB$RELATION_NAME AND
4795-
(REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING)
4796+
(REL.RDB$SYSTEM_FLAG NE 1 OR REL.RDB$SYSTEM_FLAG MISSING) AND
4797+
IDX.RDB$INDEX_NAME NOT STARTING TEMP_DEPEND
47964798
SORTED BY IDX.RDB$SCHEMA_NAME, IDX.RDB$RELATION_NAME, IDX.RDB$INDEX_NAME
47974799
{
47984800
const QualifiedMetaString indexName(IDX.RDB$INDEX_NAME, IDX.RDB$SCHEMA_NAME);

src/jrd/Relation.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ class IndexPermanent : public Firebird::PermanentStorage
482482

483483
void releaseLock(thread_db*) { }
484484

485-
RelationPermanent* getRelation()
485+
RelationPermanent* getRelation() noexcept
486486
{
487487
return idp_relation;
488488
}
@@ -495,6 +495,7 @@ class IndexPermanent : public Firebird::PermanentStorage
495495
MetaId idp_id;
496496
TraNumber idp_tranum = 0;
497497
UCHAR idp_state = 0;
498+
UCHAR idp_formatNumber = 0;
498499

499500
[[noreturn]] void errIndexGone();
500501

@@ -515,10 +516,30 @@ class IndexPermanent : public Firebird::PermanentStorage
515516
memcpy(&idx->idx_expression_desc, &idp_expression_desc, sizeof(struct dsc));
516517
}
517518

519+
void setState(UCHAR state) noexcept
520+
{
521+
idp_state = state;
522+
}
523+
524+
UCHAR getState() const noexcept
525+
{
526+
return idp_state;
527+
}
528+
529+
UCHAR getFormat() const noexcept
530+
{
531+
return idp_formatNumber;
532+
}
533+
534+
void setFormat(UCHAR fmt) noexcept
535+
{
536+
idp_formatNumber = fmt;
537+
}
538+
539+
private:
518540
void refreshIndexCode(thread_db* tdbb, Cached::Relation* relation,
519541
index_desc* idx, const Ods::index_root_page::irt_repeat* irt_desc);
520542

521-
private:
522543
Firebird::Mutex idp_code_mutex; // Delays concurrent threads till the end of code refresh
523544

524545
bid idp_expression_bid;

src/jrd/btr.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,11 @@ void IndexErrorContext::raise(thread_db* tdbb, idx_e result, Record* record)
462462
ERR_post_nothrow(Arg::Gds(isc_no_dup) << indexName.toQuotedString());
463463
break;
464464

465+
case idx_e_skip:
466+
fb_assert(false);
467+
fatal_exception::raise("Sorry, such error should not take place");
468+
break;
469+
465470
default:
466471
fb_assert(false);
467472
}
@@ -665,7 +670,7 @@ dsc* IndexExpression::evaluate(Record* record) const
665670

666671
// IndexKey class
667672

668-
idx_e IndexKey::compose(Record* record)
673+
idx_e IndexKey::composeIKey(Record* record, bool skipNewFormat)
669674
{
670675
// Compute a key from a record and an index descriptor.
671676
// Note that compound keys are expanded by 25%.
@@ -687,6 +692,14 @@ idx_e IndexKey::compose(Record* record)
687692

688693
const bool descending = (m_index->idx_flags & idx_descending);
689694

695+
auto* idp = m_relation->getPermanent()->lookupIndex(m_tdbb, m_index->idx_id, CacheFlag::AUTOCREATE);
696+
if (skipNewFormat && idp && (idp->getState() == Ods::irt_drop) && idp->getFormat() &&
697+
(record->getFormat()->fmt_version > idp->getFormat()))
698+
{
699+
// tried to insert fresh formatted record into old index - skip this
700+
return idx_e_skip;
701+
}
702+
690703
try
691704
{
692705
if (m_index->idx_count == 1)
@@ -1402,6 +1415,12 @@ bool BTR_description(thread_db* tdbb, Cached::Relation* relation, const index_ro
14021415
error = isc_idx_cond_not_found;
14031416
}
14041417
}
1418+
else if (irt_desc->getState() == Ods::irt_drop)
1419+
{
1420+
auto* idp = relation->ensureIndex(tdbb, idx->idx_id);
1421+
if (idp)
1422+
idp->setState(Ods::irt_drop);
1423+
}
14051424

14061425
if (error)
14071426
{

src/jrd/btr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ class IndexKey
486486
{
487487
}
488488

489-
idx_e compose(Record* record);
489+
idx_e composeIKey(Record* record, bool skipNewFormat = false);
490490

491491
operator temporary_key*()
492492
{

src/jrd/dfw.epp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,7 @@ DeferredWork* DFW_post_work_arg( jrd_tra* transaction, DeferredWork* work, const
16871687

16881688

16891689
void DFW_update_index(const QualifiedName& name, USHORT id, const SelectivityList& selectivity,
1690-
jrd_tra* transaction)
1690+
jrd_tra* transaction, jrd_rel* relation)
16911691
{
16921692
/**************************************
16931693
*
@@ -1727,6 +1727,11 @@ void DFW_update_index(const QualifiedName& name, USHORT id, const SelectivityLis
17271727
IDX.RDB$INDEX_ID = id + 1;
17281728
IDX.RDB$INDEX_ID.NULL = FALSE;
17291729
IDX.RDB$STATISTICS = selectivity.back();
1730+
if (relation)
1731+
{
1732+
IDX.RDB$FORMAT = relation->rel_current_fmt;
1733+
IDX.RDB$FORMAT.NULL = FALSE;
1734+
}
17301735
END_MODIFY
17311736
}
17321737
END_FOR

src/jrd/dfw_proto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ Jrd::DeferredWork* DFW_post_work_arg(Jrd::jrd_tra*, Jrd::DeferredWork*, const ds
5353
USHORT);
5454
Jrd::DeferredWork* DFW_post_work_arg(Jrd::jrd_tra*, Jrd::DeferredWork*, const dsc* nameDesc, const dsc* schemaDesc,
5555
USHORT, Jrd::dfw_t);
56-
void DFW_update_index(const Jrd::QualifiedName&, USHORT, const Jrd::SelectivityList&, Jrd::jrd_tra*);
56+
void DFW_update_index(const Jrd::QualifiedName&, USHORT, const Jrd::SelectivityList&, Jrd::jrd_tra*,
57+
Jrd::jrd_rel* relation = nullptr);
5758
void DFW_reset_icu(Jrd::thread_db*);
5859
Firebird::string DFW_remove_icu_info_from_attributes(const Jrd::QualifiedName&, const Firebird::string&);
5960

src/jrd/err_proto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ enum idx_e {
4141
idx_e_conversion,
4242
idx_e_interrupt,
4343
idx_e_foreign_target_doesnt_exist,
44-
idx_e_foreign_references_present
44+
idx_e_foreign_references_present,
45+
idx_e_skip
4546
};
4647

4748
} //namespace Jrd

src/jrd/idx.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ bool IndexCreateTask::handler(WorkItem& _item)
636636
if (!checkResult.asBool())
637637
continue;
638638

639-
result = key.compose(record);
639+
result = key.composeIKey(record);
640640

641641
if (result == idx_e_ok)
642642
{
@@ -1147,7 +1147,7 @@ void IDX_garbage_collect(thread_db* tdbb, record_param* rpb, RecordStack& going,
11471147
if (!condition.check(rec1).asBool())
11481148
continue;
11491149

1150-
if (const auto result = key1.compose(rec1))
1150+
if (const auto result = key1.composeIKey(rec1))
11511151
{
11521152
if (result == idx_e_conversion)
11531153
continue;
@@ -1163,7 +1163,7 @@ void IDX_garbage_collect(thread_db* tdbb, record_param* rpb, RecordStack& going,
11631163
{
11641164
Record* const rec2 = stack2.object();
11651165

1166-
if (const auto result = key2.compose(rec2))
1166+
if (const auto result = key2.composeIKey(rec2))
11671167
{
11681168
if (result == idx_e_conversion)
11691169
continue;
@@ -1186,7 +1186,7 @@ void IDX_garbage_collect(thread_db* tdbb, record_param* rpb, RecordStack& going,
11861186
{
11871187
Record* const rec3 = stack3.object();
11881188

1189-
if (const auto result = key2.compose(rec3))
1189+
if (const auto result = key2.composeIKey(rec3))
11901190
{
11911191
if (result == idx_e_conversion)
11921192
continue;
@@ -1275,13 +1275,16 @@ void IDX_modify(thread_db* tdbb,
12751275
AutoIndexExpression expression;
12761276
IndexKey newKey(tdbb, new_rpb->rpb_relation, &idx, expression), orgKey(newKey);
12771277

1278-
if ( (error_code = newKey.compose(new_rpb->rpb_record)) )
1278+
if ( (error_code = newKey.composeIKey(new_rpb->rpb_record, true)) )
12791279
{
1280+
if (error_code == idx_e_skip)
1281+
continue;
1282+
12801283
CCH_RELEASE(tdbb, &window);
12811284
context.raise(tdbb, error_code, new_rpb->rpb_record);
12821285
}
12831286

1284-
if ( (error_code = orgKey.compose(org_rpb->rpb_record)) )
1287+
if ( (error_code = orgKey.composeIKey(org_rpb->rpb_record)) )
12851288
{
12861289
CCH_RELEASE(tdbb, &window);
12871290
context.raise(tdbb, error_code, org_rpb->rpb_record);
@@ -1374,13 +1377,16 @@ void IDX_modify_check_constraints(thread_db* tdbb,
13741377
AutoIndexExpression expression;
13751378
IndexKey newKey(tdbb, new_rpb->rpb_relation, &idx, expression), orgKey(newKey);
13761379

1377-
if ( (error_code = newKey.compose(new_rpb->rpb_record)) )
1380+
if ( (error_code = newKey.composeIKey(new_rpb->rpb_record, true)) )
13781381
{
1382+
if (error_code == idx_e_skip)
1383+
continue;
1384+
13791385
CCH_RELEASE(tdbb, &window);
13801386
context.raise(tdbb, error_code, new_rpb->rpb_record);
13811387
}
13821388

1383-
if ( (error_code = orgKey.compose(org_rpb->rpb_record)) )
1389+
if ( (error_code = orgKey.composeIKey(org_rpb->rpb_record)) )
13841390
{
13851391
CCH_RELEASE(tdbb, &window);
13861392
context.raise(tdbb, error_code, org_rpb->rpb_record);
@@ -1536,8 +1542,11 @@ void IDX_store(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
15361542
AutoIndexExpression expression;
15371543
IndexKey key(tdbb, rpb->rpb_relation, &idx, expression);
15381544

1539-
if ( (error_code = key.compose(rpb->rpb_record)) )
1545+
if ( (error_code = key.composeIKey(rpb->rpb_record, true)) )
15401546
{
1547+
if (error_code == idx_e_skip)
1548+
continue;
1549+
15411550
CCH_RELEASE(tdbb, &window);
15421551
context.raise(tdbb, error_code, rpb->rpb_record);
15431552
}
@@ -1900,7 +1909,7 @@ static idx_e check_partner_index(thread_db* tdbb,
19001909
(tmpIndex.idx_flags & idx_unique) ? INTL_KEY_UNIQUE : INTL_KEY_SORT;
19011910

19021911
IndexKey key(tdbb, relation, &tmpIndex, keyType, segment);
1903-
auto result = key.compose(record);
1912+
auto result = key.composeIKey(record);
19041913

19051914
CCH_RELEASE(tdbb, &window);
19061915

0 commit comments

Comments
 (0)