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 228d19ac77d33b010793d594cc12209e7620dc66
Author: Ekta Khanna <[email protected]>
AuthorDate: Tue Apr 11 17:45:03 2023 -0700

    Update Array Coerce Cast Metadata object
    
    For certain queries, ORCA generates an Array Coerce Expr. To correctly
    generate this, in addition to the current information that is passed as
    part of ArrayCoerceCast MD object, we also require the element type.
    This commit updates that information and generates the equivalent
    ArrayCoerceExpr.
---
 .../gpopt/translate/CTranslatorRelcacheToDXL.cpp   |  4 ++-
 .../gporca/libgpopt/include/gpopt/base/CUtils.h    |  6 +++++
 .../gporca/libgpopt/src/base/CCastUtils.cpp        |  7 +++++-
 src/backend/gporca/libgpopt/src/base/CUtils.cpp    | 29 +++++++++++++++++++++-
 .../src/translate/CTranslatorDXLToExpr.cpp         | 17 ++++++++++---
 .../include/naucrates/dxl/xml/dxltokens.h          |  1 +
 .../include/naucrates/md/CMDArrayCoerceCastGPDB.h  |  8 +++++-
 .../libnaucrates/src/md/CMDArrayCoerceCastGPDB.cpp | 16 ++++++++++--
 .../src/parser/CParseHandlerMDArrayCoerceCast.cpp  |  7 +++++-
 .../gporca/libnaucrates/src/xml/dxltokens.cpp      |  1 +
 10 files changed, 86 insertions(+), 10 deletions(-)

diff --git a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp 
b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
index 44b95b3454..2a3d0f80b4 100644
--- a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
+++ b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
@@ -2106,11 +2106,13 @@ CTranslatorRelcacheToDXL::RetrieveCast(CMemoryPool *mp, 
IMDId *mdid)
        {
                case COERCION_PATH_ARRAYCOERCE:
                {
+                       IMDId *src_elem_mdid = GPOS_NEW(mp)
+                               CMDIdGPDB(IMDId::EmdidGeneral, 
gpdb::GetElementType(src_oid));
                        return GPOS_NEW(mp) CMDArrayCoerceCastGPDB(
                                mp, mdid, mdname, mdid_src, mdid_dest, 
is_binary_coercible,
                                GPOS_NEW(mp) CMDIdGPDB(IMDId::EmdidGeneral, 
cast_fn_oid),
                                IMDCast::EmdtArrayCoerce, 
default_type_modifier, false,
-                               EdxlcfImplicitCast, -1);
+                               EdxlcfImplicitCast, -1, src_elem_mdid);
                }
                break;
                case COERCION_PATH_FUNC:
diff --git a/src/backend/gporca/libgpopt/include/gpopt/base/CUtils.h 
b/src/backend/gporca/libgpopt/include/gpopt/base/CUtils.h
index 3735b31079..493d6e1895 100644
--- a/src/backend/gporca/libgpopt/include/gpopt/base/CUtils.h
+++ b/src/backend/gporca/libgpopt/include/gpopt/base/CUtils.h
@@ -878,6 +878,12 @@ public:
        static CExpression *PexprCast(CMemoryPool *mp, CMDAccessor *md_accessor,
                                                                  CExpression 
*pexpr, IMDId *mdid_dest);
 
+       // construct a func element expr for array coerce
+       static CExpression *PexprFuncElemExpr(CMemoryPool *mp,
+                                                                               
  CMDAccessor *md_accessor,
+                                                                               
  IMDId *mdid_func,
+                                                                               
  IMDId *mdid_elem_type, INT typmod);
+
        // construct a logical join expression of the given type, with the 
