in src/Microsoft.SqlTools.ServiceLayer/ShowPlan/ShowPlanGraph/Node.cs [406:492]
public bool IsLogicallyEquivalentTo(Node nodeToCompare, bool ignoreDatabaseName)
{
// same exact node
if (this == nodeToCompare)
return true;
// seek and scan types are equivalent so ignore them when comparing logical op
if (this[NodeBuilderConstants.LogicalOp] != nodeToCompare[NodeBuilderConstants.LogicalOp] &&
(!this.IsSeekOrScanType() || !nodeToCompare.IsSeekOrScanType()))
return false;
// one has object but other does not
if (this[objectProperty] != null && nodeToCompare[objectProperty] == null || nodeToCompare[objectProperty] != null && this[objectProperty] == null)
return false;
// both have object
if (this[objectProperty] != null && nodeToCompare[objectProperty] != null)
{
ExpandableObjectWrapper objectProp1 = (ExpandableObjectWrapper)this[objectProperty];
ExpandableObjectWrapper objectProp2 = (ExpandableObjectWrapper)nodeToCompare[objectProperty];
// object property doesn't match
// by default, we ignore DB name
// for ex: "[master].[sys].[sysobjvalues].[clst] [e]" and "[master_copy].[sys].[sysobjvalues].[clst] [e]" would be same
if (ignoreDatabaseName)
{
if (!CompareObjectPropertyValue((PropertyValue)(objectProp1.Properties[SR.ObjectServer]), (PropertyValue)(objectProp2.Properties[SR.ObjectServer])))
{
return false;
}
if (!CompareObjectPropertyValue((PropertyValue)(objectProp1.Properties[SR.ObjectSchema]), (PropertyValue)(objectProp2.Properties[SR.ObjectSchema])))
{
return false;
}
if (!CompareObjectPropertyValue((PropertyValue)(objectProp1.Properties[SR.ObjectTable]), (PropertyValue)(objectProp2.Properties[SR.ObjectTable])))
{
return false;
}
if (!CompareObjectPropertyValue((PropertyValue)(objectProp1.Properties[SR.ObjectAlias]), (PropertyValue)(objectProp2.Properties[SR.ObjectAlias])))
{
return false;
}
// check for CloneAccessScope if it is specified
PropertyValue specified1 = (PropertyValue)(objectProp1.Properties["CloneAccessScopeSpecified"]);
PropertyValue specified2 = (PropertyValue)(objectProp2.Properties["CloneAccessScopeSpecified"]);
if (specified1 == null && specified2 != null || specified1 != null && specified2 == null)
{
return false;
}
else if (specified1 != null && specified2 != null)
{
if ((bool)(specified1.Value) != (bool)(specified2.Value))
{
return false;
}
else
{
if ((bool)(specified1.Value) == true)
{
PropertyValue p1 = (PropertyValue)(objectProp1.Properties["CloneAccessScope"]);
PropertyValue p2 = (PropertyValue)(objectProp2.Properties["CloneAccessScope"]);
if (p1 == null && p2 != null || p1 != null && p2 == null)
{
return false;
}
else if (p1 != null && p2 != null)
{
if ((CloneAccessScopeType)(p1.Value) != (CloneAccessScopeType)(p2.Value))
{
return false;
}
}
}
}
}
}
else
{
if (objectProp1.DisplayName != objectProp2.DisplayName)
{
return false;
}
}
}
// same logical op, no other criteria
return true;
}