// test cardinality for predicates of the form: a + c = b
	// for such predicates, NDV based cardinality estimation is not applicable
	GPOS_RESULT
	CJoinCardinalityNDVBasedEqPredTest::EresUnittest_NDVCardEstimationNotApplicableMultipleIdents()
	{
		// cartesian product / 2.5
		// 2.5 = 1/.4 -- where .4 is default selectivity
		CDouble dRowsExpected(76004000);

		Fixture f(file_name);
		IMemoryPool *mp = f.Pmp();
		IStatisticsArray *statistics_array = f.PdrgPstat();

		CExpression *pexprLgGet = CTestUtils::PexprLogicalGet(mp);
		CLogicalGet *popGet = CLogicalGet::PopConvert(pexprLgGet->Pop());
		CColRefArray *colref_array = popGet->PdrgpcrOutput();

		// use the colid available in the input xml file
		CColRef *pcrLeft1 = (*colref_array)[2];
		CColRef *pcrLeft2 = (*colref_array)[1];
		CColRef *pcrRight = (*colref_array)[0];

		// create a scalar ident
		// CScalarIdent "column_0000" (0)
		CExpression *pexprScalarIdentRight = CUtils::PexprScalarIdent(mp, pcrRight);
		CExpression *pexprScalarIdentLeft2 = CUtils::PexprScalarIdent(mp, pcrLeft2);

		// create a scalar op expression column_0002 + column_0001
		//  CScalarOp (+)
		//	|--CScalarIdent "column_0002" (2)
		//	+--CScalarIdent "column_0001" (1)
		CExpression *pexprScOp = CUtils::PexprScalarOp(mp, pcrLeft1, pexprScalarIdentLeft2,
													   CWStringConst(GPOS_WSZ_LIT("+")),
													   GPOS_NEW(mp) CMDIdGPDB(GPDB_INT4_ADD_OP));

		// create a scalar comparision operator
		//	+--CScalarCmp (=)
		//	|--CScalarOp (+)
		//	|  |--CScalarIdent "column_0002" (2)
		//	|  +--CScalarIdent "column_0001" (1)
		//	+--CScalarIdent "column_0000" (0)
		CExpression *pScalarCmp = CUtils::PexprScalarEqCmp(mp, pexprScOp, pexprScalarIdentRight);
		IStatistics *join_stats = CJoinStatsProcessor::CalcAllJoinStats(mp, statistics_array, pScalarCmp,
																	   IStatistics::EsjtInnerJoin);

		GPOS_ASSERT(NULL != join_stats);
		CDouble dRowsActual(join_stats->Rows());

		GPOS_RESULT eres = GPOS_OK;
		if (floor(dRowsActual.Get()) != dRowsExpected)
		{
			eres = GPOS_FAILED;
		}

		join_stats->Release();
		pexprLgGet->Release();
		pScalarCmp->Release();

		return eres;
	}
