// 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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }