This is an automated email from the ASF dual-hosted git repository. maxyang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit a76a41736cbcee1c87032267957ff24930962fc8 Author: David Kimura <[email protected]> AuthorDate: Fri Sep 9 09:16:20 2022 -0700 [ORCA] Fix duplicate cast predicates (#14061) ORCA commit f8990fbd5dfb enables more datatypes in constraint evaluation. However, it also exposed an issue in preprocessor step PexprInferPredicates() which can cause ORCA to produce a plan with duplicate casted predicates. This commit fixes the issue by deduplicating cast equality predicates. Example: Date-TimeStamp-HashJoin.mdp --- .../data/dxl/minidump/Date-TimeStamp-HashJoin.mdp | 2 +- .../NotWellDefinedDisjunctConjunctPredicates.mdp | 185 +++++++++++---------- .../data/dxl/minidump/TimeStamp-Date-HashJoin.mdp | 2 +- src/backend/gporca/libgpopt/src/base/CUtils.cpp | 26 +++ .../src/unittest/gpopt/minidump/CCastTest.cpp | 5 +- 5 files changed, 131 insertions(+), 89 deletions(-) diff --git a/src/backend/gporca/data/dxl/minidump/Date-TimeStamp-HashJoin.mdp b/src/backend/gporca/data/dxl/minidump/Date-TimeStamp-HashJoin.mdp index 7d2ded1d80..82768a7bdc 100644 --- a/src/backend/gporca/data/dxl/minidump/Date-TimeStamp-HashJoin.mdp +++ b/src/backend/gporca/data/dxl/minidump/Date-TimeStamp-HashJoin.mdp @@ -283,7 +283,7 @@ </dxl:Comparison> </dxl:LogicalJoin> </dxl:Query> - <dxl:Plan Id="0" SpaceSize="20"> + <dxl:Plan Id="0" SpaceSize="12"> <dxl:HashJoin JoinType="Inner"> <dxl:Properties> <dxl:Cost StartupCost="0" TotalCost="862.000955" Rows="1.000000" Width="32"/> diff --git a/src/backend/gporca/data/dxl/minidump/NotWellDefinedDisjunctConjunctPredicates.mdp b/src/backend/gporca/data/dxl/minidump/NotWellDefinedDisjunctConjunctPredicates.mdp index dfff274f62..a97fa816be 100644 --- a/src/backend/gporca/data/dxl/minidump/NotWellDefinedDisjunctConjunctPredicates.mdp +++ b/src/backend/gporca/data/dxl/minidump/NotWellDefinedDisjunctConjunctPredicates.mdp @@ -49,25 +49,8 @@ <dxl:Commutator Mdid="0.518.1.0"/> <dxl:InverseOp Mdid="0.96.1.0"/> </dxl:GPDBScalarOp> - <dxl:Type Mdid="0.16.1.0" Name="bool" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="1" PassByValue="true"> - <dxl:DistrOpfamily Mdid="0.2222.1.0"/> - <dxl:LegacyDistrOpfamily Mdid="0.7124.1.0"/> - <dxl:EqualityOp Mdid="0.91.1.0"/> - <dxl:InequalityOp Mdid="0.85.1.0"/> - <dxl:LessThanOp Mdid="0.58.1.0"/> - <dxl:LessThanEqualsOp Mdid="0.1694.1.0"/> - <dxl:GreaterThanOp Mdid="0.59.1.0"/> - <dxl:GreaterThanEqualsOp Mdid="0.1695.1.0"/> - <dxl:ComparisonOp Mdid="0.1693.1.0"/> - <dxl:ArrayType Mdid="0.1000.1.0"/> - <dxl:MinAgg Mdid="0.0.0.0"/> - <dxl:MaxAgg Mdid="0.0.0.0"/> - <dxl:AvgAgg Mdid="0.0.0.0"/> - <dxl:SumAgg Mdid="0.0.0.0"/> - <dxl:CountAgg Mdid="0.2147.1.0"/> - </dxl:Type> - <dxl:RelationStatistics Mdid="2.65554.1.0" Name="bar" Rows="1000.000000" RelPages="3" RelAllVisible="0" EmptyRelation="false"/> - <dxl:Relation Mdid="0.65554.1.0" Name="bar" IsTemporary="false" StorageType="Heap" DistributionPolicy="Hash" DistributionColumns="0" Keys="8,2" NumberLeafPartitions="0"> + <dxl:RelationStatistics Mdid="2.57354.1.0" Name="bar" Rows="1000.000000" RelPages="3" RelAllVisible="0" EmptyRelation="false"/> + <dxl:Relation Mdid="0.57354.1.0" Name="bar" IsTemporary="false" StorageType="Heap" DistributionPolicy="Hash" DistributionColumns="0" Keys="8,2" NumberLeafPartitions="0"> <dxl:Columns> <dxl:Column Name="a" Attno="1" Mdid="0.23.1.0" Nullable="true" ColWidth="4"> <dxl:DefaultValue/> @@ -104,6 +87,23 @@ <dxl:DistrOpfamily Mdid="0.1977.1.0"/> </dxl:DistrOpfamilies> </dxl:Relation> + <dxl:Type Mdid="0.16.1.0" Name="bool" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="1" PassByValue="true"> + <dxl:DistrOpfamily Mdid="0.2222.1.0"/> + <dxl:LegacyDistrOpfamily Mdid="0.7124.1.0"/> + <dxl:EqualityOp Mdid="0.91.1.0"/> + <dxl:InequalityOp Mdid="0.85.1.0"/> + <dxl:LessThanOp Mdid="0.58.1.0"/> + <dxl:LessThanEqualsOp Mdid="0.1694.1.0"/> + <dxl:GreaterThanOp Mdid="0.59.1.0"/> + <dxl:GreaterThanEqualsOp Mdid="0.1695.1.0"/> + <dxl:ComparisonOp Mdid="0.1693.1.0"/> + <dxl:ArrayType Mdid="0.1000.1.0"/> + <dxl:MinAgg Mdid="0.0.0.0"/> + <dxl:MaxAgg Mdid="0.0.0.0"/> + <dxl:AvgAgg Mdid="0.0.0.0"/> + <dxl:SumAgg Mdid="0.0.0.0"/> + <dxl:CountAgg Mdid="0.2147.1.0"/> + </dxl:Type> <dxl:Type Mdid="0.20.1.0" Name="Int8" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="8" PassByValue="true"> <dxl:DistrOpfamily Mdid="0.1977.1.0"/> <dxl:LegacyDistrOpfamily Mdid="0.7100.1.0"/> @@ -146,6 +146,23 @@ <dxl:Commutator Mdid="0.411.1.0"/> <dxl:InverseOp Mdid="0.410.1.0"/> </dxl:GPDBScalarOp> + <dxl:GPDBScalarOp Mdid="0.410.1.0" Name="=" ComparisonType="Eq" ReturnsNullOnNullInput="true" IsNDVPreserving="false"> + <dxl:LeftType Mdid="0.20.1.0"/> + <dxl:RightType Mdid="0.20.1.0"/> + <dxl:ResultType Mdid="0.16.1.0"/> + <dxl:OpFunc Mdid="0.467.1.0"/> + <dxl:Commutator Mdid="0.410.1.0"/> + <dxl:InverseOp Mdid="0.411.1.0"/> + <dxl:HashOpfamily Mdid="0.1977.1.0"/> + <dxl:LegacyHashOpfamily Mdid="0.7100.1.0"/> + <dxl:Opfamilies> + <dxl:Opfamily Mdid="0.1976.1.0"/> + <dxl:Opfamily Mdid="0.1977.1.0"/> + <dxl:Opfamily Mdid="0.4054.1.0"/> + <dxl:Opfamily Mdid="0.7100.1.0"/> + <dxl:Opfamily Mdid="0.10009.1.0"/> + </dxl:Opfamilies> + </dxl:GPDBScalarOp> <dxl:Type Mdid="0.26.1.0" Name="oid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true"> <dxl:DistrOpfamily Mdid="0.1990.1.0"/> <dxl:LegacyDistrOpfamily Mdid="0.7109.1.0"/> @@ -180,7 +197,68 @@ <dxl:SumAgg Mdid="0.0.0.0"/> <dxl:CountAgg Mdid="0.2147.1.0"/> </dxl:Type> - <dxl:ColumnStatistics Mdid="1.65554.1.0.1" Name="b" Width="4.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false"> + <dxl:Type Mdid="0.29.1.0" Name="cid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true"> + <dxl:DistrOpfamily Mdid="0.2226.1.0"/> + <dxl:EqualityOp Mdid="0.385.1.0"/> + <dxl:InequalityOp Mdid="0.0.0.0"/> + <dxl:LessThanOp Mdid="0.0.0.0"/> + <dxl:LessThanEqualsOp Mdid="0.0.0.0"/> + <dxl:GreaterThanOp Mdid="0.0.0.0"/> + <dxl:GreaterThanEqualsOp Mdid="0.0.0.0"/> + <dxl:ComparisonOp Mdid="0.0.0.0"/> + <dxl:ArrayType Mdid="0.1012.1.0"/> + <dxl:MinAgg Mdid="0.0.0.0"/> + <dxl:MaxAgg Mdid="0.0.0.0"/> + <dxl:AvgAgg Mdid="0.0.0.0"/> + <dxl:SumAgg Mdid="0.0.0.0"/> + <dxl:CountAgg Mdid="0.2147.1.0"/> + </dxl:Type> + <dxl:Type Mdid="0.28.1.0" Name="xid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true"> + <dxl:DistrOpfamily Mdid="0.2225.1.0"/> + <dxl:EqualityOp Mdid="0.352.1.0"/> + <dxl:InequalityOp Mdid="0.3315.1.0"/> + <dxl:LessThanOp Mdid="0.0.0.0"/> + <dxl:LessThanEqualsOp Mdid="0.0.0.0"/> + <dxl:GreaterThanOp Mdid="0.0.0.0"/> + <dxl:GreaterThanEqualsOp Mdid="0.0.0.0"/> + <dxl:ComparisonOp Mdid="0.0.0.0"/> + <dxl:ArrayType Mdid="0.1011.1.0"/> + <dxl:MinAgg Mdid="0.0.0.0"/> + <dxl:MaxAgg Mdid="0.0.0.0"/> + <dxl:AvgAgg Mdid="0.0.0.0"/> + <dxl:SumAgg Mdid="0.0.0.0"/> + <dxl:CountAgg Mdid="0.2147.1.0"/> + </dxl:Type> + <dxl:GPDBScalarOp Mdid="0.416.1.0" Name="=" ComparisonType="Eq" ReturnsNullOnNullInput="true" IsNDVPreserving="false"> + <dxl:LeftType Mdid="0.20.1.0"/> + <dxl:RightType Mdid="0.23.1.0"/> + <dxl:ResultType Mdid="0.16.1.0"/> + <dxl:OpFunc Mdid="0.474.1.0"/> + <dxl:Commutator Mdid="0.15.1.0"/> + <dxl:InverseOp Mdid="0.417.1.0"/> + <dxl:HashOpfamily Mdid="0.1977.1.0"/> + <dxl:LegacyHashOpfamily Mdid="0.7100.1.0"/> + <dxl:Opfamilies> + <dxl:Opfamily Mdid="0.1976.1.0"/> + <dxl:Opfamily Mdid="0.1977.1.0"/> + <dxl:Opfamily Mdid="0.4054.1.0"/> + <dxl:Opfamily Mdid="0.7100.1.0"/> + <dxl:Opfamily Mdid="0.10009.1.0"/> + </dxl:Opfamilies> + </dxl:GPDBScalarOp> + <dxl:GPDBScalarOp Mdid="0.417.1.0" Name="<>" ComparisonType="NEq" ReturnsNullOnNullInput="true" IsNDVPreserving="false"> + <dxl:LeftType Mdid="0.20.1.0"/> + <dxl:RightType Mdid="0.23.1.0"/> + <dxl:ResultType Mdid="0.16.1.0"/> + <dxl:OpFunc Mdid="0.475.1.0"/> + <dxl:Commutator Mdid="0.36.1.0"/> + <dxl:InverseOp Mdid="0.416.1.0"/> + </dxl:GPDBScalarOp> + <dxl:MDScalarComparison Mdid="4.20.1.0;23.1.0;0" Name="=" ComparisonType="Eq" LeftType="0.20.1.0" RightType="0.23.1.0" OperatorMdid="0.416.1.0"/> + <dxl:GPDBFunc Mdid="0.481.1.0" Name="int8" ReturnsSet="false" Stability="Immutable" DataAccess="NoSQL" IsStrict="true" IsNDVPreserving="false" IsAllowedForPS="false"> + <dxl:ResultType Mdid="0.20.1.0"/> + </dxl:GPDBFunc> + <dxl:ColumnStatistics Mdid="1.57354.1.0.1" Name="b" Width="4.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false"> <dxl:StatsBucket Frequency="0.010000" DistinctValues="10.000000"> <dxl:LowerBound Closed="true" TypeMdid="0.23.1.0" Value="1"/> <dxl:UpperBound Closed="false" TypeMdid="0.23.1.0" Value="10"/> @@ -582,7 +660,7 @@ <dxl:UpperBound Closed="true" TypeMdid="0.23.1.0" Value="1000"/> </dxl:StatsBucket> </dxl:ColumnStatistics> - <dxl:ColumnStatistics Mdid="1.65554.1.0.0" Name="a" Width="4.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false"> + <dxl:ColumnStatistics Mdid="1.57354.1.0.0" Name="a" Width="4.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false"> <dxl:StatsBucket Frequency="0.010000" DistinctValues="10.000000"> <dxl:LowerBound Closed="true" TypeMdid="0.23.1.0" Value="1"/> <dxl:UpperBound Closed="false" TypeMdid="0.23.1.0" Value="10"/> @@ -984,67 +1062,6 @@ <dxl:UpperBound Closed="true" TypeMdid="0.23.1.0" Value="1000"/> </dxl:StatsBucket> </dxl:ColumnStatistics> - <dxl:Type Mdid="0.29.1.0" Name="cid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true"> - <dxl:DistrOpfamily Mdid="0.2226.1.0"/> - <dxl:EqualityOp Mdid="0.385.1.0"/> - <dxl:InequalityOp Mdid="0.0.0.0"/> - <dxl:LessThanOp Mdid="0.0.0.0"/> - <dxl:LessThanEqualsOp Mdid="0.0.0.0"/> - <dxl:GreaterThanOp Mdid="0.0.0.0"/> - <dxl:GreaterThanEqualsOp Mdid="0.0.0.0"/> - <dxl:ComparisonOp Mdid="0.0.0.0"/> - <dxl:ArrayType Mdid="0.1012.1.0"/> - <dxl:MinAgg Mdid="0.0.0.0"/> - <dxl:MaxAgg Mdid="0.0.0.0"/> - <dxl:AvgAgg Mdid="0.0.0.0"/> - <dxl:SumAgg Mdid="0.0.0.0"/> - <dxl:CountAgg Mdid="0.2147.1.0"/> - </dxl:Type> - <dxl:Type Mdid="0.28.1.0" Name="xid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true"> - <dxl:DistrOpfamily Mdid="0.2225.1.0"/> - <dxl:EqualityOp Mdid="0.352.1.0"/> - <dxl:InequalityOp Mdid="0.3315.1.0"/> - <dxl:LessThanOp Mdid="0.0.0.0"/> - <dxl:LessThanEqualsOp Mdid="0.0.0.0"/> - <dxl:GreaterThanOp Mdid="0.0.0.0"/> - <dxl:GreaterThanEqualsOp Mdid="0.0.0.0"/> - <dxl:ComparisonOp Mdid="0.0.0.0"/> - <dxl:ArrayType Mdid="0.1011.1.0"/> - <dxl:MinAgg Mdid="0.0.0.0"/> - <dxl:MaxAgg Mdid="0.0.0.0"/> - <dxl:AvgAgg Mdid="0.0.0.0"/> - <dxl:SumAgg Mdid="0.0.0.0"/> - <dxl:CountAgg Mdid="0.2147.1.0"/> - </dxl:Type> - <dxl:GPDBScalarOp Mdid="0.416.1.0" Name="=" ComparisonType="Eq" ReturnsNullOnNullInput="true" IsNDVPreserving="false"> - <dxl:LeftType Mdid="0.20.1.0"/> - <dxl:RightType Mdid="0.23.1.0"/> - <dxl:ResultType Mdid="0.16.1.0"/> - <dxl:OpFunc Mdid="0.474.1.0"/> - <dxl:Commutator Mdid="0.15.1.0"/> - <dxl:InverseOp Mdid="0.417.1.0"/> - <dxl:HashOpfamily Mdid="0.1977.1.0"/> - <dxl:LegacyHashOpfamily Mdid="0.7100.1.0"/> - <dxl:Opfamilies> - <dxl:Opfamily Mdid="0.1976.1.0"/> - <dxl:Opfamily Mdid="0.1977.1.0"/> - <dxl:Opfamily Mdid="0.4054.1.0"/> - <dxl:Opfamily Mdid="0.7100.1.0"/> - <dxl:Opfamily Mdid="0.10009.1.0"/> - </dxl:Opfamilies> - </dxl:GPDBScalarOp> - <dxl:GPDBScalarOp Mdid="0.417.1.0" Name="<>" ComparisonType="NEq" ReturnsNullOnNullInput="true" IsNDVPreserving="false"> - <dxl:LeftType Mdid="0.20.1.0"/> - <dxl:RightType Mdid="0.23.1.0"/> - <dxl:ResultType Mdid="0.16.1.0"/> - <dxl:OpFunc Mdid="0.475.1.0"/> - <dxl:Commutator Mdid="0.36.1.0"/> - <dxl:InverseOp Mdid="0.416.1.0"/> - </dxl:GPDBScalarOp> - <dxl:MDScalarComparison Mdid="4.20.1.0;23.1.0;0" Name="=" ComparisonType="Eq" LeftType="0.20.1.0" RightType="0.23.1.0" OperatorMdid="0.416.1.0"/> - <dxl:GPDBFunc Mdid="0.481.1.0" Name="int8" ReturnsSet="false" Stability="Immutable" DataAccess="NoSQL" IsStrict="true" IsNDVPreserving="false" IsAllowedForPS="false"> - <dxl:ResultType Mdid="0.20.1.0"/> - </dxl:GPDBFunc> <dxl:MDCast Mdid="3.23.1.0;20.1.0" Name="int8" BinaryCoercible="false" SourceTypeId="0.23.1.0" DestinationTypeId="0.20.1.0" CastFuncId="0.481.1.0" CoercePathType="1"/> </dxl:Metadata> <dxl:Query> @@ -1062,7 +1079,7 @@ </dxl:ProjElem> </dxl:ProjList> <dxl:LogicalGet> - <dxl:TableDescriptor Mdid="0.65554.1.0" TableName="bar" LockMode="1"> + <dxl:TableDescriptor Mdid="0.57354.1.0" TableName="bar" LockMode="1"> <dxl:Columns> <dxl:Column ColId="1" Attno="1" ColName="a" TypeMdid="0.23.1.0" ColWidth="4"/> <dxl:Column ColId="2" Attno="2" ColName="b" TypeMdid="0.23.1.0" ColWidth="4"/> @@ -1208,7 +1225,7 @@ </dxl:ProjElem> </dxl:ProjList> <dxl:Filter/> - <dxl:TableDescriptor Mdid="0.65554.1.0" TableName="bar" LockMode="1"> + <dxl:TableDescriptor Mdid="0.57354.1.0" TableName="bar" LockMode="1"> <dxl:Columns> <dxl:Column ColId="12" Attno="1" ColName="a" TypeMdid="0.23.1.0" ColWidth="4"/> <dxl:Column ColId="11" Attno="2" ColName="b" TypeMdid="0.23.1.0" ColWidth="4"/> diff --git a/src/backend/gporca/data/dxl/minidump/TimeStamp-Date-HashJoin.mdp b/src/backend/gporca/data/dxl/minidump/TimeStamp-Date-HashJoin.mdp index 240be11b79..cf9422a968 100644 --- a/src/backend/gporca/data/dxl/minidump/TimeStamp-Date-HashJoin.mdp +++ b/src/backend/gporca/data/dxl/minidump/TimeStamp-Date-HashJoin.mdp @@ -291,7 +291,7 @@ </dxl:Comparison> </dxl:LogicalJoin> </dxl:Query> - <dxl:Plan Id="0" SpaceSize="20"> + <dxl:Plan Id="0" SpaceSize="12"> <dxl:HashJoin JoinType="Inner"> <dxl:Properties> <dxl:Cost StartupCost="0" TotalCost="862.000955" Rows="1.000000" Width="32"/> diff --git a/src/backend/gporca/libgpopt/src/base/CUtils.cpp b/src/backend/gporca/libgpopt/src/base/CUtils.cpp index 49dfef3dba..536e7c0606 100644 --- a/src/backend/gporca/libgpopt/src/base/CUtils.cpp +++ b/src/backend/gporca/libgpopt/src/base/CUtils.cpp @@ -1433,6 +1433,32 @@ CUtils::PdrgpexprDedup(CMemoryPool *mp, CExpressionArray *pdrgpexpr) { pexpr->Release(); } + + // Here we also take into account cast equality expressions. This + // allows us to consider the following 2 expressions as duplicates. + // + // 1) + // +--CScalarCmp (=) + // |--CScalarIdent "d" (1) + // +--CScalarIdent "d" (10) + // 2) + // +--CScalarCmp (=) + // |--CScalarCast + // | +--CScalarIdent "d" (1) + // +--CScalarIdent "d" (10) + if (pexpr->Pop()->Eopid() == COperator::EopScalarCmp) + { + CExpressionArray *pdexpr = + CCastUtils::PdrgpexprCastEquality(mp, pexpr); + for (ULONG ulInner = 0; ulInner < pdexpr->Size(); ulInner++) + { + if (phsexpr->Insert((*pdexpr)[ulInner])) + { + (*pdexpr)[ulInner]->AddRef(); + } + } + pdexpr->Release(); + } } phsexpr->Release(); diff --git a/src/backend/gporca/server/src/unittest/gpopt/minidump/CCastTest.cpp b/src/backend/gporca/server/src/unittest/gpopt/minidump/CCastTest.cpp index 200aeb407e..92dbb24388 100644 --- a/src/backend/gporca/server/src/unittest/gpopt/minidump/CCastTest.cpp +++ b/src/backend/gporca/server/src/unittest/gpopt/minidump/CCastTest.cpp @@ -39,9 +39,8 @@ const CHAR *rgszCastMdpFiles[] = { "../data/dxl/minidump/HashJoinOnRelabeledColumns.mdp", "../data/dxl/minidump/Correlation-With-Casting-1.mdp", "../data/dxl/minidump/Correlation-With-Casting-2.mdp", - // GPDB_12_MERGE_FIXME: Produces duplicate cast predicates - // "../data/dxl/minidump/Date-TimeStamp-HashJoin.mdp", - // "../data/dxl/minidump/TimeStamp-Date-HashJoin.mdp", + "../data/dxl/minidump/Date-TimeStamp-HashJoin.mdp", + "../data/dxl/minidump/TimeStamp-Date-HashJoin.mdp", }; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