Пример #2
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializePlan
//
//	@doc:
//		Verifies that after parsing the given DXL file into a DXL tree,
//		it will be serialized back to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializePlan
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	CWStringDynamic str(pmp);
	COstreamString oss(&str);
	
	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);

	GPOS_CHECK_ABORT;
		
	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{  
	   szValidationPath = CTestUtils::m_szXSDPath;
	}

	// the root of the parsed DXL tree
	ULLONG ullPlanId = ULLONG_MAX;
	ULLONG ullPlanSpaceSize = ULLONG_MAX;
	CDXLNode *pdxlnRoot = CDXLUtils::PdxlnParsePlan(pmp, szDXL, szValidationPath, &ullPlanId, &ullPlanSpaceSize);
	
	GPOS_CHECK_ABORT;

	oss << "Serializing parsed tree" << std::endl;

	CWStringDynamic strPlan(pmp);
	COstreamString osPlan(&strPlan);

	CDXLUtils::SerializePlan(pmp, osPlan, pdxlnRoot, ullPlanId, ullPlanSpaceSize, true /*fSerializeHeaderFooter*/, true /*fIndent*/);

	GPOS_CHECK_ABORT;

	CWStringDynamic dstrExpected(pmp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);

	if (!dstrExpected.FEquals(&strPlan))
	{
		GPOS_TRACE(dstrExpected.Wsz());
		GPOS_TRACE(strPlan.Wsz());

		GPOS_ASSERT(!"Not matching");
	}
	
	// cleanup
	pdxlnRoot->Release();
	GPOS_DELETE_ARRAY(szDXL);
	
	return GPOS_OK;
}
Пример #3
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializePlan
//
//	@doc:
//		Verifies that after parsing the given DXL file into a DXL tree,
//		it will be serialized back to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializePlan
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	CWStringDynamic str(mp);
	COstreamString oss(&str);
	
	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);

	GPOS_CHECK_ABORT;
		
	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{  
	   szValidationPath = CTestUtils::m_szXSDPath;
	}

	// the root of the parsed DXL tree
	ULLONG plan_id = gpos::ullong_max;
	ULLONG plan_space_size = gpos::ullong_max;
	CDXLNode *root_dxl_node = CDXLUtils::GetPlanDXLNode(mp, dxl_string, szValidationPath, &plan_id, &plan_space_size);
	
	GPOS_CHECK_ABORT;

	oss << "Serializing parsed tree" << std::endl;

	CWStringDynamic strPlan(mp);
	COstreamString osPlan(&strPlan);

	CDXLUtils::SerializePlan(mp, osPlan, root_dxl_node, plan_id, plan_space_size, true /*serialize_header_footer*/, true /*indentation*/);

	GPOS_CHECK_ABORT;

	CWStringDynamic dstrExpected(mp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);

	if (!dstrExpected.Equals(&strPlan))
	{
		GPOS_TRACE(dstrExpected.GetBuffer());
		GPOS_TRACE(strPlan.GetBuffer());

		GPOS_ASSERT(!"Not matching");
	}
	
	// cleanup
	root_dxl_node->Release();
	GPOS_DELETE_ARRAY(dxl_string);
	
	return GPOS_OK;
}
Пример #4
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeMetadata
//
//	@doc:
//		Verifies that after parsing the given DXL file containing metadata into 
//		a list of metadata objects, which should be serialized back to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeMetadata
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	CWStringDynamic str(mp);
	COstreamString oss(&str);

	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);

	GPOS_CHECK_ABORT;
	
	// parse the metadata objects into a dynamic array	
	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{  
	   szValidationPath = CTestUtils::m_szXSDPath;
	}
	
	IMDCacheObjectArray *mdcache_obj_array = CDXLUtils::ParseDXLToIMDObjectArray(mp, dxl_string, szValidationPath);
	
	GPOS_ASSERT(NULL != mdcache_obj_array);
	
	GPOS_CHECK_ABORT;

	oss << "Serializing metadata objects" << std::endl;
	CWStringDynamic *metadata_str = CDXLUtils::SerializeMetadata(mp, mdcache_obj_array, true /*serialize_header_footer*/, true /*indentation*/);

	GPOS_CHECK_ABORT;

	CWStringDynamic dstrExpected(mp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);
	
	if (!dstrExpected.Equals(metadata_str))
	{
		GPOS_TRACE(metadata_str->GetBuffer());
		GPOS_ASSERT(false);
	}

	mdcache_obj_array->Release();
	GPOS_DELETE(metadata_str);
	GPOS_DELETE_ARRAY(dxl_string);
	
	return GPOS_OK;
}
Пример #5
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeMetadata
//
//	@doc:
//		Verifies that after parsing the given DXL file containing metadata into 
//		a list of metadata objects, which should be serialized back to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeMetadata
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	CWStringDynamic str(pmp);
	COstreamString oss(&str);

	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);

	GPOS_CHECK_ABORT;
	
	// parse the metadata objects into a dynamic array	
	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{  
	   szValidationPath = CTestUtils::m_szXSDPath;
	}
	
	DrgPimdobj *pdrgpmdobj = CDXLUtils::PdrgpmdobjParseDXL(pmp, szDXL, szValidationPath);
	
	GPOS_ASSERT(NULL != pdrgpmdobj);
	
	GPOS_CHECK_ABORT;

	oss << "Serializing metadata objects" << std::endl;
	CWStringDynamic *pstr = CDXLUtils::PstrSerializeMetadata(pmp, pdrgpmdobj, true /*fSerializeHeaderFooter*/, true /*fIndent*/);

	GPOS_CHECK_ABORT;

	CWStringDynamic dstrExpected(pmp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);
	
	if (!dstrExpected.FEquals(pstr))
	{
		GPOS_TRACE(pstr->Wsz());
		GPOS_ASSERT(false);
	}

	pdrgpmdobj->Release();
	GPOS_DELETE(pstr);
	GPOS_DELETE_ARRAY(szDXL);
	
	return GPOS_OK;
}
Пример #6
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeQuery
//
//	@doc:
//		Verifies that after parsing the given DXL file into a DXL tree
//		representing a query, it will be serialized back to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeQuery
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	CWStringDynamic str(mp);
	COstreamString oss(&str);

	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);

	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{
		szValidationPath = CTestUtils::m_szXSDPath;
	}
	
	// the root of the parsed DXL tree
	CQueryToDXLResult *pq2dxlresult = CDXLUtils::ParseQueryToQueryDXLTree(mp, dxl_string, szValidationPath);
	GPOS_ASSERT(NULL != pq2dxlresult);

	oss << "Serializing parsed tree" << std::endl;

	CDXLNode *root_dxlnode = const_cast<CDXLNode *>(pq2dxlresult->CreateDXLNode());
	CDXLNodeArray* dxl_array = const_cast<CDXLNodeArray* >(pq2dxlresult->GetOutputColumnsDXLArray());
	CDXLNodeArray* cte_producers = const_cast<CDXLNodeArray* >(pq2dxlresult->GetCTEProducerDXLArray());

	CWStringDynamic wstrQuery(mp);
	COstreamString osQuery(&wstrQuery);

	CDXLUtils::SerializeQuery(mp, osQuery, root_dxlnode, dxl_array, cte_producers, true /*serialize_header_footer*/, true /*indentation*/);

	CWStringDynamic dstrExpected(mp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);

	if (!dstrExpected.Equals(&wstrQuery))
	{
		GPOS_TRACE(wstrQuery.GetBuffer());
	}

	// cleanup
	GPOS_DELETE(pq2dxlresult);
	GPOS_DELETE_ARRAY(dxl_string);

	return GPOS_OK;
}
Пример #7
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeQuery
//
//	@doc:
//		Verifies that after parsing the given DXL file into a DXL tree
//		representing a query, it will be serialized back to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeQuery
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	CWStringDynamic str(pmp);
	COstreamString oss(&str);

	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);

	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{
		szValidationPath = CTestUtils::m_szXSDPath;
	}
	
	// the root of the parsed DXL tree
	CQueryToDXLResult *pq2dxlresult = CDXLUtils::PdxlnParseDXLQuery(pmp, szDXL, szValidationPath);
	GPOS_ASSERT(NULL != pq2dxlresult);

	oss << "Serializing parsed tree" << std::endl;

	CDXLNode *pdxlnRoot = const_cast<CDXLNode *>(pq2dxlresult->Pdxln());
	DrgPdxln* pdrgpdxln = const_cast<DrgPdxln* >(pq2dxlresult->PdrgpdxlnOutputCols());
	DrgPdxln* pdrgpdxlnCTE = const_cast<DrgPdxln* >(pq2dxlresult->PdrgpdxlnCTE());

	CWStringDynamic wstrQuery(pmp);
	COstreamString osQuery(&wstrQuery);

	CDXLUtils::SerializeQuery(pmp, osQuery, pdxlnRoot, pdrgpdxln, pdrgpdxlnCTE, true /*fSerializeHeaderFooter*/, true /*fIndent*/);

	CWStringDynamic dstrExpected(pmp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);

	if (!dstrExpected.FEquals(&wstrQuery))
	{
		GPOS_TRACE(wstrQuery.Wsz());
	}

	// cleanup
	GPOS_DELETE(pq2dxlresult);
	GPOS_DELETE_ARRAY(szDXL);

	return GPOS_OK;
}
Пример #8
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeScalarExpr
//
//	@doc:
//      Parses a ScalarExpr and verifies that the serialization is identical
//      to the original input.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeScalarExpr
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);
	GPOS_CHECK_ABORT;

	const CHAR *szValidationPath = NULL;
	if (fValidate)
	{
		szValidationPath = CTestUtils::m_szXSDPath;
	}

	// the root of the parsed DXL tree
	CDXLNode *pdxlnRoot = CDXLUtils::PdxlnParseScalarExpr(pmp, szDXL, szValidationPath);
	GPOS_CHECK_ABORT;

	CWStringDynamic str(pmp);
	COstreamString oss(&str);
	oss << "Serializing parsed tree" << std::endl;
	CWStringDynamic *pstr = CDXLUtils::PstrSerializeScalarExpr(pmp, pdxlnRoot, true /*fSerializeHeaderFooter*/, true /*fIndent*/);
	GPOS_CHECK_ABORT;

	CWStringDynamic dstrExpected(pmp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);

	GPOS_RESULT eres = GPOS_OK;
	if (!dstrExpected.FEquals(pstr))
	{
		GPOS_TRACE(dstrExpected.Wsz());
		GPOS_TRACE(pstr->Wsz());

		GPOS_ASSERT(!"Not matching");
		eres = GPOS_FAILED;
	}

	// cleanup
	pdxlnRoot->Release();
	GPOS_DELETE(pstr);
	GPOS_DELETE_ARRAY(szDXL);

	return eres;
}
Пример #9
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeScalarExpr
//
//	@doc:
//      Parses a ScalarExpr and verifies that the serialization is identical
//      to the original input.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeScalarExpr
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);
	GPOS_CHECK_ABORT;

	const CHAR *szValidationPath = NULL;
	if (fValidate)
	{
		szValidationPath = CTestUtils::m_szXSDPath;
	}

	// the root of the parsed DXL tree
	CDXLNode *root_dxl_node = CDXLUtils::ParseDXLToScalarExprDXLNode(mp, dxl_string, szValidationPath);
	GPOS_CHECK_ABORT;

	CWStringDynamic str(mp);
	COstreamString oss(&str);
	oss << "Serializing parsed tree" << std::endl;
	CWStringDynamic *scalar_expr_str = CDXLUtils::SerializeScalarExpr(mp, root_dxl_node, true /*serialize_header_footer*/, true /*indentation*/);
	GPOS_CHECK_ABORT;

	CWStringDynamic dstrExpected(mp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);

	GPOS_RESULT eres = GPOS_OK;
	if (!dstrExpected.Equals(scalar_expr_str))
	{
		GPOS_TRACE(dstrExpected.GetBuffer());
		GPOS_TRACE(scalar_expr_str->GetBuffer());

		GPOS_ASSERT(!"Not matching");
		eres = GPOS_FAILED;
	}

	// cleanup
	root_dxl_node->Release();
	GPOS_DELETE(scalar_expr_str);
	GPOS_DELETE_ARRAY(dxl_string);

	return eres;
}
Пример #10
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeMDRequest
//
//	@doc:
//		Parse an MD request and verify correctness of serialization.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeMDRequest
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	CWStringDynamic str(pmp);
	COstreamString oss(&str);
	
	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);

	GPOS_CHECK_ABORT;
	
	// parse the mdid objects into a dynamic array	
	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{  
	   szValidationPath = CTestUtils::m_szXSDPath;
	}
	
	CMDRequest *pmdr = CDXLUtils::PmdrequestParseDXL(pmp, szDXL, szValidationPath);
	
	GPOS_ASSERT(NULL != pmdr);
	
	GPOS_CHECK_ABORT;

	CDXLUtils::SerializeMDRequest(pmp, pmdr, oss, true /*fSerializeHeaderFooter*/, true /*fIndent*/);

	GPOS_CHECK_ABORT;

	CWStringDynamic strExpected(pmp);
	strExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);
	
	GPOS_ASSERT(strExpected.FEquals(&str));

	pmdr->Release();
	GPOS_DELETE_ARRAY(szDXL);
	
	return GPOS_OK;
}
Пример #11
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeMDRequest
//
//	@doc:
//		Parse an MD request and verify correctness of serialization.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeMDRequest
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	CWStringDynamic str(mp);
	COstreamString oss(&str);
	
	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);

	GPOS_CHECK_ABORT;
	
	// parse the mdid objects into a dynamic array	
	const CHAR *szValidationPath = NULL;
	
	if (fValidate)
	{  
	   szValidationPath = CTestUtils::m_szXSDPath;
	}
	
	CMDRequest *pmdr = CDXLUtils::ParseDXLToMDRequest(mp, dxl_string, szValidationPath);
	
	GPOS_ASSERT(NULL != pmdr);
	
	GPOS_CHECK_ABORT;

	CDXLUtils::SerializeMDRequest(mp, pmdr, oss, true /*serialize_header_footer*/, true /*indentation*/);

	GPOS_CHECK_ABORT;

	CWStringDynamic strExpected(mp);
	strExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);
	
	GPOS_ASSERT(strExpected.Equals(&str));

	pmdr->Release();
	GPOS_DELETE_ARRAY(dxl_string);
	
	return GPOS_OK;
}
Пример #12
0
//---------------------------------------------------------------------------
//	@function:
//		CTableDescriptorTest::EresUnittest_Basic
//
//	@doc:
//		basic naming, assignment thru copy constructors
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTableDescriptorTest::EresUnittest_Basic()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	// Setup an MD cache with a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::Pcm(pmp)
					);

	CWStringConst strName(GPOS_WSZ_LIT("MyTable"));
	CMDIdGPDB *pmdid = GPOS_NEW(pmp) CMDIdGPDB(GPOPT_MDCACHE_TEST_OID, 1, 1);
	CTableDescriptor *ptabdesc = CTestUtils::PtabdescCreate(pmp, 10, pmdid, CName(&strName));

#ifdef GPOS_DEBUG
	CWStringDynamic str(pmp);
	COstreamString oss(&str);
	ptabdesc->OsPrint(oss);

	GPOS_TRACE(str.Wsz());
#endif // GPOS_DEBUG

	ptabdesc->Release();

	return GPOS_OK;
}
Пример #13
0
//---------------------------------------------------------------------------
//	@function:
//		COrderSpecTest::EresUnittest_Basics
//
//	@doc:
//		Basic order spec tests
//
//---------------------------------------------------------------------------
GPOS_RESULT
COrderSpecTest::EresUnittest_Basics()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();
		
	// Setup an MD cache with a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
	
	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL, /* pceeval */
					CTestUtils::Pcm(pmp)
					);
	
	// get column factory from optimizer context object
	CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();
	
	CWStringConst strName(GPOS_WSZ_LIT("Test Column"));
	CName name(&strName);
	
	const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>(CTestUtils::m_sysidDefault);		

	CColRef *pcr1 = pcf->PcrCreate(pmdtypeint4, name);
	CColRef *pcr2 = pcf->PcrCreate(pmdtypeint4, name);
	CColRef *pcr3 = pcf->PcrCreate(pmdtypeint4, name);
	
	
	COrderSpec *pos1 = GPOS_NEW(pmp) COrderSpec(pmp);
	
	IMDId *pmdidInt4LT = pmdtypeint4->PmdidCmp(IMDType::EcmptL);
	pmdidInt4LT->AddRef();
	pmdidInt4LT->AddRef();
	
	pos1->Append(pmdidInt4LT, pcr1, COrderSpec::EntFirst);
	pos1->Append(pmdidInt4LT, pcr2, COrderSpec::EntLast);

	GPOS_ASSERT(pos1->FMatch(pos1));
	GPOS_ASSERT(pos1->FSatisfies(pos1));
	
	COrderSpec *pos2 = GPOS_NEW(pmp) COrderSpec(pmp);
	pmdidInt4LT->AddRef();
	pmdidInt4LT->AddRef();
	pmdidInt4LT->AddRef();
		
	pos2->Append(pmdidInt4LT, pcr1, COrderSpec::EntFirst);
	pos2->Append(pmdidInt4LT, pcr2, COrderSpec::EntLast);
	pos2->Append(pmdidInt4LT, pcr3, COrderSpec::EntAuto);

	(void) pos1->UlHash();
	(void) pos2->UlHash();
	
	GPOS_ASSERT(pos2->FMatch(pos2));
	GPOS_ASSERT(pos2->FSatisfies(pos2));
	
	
	GPOS_ASSERT(!pos1->FMatch(pos2));
	GPOS_ASSERT(!pos2->FMatch(pos1));
	
	GPOS_ASSERT(pos2->FSatisfies(pos1));
	GPOS_ASSERT(!pos1->FSatisfies(pos2));
	
	// iterate over the components of the order spec
	for (ULONG ul = 0; ul < pos1->UlSortColumns(); ul++)
	{
#ifdef GPOS_DEBUG
		const CColRef *pcr =
#endif // GPOS_DEBUG
		pos1->Pcr(ul);
		
		GPOS_ASSERT(NULL != pcr);
		
#ifdef GPOS_DEBUG
		const IMDId *pmdid =
#endif // GPOS_DEBUG
		pos1->PmdidSortOp(ul);
		
		GPOS_ASSERT(pmdid->FValid());
		
		(void) pos1->Ent(ul);
	}
	
	pos1->Release();
	pos2->Release();

	return GPOS_OK;
}
Пример #14
0
//---------------------------------------------------------------------------
//	@function:
//		CPredicateUtilsTest::EresUnittest_Implication
//
//	@doc:
//		Test removal of implied predicates
//
//---------------------------------------------------------------------------
GPOS_RESULT
CPredicateUtilsTest::EresUnittest_Implication()
{
	CAutoMemoryPool amp;
	IMemoryPool *mp = amp.Pmp();

	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					mp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::GetCostModel(mp)
					);

	// generate a two cascaded joins
	CWStringConst strName1(GPOS_WSZ_LIT("Rel1"));
	CMDIdGPDB *pmdid1 = GPOS_NEW(mp) CMDIdGPDB(GPOPT_TEST_REL_OID1, 1, 1);
	CTableDescriptor *ptabdesc1 = CTestUtils::PtabdescCreate(mp, 3, pmdid1, CName(&strName1));
	CWStringConst strAlias1(GPOS_WSZ_LIT("Rel1"));
	CExpression *pexprRel1 = CTestUtils::PexprLogicalGet(mp, ptabdesc1, &strAlias1);

	CWStringConst strName2(GPOS_WSZ_LIT("Rel2"));
	CMDIdGPDB *pmdid2 = GPOS_NEW(mp) CMDIdGPDB(GPOPT_TEST_REL_OID2, 1, 1);
	CTableDescriptor *ptabdesc2 = CTestUtils::PtabdescCreate(mp, 3, pmdid2, CName(&strName2));
	CWStringConst strAlias2(GPOS_WSZ_LIT("Rel2"));
	CExpression *pexprRel2 = CTestUtils::PexprLogicalGet(mp, ptabdesc2, &strAlias2);

	CWStringConst strName3(GPOS_WSZ_LIT("Rel3"));
	CMDIdGPDB *pmdid3 = GPOS_NEW(mp) CMDIdGPDB(GPOPT_TEST_REL_OID3, 1, 1);
	CTableDescriptor *ptabdesc3 = CTestUtils::PtabdescCreate(mp, 3, pmdid3, CName(&strName3));
	CWStringConst strAlias3(GPOS_WSZ_LIT("Rel3"));
	CExpression *pexprRel3 = CTestUtils::PexprLogicalGet(mp, ptabdesc3, &strAlias3);

	CExpression *pexprJoin1 = CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>(mp, pexprRel1, pexprRel2);
	CExpression *pexprJoin2 = CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>(mp, pexprJoin1, pexprRel3);

	{
		CAutoTrace at(mp);
		at.Os() << "Original expression:" << std::endl << *pexprJoin2 <<std::endl;
	}

	// imply new predicates by deriving constraints
	CExpression *pexprConstraints = CExpressionPreprocessor::PexprAddPredicatesFromConstraints(mp, pexprJoin2);

	{
		CAutoTrace at(mp);
		at.Os() << "Expression with implied predicates:" << std::endl << *pexprConstraints <<std::endl;;
	}

	// minimize join predicates by removing implied conjuncts
	CExpressionHandle exprhdl(mp);
	exprhdl.Attach(pexprConstraints);
	CExpression *pexprMinimizedPred = CPredicateUtils::PexprRemoveImpliedConjuncts(mp, (*pexprConstraints)[2], exprhdl);

	{
		CAutoTrace at(mp);
		at.Os() << "Minimized join predicate:" << std::endl << *pexprMinimizedPred <<std::endl;
	}

	CExpressionArray *pdrgpexprOriginalConjuncts = CPredicateUtils::PdrgpexprConjuncts(mp,  (*pexprConstraints)[2]);
	CExpressionArray *pdrgpexprNewConjuncts = CPredicateUtils::PdrgpexprConjuncts(mp, pexprMinimizedPred);

	GPOS_ASSERT(pdrgpexprNewConjuncts->Size() < pdrgpexprOriginalConjuncts->Size());

	// clean up
	pdrgpexprOriginalConjuncts->Release();
	pdrgpexprNewConjuncts->Release();
	pexprJoin2->Release();
	pexprConstraints->Release();
	pexprMinimizedPred->Release();

	return GPOS_OK;
}
Пример #15
0
//---------------------------------------------------------------------------
//	@function:
//		CPredicateUtilsTest::EresUnittest_PlainEqualities
//
//	@doc:
//		Test the extraction of equality predicates between scalar identifiers
//
//---------------------------------------------------------------------------
GPOS_RESULT
CPredicateUtilsTest::EresUnittest_PlainEqualities()
{
	CAutoMemoryPool amp;
	IMemoryPool *mp = amp.Pmp();

	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					mp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::GetCostModel(mp)
					);

	CExpression *pexprLeft = CTestUtils::PexprLogicalGet(mp);
	CExpression *pexprRight = CTestUtils::PexprLogicalGet(mp);

	CExpressionArray *pdrgpexprOriginal = GPOS_NEW(mp) CExpressionArray(mp);

	CColRefSet *pcrsLeft = CDrvdPropRelational::GetRelationalProperties(pexprLeft->PdpDerive())->PcrsOutput();
	CColRefSet *pcrsRight = CDrvdPropRelational::GetRelationalProperties(pexprRight->PdpDerive())->PcrsOutput();

	CColRef *pcrLeft = pcrsLeft->PcrAny();
	CColRef *pcrRight = pcrsRight->PcrAny();

	// generate an equality predicate between two column reference
	CExpression *pexprScIdentEquality =
		CUtils::PexprScalarEqCmp(mp, pcrLeft, pcrRight);

	pexprScIdentEquality->AddRef();
	pdrgpexprOriginal->Append(pexprScIdentEquality);

	// generate a non-equality predicate between two column reference
	CExpression *pexprScIdentInequality =
		CUtils::PexprScalarCmp(mp, pcrLeft, pcrRight, CWStringConst(GPOS_WSZ_LIT("<")), GPOS_NEW(mp) CMDIdGPDB(GPDB_INT4_LT_OP));

	pexprScIdentInequality->AddRef();
	pdrgpexprOriginal->Append(pexprScIdentInequality);

	// generate an equality predicate between a column reference and a constant value
	CExpression *pexprScalarConstInt4 = CUtils::PexprScalarConstInt4(mp, 10 /*fValue*/);
	CExpression *pexprScIdentConstEquality = CUtils::PexprScalarEqCmp(mp, pexprScalarConstInt4, pcrRight);

	pdrgpexprOriginal->Append(pexprScIdentConstEquality);

	GPOS_ASSERT(3 == pdrgpexprOriginal->Size());

	CExpressionArray *pdrgpexprResult = CPredicateUtils::PdrgpexprPlainEqualities(mp, pdrgpexprOriginal);

	GPOS_ASSERT(1 == pdrgpexprResult->Size());

	// clean up
	pdrgpexprOriginal->Release();
	pdrgpexprResult->Release();
	pexprLeft->Release();
	pexprRight->Release();
	pexprScIdentEquality->Release();
	pexprScIdentInequality->Release();

	return GPOS_OK;
}
Пример #16
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderTest::EresUnittest_ExpandMinCard
//
//	@doc:
//		Expansion expansion based on cardinality of intermediate results
//
//---------------------------------------------------------------------------
GPOS_RESULT
CJoinOrderTest::EresUnittest_ExpandMinCard()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	// array of relation names
	CWStringConst rgscRel[] =
	{
		GPOS_WSZ_LIT("Rel10"),
		GPOS_WSZ_LIT("Rel3"),
		GPOS_WSZ_LIT("Rel4"),
		GPOS_WSZ_LIT("Rel6"),
		GPOS_WSZ_LIT("Rel7"),
		GPOS_WSZ_LIT("Rel8"),
		GPOS_WSZ_LIT("Rel12"),
		GPOS_WSZ_LIT("Rel13"),
		GPOS_WSZ_LIT("Rel5"),
		GPOS_WSZ_LIT("Rel14"),
		GPOS_WSZ_LIT("Rel15"),
		GPOS_WSZ_LIT("Rel1"),
		GPOS_WSZ_LIT("Rel11"),
		GPOS_WSZ_LIT("Rel2"),
		GPOS_WSZ_LIT("Rel9"),
	};

	// array of relation IDs
	ULONG rgulRel[] =
	{
		GPOPT_TEST_REL_OID10,
		GPOPT_TEST_REL_OID3,
		GPOPT_TEST_REL_OID4,
		GPOPT_TEST_REL_OID6,
		GPOPT_TEST_REL_OID7,
		GPOPT_TEST_REL_OID8,
		GPOPT_TEST_REL_OID12,
		GPOPT_TEST_REL_OID13,
		GPOPT_TEST_REL_OID5,
		GPOPT_TEST_REL_OID14,
		GPOPT_TEST_REL_OID15,
		GPOPT_TEST_REL_OID1,
		GPOPT_TEST_REL_OID11,
		GPOPT_TEST_REL_OID2,
		GPOPT_TEST_REL_OID9,
	};

	const ULONG ulRels = GPOS_ARRAY_SIZE(rgscRel);
	GPOS_ASSERT(GPOS_ARRAY_SIZE(rgulRel) == ulRels);

	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache());
	mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp);

	{
		// install opt context in TLS
		CAutoOptCtxt aoc
				(
				pmp,
				&mda,
				NULL,  /* pceeval */
				CTestUtils::Pcm(pmp)
				);

		CExpression *pexprNAryJoin =
				CTestUtils::PexprLogicalNAryJoin(pmp, rgscRel, rgulRel, ulRels, false /*fCrossProduct*/);

		// derive stats on input expression
		CExpressionHandle exprhdl(pmp);
		exprhdl.Attach(pexprNAryJoin);
		exprhdl.DeriveStats(pmp, pmp, NULL /*prprel*/, NULL /*pdrgpstatCtxt*/);

		DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
		for (ULONG ul = 0; ul < ulRels; ul++)
		{
			CExpression *pexprChild = (*pexprNAryJoin)[ul];
			pexprChild->AddRef();
			pdrgpexpr->Append(pexprChild);
		}
		DrgPexpr *pdrgpexprPred = CPredicateUtils::PdrgpexprConjuncts(pmp, (*pexprNAryJoin)[ulRels]);
		pdrgpexpr->AddRef();
		pdrgpexprPred->AddRef();
		CJoinOrderMinCard jomc(pmp, pdrgpexpr, pdrgpexprPred);
		CExpression *pexprResult = jomc.PexprExpand();
		{
			CAutoTrace at(pmp);
			at.Os() << std::endl << "INPUT:" << std::endl << *pexprNAryJoin << std::endl;
			at.Os() << std::endl << "OUTPUT:" << std::endl << *pexprResult << std::endl;
		}
		pexprResult->Release();
		pexprNAryJoin->Release();
		pdrgpexpr->Release();
		pdrgpexprPred->Release();
	}

	return GPOS_OK;
}
Пример #17
0
//---------------------------------------------------------------------------
//	@function:
//		CContradictionTest::EresUnittest_Constraint
//
//	@doc:
//		Tests for constraint property derivation and constraint push down
//
//---------------------------------------------------------------------------
GPOS_RESULT
CContradictionTest::EresUnittest_Constraint()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);


	typedef CExpression *(*Pfpexpr)(IMemoryPool*);

	Pfpexpr rgpf[] =
		{
		CTestUtils::PexprLogicalApplyWithOuterRef<CLogicalInnerApply>,
		CTestUtils::PexprLogicalApply<CLogicalLeftSemiApply>,
		CTestUtils::PexprLogicalApply<CLogicalLeftAntiSemiApply>,
		CTestUtils::PexprLogicalApplyWithOuterRef<CLogicalLeftOuterApply>,
		CTestUtils::PexprLogicalGet,
		CTestUtils::PexprLogicalGetPartitioned,
		CTestUtils::PexprLogicalSelect,
		CTestUtils::PexprLogicalSelectCmpToConst,
		CTestUtils::PexprLogicalSelectPartitioned,
		CTestUtils::PexprLogicalSelectWithContradiction,
		CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>,
		CTestUtils::PexprLogicalJoin<CLogicalLeftOuterJoin>,
		CTestUtils::PexprLogicalJoin<CLogicalLeftSemiJoin>,
		CTestUtils::PexprLogicalJoin<CLogicalLeftAntiSemiJoin>,
		CTestUtils::PexprLogicalGbAgg,
		CTestUtils::PexprLogicalGbAggOverJoin,
		CTestUtils::PexprLogicalGbAggWithSum,
		CTestUtils::PexprLogicalLimit,
		CTestUtils::PexprLogicalNAryJoin,
		CTestUtils::PexprLogicalProject,
		CTestUtils::PexprConstTableGet5,
		CTestUtils::PexprLogicalDynamicGet,
		CTestUtils::PexprLogicalSequence,
		CTestUtils::PexprLogicalTVFTwoArgs,
		};

	for (ULONG i = 0; i < GPOS_ARRAY_SIZE(rgpf); i++)
	{
		// install opt context in TLS
		CAutoOptCtxt aoc
						(
						pmp,
						&mda,
						NULL,  /* pceeval */
						CTestUtils::Pcm(pmp)
						);

		// generate simple expression
		CExpression *pexpr = rgpf[i](pmp);

		// self-match
		GPOS_ASSERT(pexpr->FMatchDebug(pexpr));

		// debug print
		CWStringDynamic str(pmp, GPOS_WSZ_LIT("\n"));
		COstreamString oss(&str);

		oss << "EXPR:" << std::endl << *pexpr << std::endl;
		GPOS_TRACE(str.Wsz());
		str.Reset();


#ifdef GPOS_DEBUG
		// derive properties on expression
		(void) pexpr->PdpDerive();

		oss << std::endl << "DERIVED PROPS:" << std::endl;
		GPOS_TRACE(str.Wsz());
		str.Reset();
		pexpr->DbgPrint();
#endif // GPOS_DEBUG

 		CExpression *pexprPreprocessed = CExpressionPreprocessor::PexprPreprocess(pmp, pexpr);
		oss	<< std::endl << "PREPROCESSED EXPR:" << std::endl << *pexprPreprocessed << std::endl;
		GPOS_TRACE(str.Wsz());
		str.Reset();

		// cleanup
		pexprPreprocessed->Release();
		pexpr->Release();
	}

	return GPOS_OK;
}
Пример #18
0
//---------------------------------------------------------------------------
//	@function:
//		CColRefSetIterTest::EresUnittest_Basics
//
//	@doc:
//		Testing ctors/dtor; and pcr decoding;
//		Other functionality already tested in vanilla CBitSetIter;
//
//---------------------------------------------------------------------------
GPOS_RESULT
CColRefSetIterTest::EresUnittest_Basics()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	// Setup an MD cache with a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache());
	mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
				(
				pmp,
				&mda,
				NULL /* pceeval */,
				CTestUtils::Pcm(pmp)
				);

	// get column factory from optimizer context object
	CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();

	CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
	CWStringConst strName(GPOS_WSZ_LIT("Test Column"));
	CName name(&strName);

	// create a int4 datum
	const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>();


	ULONG ulCols = 10;
	for(ULONG i = 0; i < ulCols; i++)
	{
		CColRef *pcr = pcf->PcrCreate(pmdtypeint4, name);
		pcrs->Include(pcr);

		GPOS_ASSERT(pcrs->FMember(pcr));
	}

	GPOS_ASSERT(pcrs->CElements() == ulCols);

	ULONG ulCount = 0;
	CColRefSetIter crsi(*pcrs);
	while(crsi.FAdvance())
	{
		GPOS_ASSERT((BOOL)crsi);

		CColRef *pcr = crsi.Pcr();
		GPOS_ASSERT(pcr->Name().FEquals(name));

		// to avoid unused variable warnings
		(void) pcr->UlId();

		ulCount++;
	}

	GPOS_ASSERT(ulCols == ulCount);
	GPOS_ASSERT(!((BOOL)crsi));

	pcrs->Release();

	return GPOS_OK;
}
Пример #19
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeStatistics
//
//	@doc:
//		Verifies that after parsing the given DXL file containing statistics
//		into a list of statistics objects, which should be serialized back
//		to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeStatistics
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL /* pceeval */,
					CTestUtils::Pcm(pmp)
					);

	CWStringDynamic str(pmp);
	COstreamString oss(&str);

	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);

	GPOS_CHECK_ABORT;

	// parse the metadata objects into a dynamic array
	const CHAR *szValidationPath = NULL;
	if (fValidate)
	{
	   szValidationPath = CTestUtils::m_szXSDPath;
	}

	// parse the statistics objects
	DrgPdxlstatsderrel *pdrgpdxlstatsderrel = CDXLUtils::PdrgpdxlstatsderrelParseDXL(pmp, szDXL, szValidationPath);
	DrgPstats *pdrgpstat = CDXLUtils::PdrgpstatsTranslateStats
								(
								pmp,
								&mda,
								pdrgpdxlstatsderrel
								);

	pdrgpdxlstatsderrel->Release();


	GPOS_ASSERT(NULL != pdrgpstat);

	CStatistics *pstats = (* pdrgpstat)[0];
	GPOS_ASSERT(pstats);

	pstats->DRows();
	oss << "Statistics:" << std::endl;
	CStatisticsTest::Print(pmp, pstats);

	GPOS_CHECK_ABORT;

	oss << "Serializing Statistics Objects" << std::endl;
	CWStringDynamic *pstr = CDXLUtils::PstrSerializeStatistics
											(
											pmp,
											&mda,
											pdrgpstat,
											true /*fSerializeHeaderFooter*/,
											true /*fIndent*/
											);

	CWStringDynamic dstrExpected(pmp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);

	GPOS_ASSERT(dstrExpected.FEquals(pstr));

	pdrgpstat->Release();

	GPOS_DELETE_ARRAY(szDXL);
	GPOS_DELETE(pstr);
	return GPOS_OK;
}
Пример #20
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeStatistics
//
//	@doc:
//		Verifies that after parsing the given DXL file containing statistics
//		into a list of statistics objects, which should be serialized back
//		to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeStatistics
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					mp,
					&mda,
					NULL /* pceeval */,
					CTestUtils::GetCostModel(mp)
					);

	CWStringDynamic str(mp);
	COstreamString oss(&str);

	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);

	GPOS_CHECK_ABORT;

	// parse the metadata objects into a dynamic array
	const CHAR *szValidationPath = NULL;
	if (fValidate)
	{
	   szValidationPath = CTestUtils::m_szXSDPath;
	}

	// parse the statistics objects
	CDXLStatsDerivedRelationArray *dxl_derived_rel_stats_array = CDXLUtils::ParseDXLToStatsDerivedRelArray(mp, dxl_string, szValidationPath);
	CStatisticsArray *statistics_array = CDXLUtils::ParseDXLToOptimizerStatisticObjArray
								(
								mp,
								&mda,
								dxl_derived_rel_stats_array
								);

	dxl_derived_rel_stats_array->Release();


	GPOS_ASSERT(NULL != statistics_array);

	CStatistics *stats = (* statistics_array)[0];
	GPOS_ASSERT(stats);

	stats->Rows();
	oss << "Statistics:" << std::endl;
	CCardinalityTestUtils::PrintStats(mp, stats);

	GPOS_CHECK_ABORT;

	oss << "Serializing Statistics Objects" << std::endl;
	CWStringDynamic *statistics_str = CDXLUtils::SerializeStatistics
											(
											mp,
											&mda,
											statistics_array,
											true /*serialize_header_footer*/,
											true /*indentation*/
											);

	CWStringDynamic dstrExpected(mp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);

	GPOS_ASSERT(dstrExpected.Equals(statistics_str));

	statistics_array->Release();

	GPOS_DELETE_ARRAY(dxl_string);
	GPOS_DELETE(statistics_str);
	return GPOS_OK;
}
	// test cardinality for predicates of the form: a + 1 = b
	// for such predicates, NDV based cardinality estimation is applicable
	GPOS_RESULT
	CJoinCardinalityNDVBasedEqPredTest::EresUnittest_NDVEqCardEstimation()
	{
		CDouble dRowsExpected(10000); // the minimum cardinality is min(NDV a, NDV b)

		Fixture f(file_name);
		IMemoryPool *mp = f.Pmp();
		IStatisticsArray *statistics_array = f.PdrgPstat();

		CExpression *pexprLgGet = CTestUtils::PexprLogicalGet(mp);
		CLogicalGet *popGet = CLogicalGet::PopConvert(pexprLgGet->Pop());
		CColRefArray *colref_array = popGet->PdrgpcrOutput();

		// use the colid available in the input xml file
		CColRef *pcrLeft = (*colref_array)[2];
		CColRef *pcrRight = (*colref_array)[0];

		// create a scalar ident
		// CScalarIdent "column_0000" (0)
		CExpression *pexprScalarIdentRight = CUtils::PexprScalarIdent(mp, pcrRight);

		// create a scalar op expression column_0002 + 10
		//  CScalarOp (+)
		//	|--CScalarIdent "column_0002" (2)
		//	+--CScalarConst (10)
		CExpression *pexprScConst = CUtils::PexprScalarConstInt4(mp, 10 /* val */);
		CExpression *pexprScOp = CUtils::PexprScalarOp(mp, pcrLeft, pexprScConst, CWStringConst(GPOS_WSZ_LIT("+")),
													   GPOS_NEW(mp) CMDIdGPDB(GPDB_INT4_ADD_OP));

		// create a scalar comparision operator
		//	+--CScalarCmp (=)
		//	|--CScalarOp (+)
		//	|  |--CScalarIdent "column_0002" (2)
		//	|  +--CScalarConst (10)
		//	+--CScalarIdent "column_0000" (0)
		CExpression *pScalarCmp = CUtils::PexprScalarEqCmp(mp, pexprScOp, pexprScalarIdentRight);

		IStatistics *join_stats = CJoinStatsProcessor::CalcAllJoinStats(mp, statistics_array, pScalarCmp,
																	   IStatistics::EsjtInnerJoin);

		GPOS_ASSERT(NULL != join_stats);
		CDouble dRowsActual(join_stats->Rows());
		GPOS_RESULT eres = GPOS_OK;

		if (std::floor(dRowsActual.Get()) != dRowsExpected)
		{
			eres = GPOS_FAILED;
		}

		join_stats->Release();
		pexprLgGet->Release();
		pScalarCmp->Release();

		return eres;
	}