Skip to content

Commit ae97741

Browse files
akshay05nmergify[bot]
authored andcommitted
Fix: Ensure ECSqlReader returns correct metadata for instance properties (#1031)
* Reset dynamic column info on ECSqlField reset --------- Co-authored-by: affank <[email protected]> (cherry picked from commit c697af6)
1 parent 30a7197 commit ae97741

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

iModelCore/ECDb/ECDb/ECSql/ECSqlField.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct ECSqlField : public IECSqlValue
2424

2525
ECSqlColumnInfoCR _GetColumnInfo() const override { return m_ecsqlDynamicColumnInfo.IsValid() ? m_ecsqlDynamicColumnInfo : m_ecsqlColumnInfo; }
2626

27-
virtual ECSqlStatus _OnAfterReset() { return ECSqlStatus::Success; }
27+
virtual ECSqlStatus _OnAfterReset() { SetDynamicColumnInfo(ECSqlColumnInfo()); return ECSqlStatus::Success; }
2828
virtual ECSqlStatus _OnAfterStep() { return ECSqlStatus::Success; }
2929
virtual void _OnDynamicPropertyUpdated() {}
3030
protected:
@@ -38,7 +38,7 @@ struct ECSqlField : public IECSqlValue
3838
virtual ~ECSqlField() {}
3939
bool RequiresOnAfterStep() const { return m_requiresOnAfterStep; }
4040
ECSqlStatus OnAfterStep() { return _OnAfterStep(); }
41-
bool RequiresOnAfterReset() const { return m_requiresOnAfterReset; }
41+
bool RequiresOnAfterReset() const { return m_requiresOnAfterReset || _GetColumnInfo().IsDynamic(); }
4242
ECSqlStatus OnAfterReset() { return _OnAfterReset(); }
4343
void SetDynamicColumnInfo(ECSqlColumnInfoCR info);
4444
};

iModelCore/ECDb/Tests/NonPublished/InstanceReaderTest.cpp

+75
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,81 @@ TEST_F(InstanceReaderFixture, dynamic_meta_data) {
15931593
}
15941594
}
15951595

1596+
TEST_F(InstanceReaderFixture, ResetDynamicMetadata) {
1597+
ASSERT_EQ(SUCCESS, SetupECDb("ResetDynamicMetadata.ecdb", SchemaItem(
1598+
R"xml(<ECSchema schemaName='TestSchema' alias='ts' version='1.0.0' xmlns='http://www.bentley.com/schemas/Bentley.ECXML.3.2'>
1599+
<ECEntityClass typeName='A'>
1600+
</ECEntityClass>
1601+
<ECEntityClass typeName='B'>
1602+
<BaseClass>A</BaseClass>
1603+
<ECProperty propertyName='prop' typeName='int' />
1604+
</ECEntityClass>
1605+
<ECEntityClass typeName='C'>
1606+
<BaseClass>A</BaseClass>
1607+
<ECProperty propertyName='prop' typeName='double' />
1608+
</ECEntityClass>
1609+
</ECSchema>)xml")));
1610+
1611+
auto exec = [&](Utf8CP ecsql) {
1612+
ECSqlStatement stmt;
1613+
EXPECT_EQ(ECSqlStatus::Success, stmt.Prepare(m_ecdb, ecsql));
1614+
EXPECT_EQ(BE_SQLITE_DONE, stmt.Step());
1615+
m_ecdb.SaveChanges();
1616+
};
1617+
1618+
auto assertDefault = [](ECSqlStatement& stmt, int cl, Utf8CP displayLabel, Utf8CP propertyName) {
1619+
ECSqlColumnInfo const* ci;
1620+
PrimitiveECPropertyCP pr;
1621+
Utf8CP className = "DynamicECSqlSelectClause";
1622+
ci = &stmt.GetColumnInfo(cl);
1623+
EXPECT_TRUE(ci->IsDynamic());
1624+
EXPECT_TRUE(ci->GetDataType().IsPrimitive());
1625+
pr = ci->GetProperty()->GetAsPrimitiveProperty();
1626+
EXPECT_FALSE(pr->HasId());
1627+
EXPECT_EQ(PrimitiveType::PRIMITIVETYPE_String, pr->GetType());
1628+
EXPECT_STRCASEEQ(className , pr->GetClass().GetName().c_str());
1629+
EXPECT_STRCASEEQ(propertyName , pr->GetName().c_str());
1630+
EXPECT_STRCASEEQ("" , pr->GetDescription().c_str());
1631+
EXPECT_STRCASEEQ(displayLabel , pr->GetDisplayLabel().c_str());
1632+
EXPECT_STRCASEEQ("json" , pr->GetExtendedTypeName().c_str());
1633+
};
1634+
1635+
auto assertDynamic = [](ECSqlStatement& stmt, int cl, Utf8CP displayLabel, Utf8CP propertyName, Utf8CP description, Utf8CP className, PrimitiveType t) {
1636+
ECSqlColumnInfo const* ci;
1637+
PrimitiveECPropertyCP pr;
1638+
ci = &stmt.GetColumnInfo(cl);
1639+
EXPECT_TRUE(ci->IsDynamic());
1640+
EXPECT_TRUE(ci->GetDataType().IsPrimitive());
1641+
pr = ci->GetProperty()->GetAsPrimitiveProperty();
1642+
EXPECT_TRUE(pr->HasId());
1643+
EXPECT_EQ(t , pr->GetType());
1644+
EXPECT_STRCASEEQ(className , pr->GetClass().GetName().c_str());
1645+
EXPECT_STRCASEEQ(propertyName, pr->GetName().c_str());
1646+
EXPECT_STRCASEEQ(description , pr->GetDescription().c_str());
1647+
EXPECT_STRCASEEQ(displayLabel, pr->GetDisplayLabel().c_str());
1648+
EXPECT_STRCASEEQ("" , pr->GetExtendedTypeName().c_str());
1649+
};
1650+
1651+
exec("insert into ts.B ( ecInstanceId, B.prop ) values ( 10, 100 )");
1652+
exec("insert into ts.C ( ecInstanceId, C.prop ) values ( 11, 101 )");
1653+
1654+
const auto sql = R"x(
1655+
select
1656+
$->prop
1657+
from ts.A
1658+
)x";
1659+
1660+
ECSqlStatement stmt;
1661+
ASSERT_EQ(ECSqlStatus::Success, stmt.Prepare(m_ecdb, sql));
1662+
assertDefault(stmt, 0 , "$->prop", "__x0024____x002D____x003E__prop");
1663+
ASSERT_EQ(BE_SQLITE_ROW, stmt.Step());
1664+
assertDynamic(stmt, 0 , "prop", "prop", "", "B", PrimitiveType::PRIMITIVETYPE_Integer);
1665+
ASSERT_EQ(BE_SQLITE_ROW, stmt.Step());
1666+
assertDynamic(stmt, 0 , "prop", "prop", "", "C", PrimitiveType::PRIMITIVETYPE_Double);
1667+
stmt.Reset();
1668+
assertDefault(stmt, 0 , "$->prop", "__x0024____x002D____x003E__prop");
1669+
}
1670+
15961671
//---------------------------------------------------------------------------------------
15971672
// @bsimethod
15981673
//+---------------+---------------+---------------+---------------+---------------+------

0 commit comments

Comments
 (0)