given children
        static CExpression *PexprLogicalJoin(CMemoryPool *mp,
                                                                                
 EdxlJoinType edxljointype,
diff --git a/src/backend/gporca/libgpopt/src/base/CCastUtils.cpp 
b/src/backend/gporca/libgpopt/src/base/CCastUtils.cpp
index d14ff5047e..6eb9b21fca 100644
--- a/src/backend/gporca/libgpopt/src/base/CCastUtils.cpp
+++ b/src/backend/gporca/libgpopt/src/base/CCastUtils.cpp
@@ -131,13 +131,18 @@ CCastUtils::PexprCast(CMemoryPool *mp, CMDAccessor 
*md_accessor,
        {
                CMDArrayCoerceCastGPDB *parrayCoerceCast =
                        (CMDArrayCoerceCastGPDB *) pmdcast;
+               IMDId *mdid_func = pmdcast->GetCastFuncMdId();
+
                pexpr = GPOS_NEW(mp) CExpression(
                        mp,
                        GPOS_NEW(mp) CScalarArrayCoerceExpr(
                                mp, mdid_dest, parrayCoerceCast->TypeModifier(),
                                (COperator::ECoercionForm) 
parrayCoerceCast->GetCoercionForm(),
                                parrayCoerceCast->Location()),
-                       CUtils::PexprScalarIdent(mp, colref));
+                       CUtils::PexprScalarIdent(mp, colref),
+                       CUtils::PexprFuncElemExpr(mp, md_accessor, mdid_func,
+                                                                         
parrayCoerceCast->GetSrcElemTypeMdId(),
+                                                                         
parrayCoerceCast->TypeModifier()));
        }
        else
        {
diff --git a/src/backend/gporca/libgpopt/src/base/CUtils.cpp 
b/src/backend/gporca/libgpopt/src/base/CUtils.cpp
index 804fe1cc63..1ccd05ea41 100644
--- a/src/backend/gporca/libgpopt/src/base/CUtils.cpp
+++ b/src/backend/gporca/libgpopt/src/base/CUtils.cpp
@@ -51,6 +51,7 @@
 #include "gpopt/operators/CPredicateUtils.h"
 #include "gpopt/operators/CScalarArray.h"
 #include "gpopt/operators/CScalarArrayCoerceExpr.h"
+#include "gpopt/operators/CScalarCaseTest.h"
 #include "gpopt/operators/CScalarCast.h"
 #include "gpopt/operators/CScalarCmp.h"
 #include "gpopt/operators/CScalarCoerceViaIO.h"
@@ -3792,13 +3793,18 @@ CUtils::PexprCast(CMemoryPool *mp, CMDAccessor 
*md_accessor, CExpression *pexpr,
        {
                CMDArrayCoerceCastGPDB *parrayCoerceCast =
                        (CMDArrayCoerceCastGPDB *) pmdcast;
+               IMDId *mdid_func = pmdcast->GetCastFuncMdId();
+
                pexprCast = GPOS_NEW(mp) CExpression(
                        mp,
                        GPOS_NEW(mp) CScalarArrayCoerceExpr(
                                mp, mdid_dest, parrayCoerceCast->TypeModifier(),
                                (COperator::ECoercionForm) 
parrayCoerceCast->GetCoercionForm(),
                                parrayCoerceCast->Location()),
-                       pexpr);
+                       pexpr,
+                       CUtils::PexprFuncElemExpr(mp, md_accessor, mdid_func,
+                                                                         
parrayCoerceCast->GetSrcElemTypeMdId(),
+                                                                         
parrayCoerceCast->TypeModifier()));
        }
        else if (pmdcast->GetMDPathType() == IMDCast::EmdtCoerceViaIO)
        {
@@ -3818,6 +3824,27 @@ CUtils::PexprCast(CMemoryPool *mp, CMDAccessor 
*md_accessor, CExpression *pexpr,
        return pexprCast;
 }
 
+// construct a func element expr for array coerce
+CExpression *
+CUtils::PexprFuncElemExpr(CMemoryPool *mp, CMDAccessor *md_accessor,
+                                                 IMDId *mdid_func, IMDId 
*mdid_elem_type, INT typmod)
+{
+       const IMDFunction *cast_func = md_accessor->RetrieveFunc(mdid_func);
+       const CWStringConst *pstrFunc = GPOS_NEW(mp)
+               CWStringConst(mp, 
(cast_func->Mdname().GetMDName())->GetBuffer());
+       mdid_func->AddRef();
+       cast_func->GetResultTypeMdid()->AddRef();
+       CScalarFunc *popCastScalarFunc =
+               GPOS_NEW(mp) CScalarFunc(mp, mdid_func, 
cast_func->GetResultTypeMdid(),
+                                                                typmod, 
pstrFunc, false /* funcvariadic */);
+       mdid_elem_type->AddRef();
+       CExpression *pexprCaseTest = GPOS_NEW(mp)
+               CExpression(mp, GPOS_NEW(mp) CScalarCaseTest(mp, 
mdid_elem_type));
+       CExpression *pexpr =
+               GPOS_NEW(mp) CExpression(mp, popCastScalarFunc, pexprCaseTest);
+       return pexpr;
+}
+
 // check whether a colref array contains repeated items
 BOOL
 CUtils::FHasDuplicates(const CColRefArray *colref_array)
diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorDXLToExpr.cpp 
b/src/backend/gporca/libgpopt/src/translate/CTranslatorDXLToExpr.cpp
index 28b6a5d6b1..a162b416e0 100644
--- a/src/backend/gporca/libgpopt/src/translate/CTranslatorDXLToExpr.cpp
+++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorDXLToExpr.cpp
@@ -797,14 +797,20 @@ CTranslatorDXLToExpr::PexprCastPrjElem(IMDId 
*pmdidSource, IMDId *mdid_dest,
        {
                CMDArrayCoerceCastGPDB *parrayCoerceCast =
                        (CMDArrayCoerceCastGPDB *) pmdcast;
+               IMDId *mdid_func = pmdcast->GetCastFuncMdId();
+               CExpression *pexprCastScalarFunc = CUtils::PexprFuncElemExpr(
+                       m_mp, m_pmda, mdid_func, 
parrayCoerceCast->GetSrcElemTypeMdId(),
+                       parrayCoerceCast->TypeModifier());
+
                pexprCast = GPOS_NEW(m_mp) CExpression(
                        m_mp,
                        GPOS_NEW(m_mp) CScalarArrayCoerceExpr(
                                m_mp, mdid_dest, 
parrayCoerceCast->TypeModifier(),
                                (COperator::ECoercionForm) 
parrayCoerceCast->GetCoercionForm(),
                                parrayCoerceCast->Location()),
-                       GPOS_NEW(m_mp) CExpression(
-                               m_mp, GPOS_NEW(m_mp) CScalarIdent(m_mp, 
pcrToCast)));
+                       GPOS_NEW(m_mp)
+                               CExpression(m_mp, GPOS_NEW(m_mp) 
CScalarIdent(m_mp, pcrToCast)),
+                       pexprCastScalarFunc);
        }
        else
        {
@@ -3673,13 +3679,18 @@ CTranslatorDXLToExpr::PexprScalarCast(const CDXLNode 
*pdxlnCast)
        {
                CMDArrayCoerceCastGPDB *parrayCoerceCast =
                        (CMDArrayCoerceCastGPDB *) pmdcast;
+               IMDId *mdid_func = pmdcast->GetCastFuncMdId();
+               CExpression *pexprCastScalarFunc = CUtils::PexprFuncElemExpr(
+                       m_mp, m_pmda, mdid_func, 
parrayCoerceCast->GetSrcElemTypeMdId(),
+                       parrayCoerceCast->TypeModifier());
+
                pexpr = GPOS_NEW(m_mp) CExpression(
                        m_mp,
                        GPOS_NEW(m_mp) CScalarArrayCoerceExpr(
                                m_mp, mdid_type, 
parrayCoerceCast->TypeModifier(),
                                (COperator::ECoercionForm) 
parrayCoerceCast->GetCoercionForm(),
                                parrayCoerceCast->Location()),
-                       pexprChild);
+                       pexprChild, pexprCastScalarFunc);
        }
        else
        {
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h
index 2ccc675dc1..059d9ee7cc 100644
--- a/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h
+++ b/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h
@@ -619,6 +619,7 @@ enum Edxltoken
        EdxltokenGPDBCastSrcType,
        EdxltokenGPDBCastDestType,
        EdxltokenGPDBCastFuncId,
+       EdxltokenGPDBCastSrcElemType,
        EdxltokenGPDBCastCoercePathType,
        EdxltokenGPDBArrayCoerceCast,
 
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/md/CMDArrayCoerceCastGPDB.h 
b/src/backend/gporca/libnaucrates/include/naucrates/md/CMDArrayCoerceCastGPDB.h
index 1929e328e1..1d53a9698f 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/md/CMDArrayCoerceCastGPDB.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/md/CMDArrayCoerceCastGPDB.h
@@ -41,6 +41,9 @@ private:
        // location
        INT m_location;
 
+       // Src element MDId
+       IMDId *m_mdid_src_elemtype;
+
 public:
        CMDArrayCoerceCastGPDB(const CMDArrayCoerceCastGPDB &) = delete;
 
@@ -50,7 +53,7 @@ public:
                                                   BOOL is_binary_coercible, 
IMDId *mdid_cast_func,
                                                   EmdCoercepathType path_type, 
INT type_modifier,
                                                   BOOL is_explicit, 
EdxlCoercionForm dxl_coerce_format,
-                                                  INT location);
+                                                  INT location, IMDId 
*mdid_src_elemtype);
 
        // dtor
        ~CMDArrayCoerceCastGPDB() override;
@@ -73,6 +76,9 @@ public:
        // return token location
        virtual INT Location() const;
 
+       // return src element type
+       virtual IMDId *GetSrcElemTypeMdId() const;
+
        // serialize object in DXL format
        void Serialize(gpdxl::CXMLSerializer *xml_serializer) const override;
 
diff --git a/src/backend/gporca/libnaucrates/src/md/CMDArrayCoerceCastGPDB.cpp 
b/src/backend/gporca/libnaucrates/src/md/CMDArrayCoerceCastGPDB.cpp
index ec1fc4a1f9..8a71112d4f 100644
--- a/src/backend/gporca/libnaucrates/src/md/CMDArrayCoerceCastGPDB.cpp
+++ b/src/backend/gporca/libnaucrates/src/md/CMDArrayCoerceCastGPDB.cpp
@@ -26,13 +26,14 @@ CMDArrayCoerceCastGPDB::CMDArrayCoerceCastGPDB(
        CMemoryPool *mp, IMDId *mdid, CMDName *mdname, IMDId *mdid_src,
        IMDId *mdid_dest, BOOL is_binary_coercible, IMDId *mdid_cast_func,
        EmdCoercepathType path_type, INT type_modifier, BOOL is_explicit,
-       EdxlCoercionForm dxl_coerce_format, INT location)
+       EdxlCoercionForm dxl_coerce_format, INT location, IMDId 
*mdid_src_elemtype)
        : CMDCastGPDB(mp, mdid, mdname, mdid_src, mdid_dest, 
is_binary_coercible,
                                  mdid_cast_func, path_type),
          m_type_modifier(type_modifier),
          m_is_explicit(is_explicit),
          m_dxl_coerce_format(dxl_coerce_format),
-         m_location(location)
+         m_location(location),
+         m_mdid_src_elemtype(mdid_src_elemtype)
 {
        m_dxl_str = CDXLUtils::SerializeMDObj(mp, this, false 
/*fSerializeHeader*/,
                                                                                
  false /*indentation*/);
@@ -42,6 +43,7 @@ CMDArrayCoerceCastGPDB::CMDArrayCoerceCastGPDB(
 CMDArrayCoerceCastGPDB::~CMDArrayCoerceCastGPDB()
 {
        GPOS_DELETE(m_dxl_str);
+       m_mdid_src_elemtype->Release();
 }
 
 // return type modifier
@@ -72,6 +74,13 @@ CMDArrayCoerceCastGPDB::Location() const
        return m_location;
 }
 
+// return src basetype mdid
+IMDId *
+CMDArrayCoerceCastGPDB::GetSrcElemTypeMdId() const
+{
+       return m_mdid_src_elemtype;
+}
+
 // serialize function metadata in DXL format
 void
 CMDArrayCoerceCastGPDB::Serialize(CXMLSerializer *xml_serializer) const
@@ -99,6 +108,9 @@ CMDArrayCoerceCastGPDB::Serialize(CXMLSerializer 
*xml_serializer) const
                xml_serializer, 
CDXLTokens::GetDXLTokenStr(EdxltokenGPDBCastDestType));
        m_mdid_cast_func->Serialize(
                xml_serializer, 
CDXLTokens::GetDXLTokenStr(EdxltokenGPDBCastFuncId));
+       m_mdid_src_elemtype->Serialize(
+               xml_serializer,
+               CDXLTokens::GetDXLTokenStr(EdxltokenGPDBCastSrcElemType));
 
        if (default_type_modifier != TypeModifier())
        {
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerMDArrayCoerceCast.cpp 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerMDArrayCoerceCast.cpp
index 81dae2d887..be950c6001 100644
--- 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerMDArrayCoerceCast.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerMDArrayCoerceCast.cpp
@@ -101,10 +101,15 @@ CParseHandlerMDArrayCoerceCast::StartElement(
                m_parse_handler_mgr->GetDXLMemoryManager(), attrs, 
EdxltokenLocation,
                EdxltokenGPDBArrayCoerceCast);
 
+       IMDId *mdid_src_elemtype =
+               CDXLOperatorFactory::ExtractConvertAttrValueToMdId(
+                       m_parse_handler_mgr->GetDXLMemoryManager(), attrs,
+                       EdxltokenGPDBCastSrcElemType, 
EdxltokenGPDBArrayCoerceCast);
+
        m_imd_obj = GPOS_NEW(m_mp) CMDArrayCoerceCastGPDB(
                m_mp, mdid, mdname, mdid_src, mdid_dest, is_binary_coercible,
                mdid_cast_func, coerce_path_type, type_modifier, is_explicit,
-               dxl_coercion_form, location);
+               dxl_coercion_form, location, mdid_src_elemtype);
 }
 
 // invoked by Xerces to process a closing tag
diff --git a/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp 
b/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp
index 908821eb26..6d11f3f026 100644
--- a/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp
+++ b/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp
@@ -689,6 +689,7 @@ CDXLTokens::Init(CMemoryPool *mp)
                {EdxltokenGPDBCastSrcType, GPOS_WSZ_LIT("SourceTypeId")},
                {EdxltokenGPDBCastDestType, GPOS_WSZ_LIT("DestinationTypeId")},
                {EdxltokenGPDBCastFuncId, GPOS_WSZ_LIT("CastFuncId")},
+               {EdxltokenGPDBCastSrcElemType, 
GPOS_WSZ_LIT("SourceElemTypeId")},
                {EdxltokenGPDBCastCoercePathType, 
GPOS_WSZ_LIT("CoercePathType")},
                {EdxltokenGPDBArrayCoerceCast, GPOS_WSZ_LIT("ArrayCoerceCast")},
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to