diff --git a/data/dxl/minidump/ArrayCoerceExpr.mdp b/data/dxl/minidump/ArrayCoerceExpr.mdp
new file mode 100644
index 0000000000000000000000000000000000000000..024fa0b21b8edca7cd5a5c014718ce1d3fde2821
--- /dev/null
+++ b/data/dxl/minidump/ArrayCoerceExpr.mdp
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libgpopt/CMakeLists.txt b/libgpopt/CMakeLists.txt
index 37721d95e86e9f6c2780588bbb93c72d67411919..cbfe8d5b7368590daa200cc1e27511be5a222b9e 100644
--- a/libgpopt/CMakeLists.txt
+++ b/libgpopt/CMakeLists.txt
@@ -547,6 +547,8 @@ add_library(gpopt
src/operators/CScalarCoerceToDomain.cpp
include/gpopt/operators/CScalarCoerceViaIO.h
src/operators/CScalarCoerceViaIO.cpp
+ include/gpopt/operators/CScalarArrayCoerceExpr.h
+ src/operators/CScalarArrayCoerceExpr.cpp
include/gpopt/operators/CScalarConst.h
src/operators/CScalarConst.cpp
include/gpopt/operators/CScalarDMLAction.h
diff --git a/libgpopt/include/gpopt/operators/COperator.h b/libgpopt/include/gpopt/operators/COperator.h
index f247fd899357393cd78038f455746ab18cf776ba..90bc55642f598a40adc991a37d382d069be75e40 100644
--- a/libgpopt/include/gpopt/operators/COperator.h
+++ b/libgpopt/include/gpopt/operators/COperator.h
@@ -185,6 +185,7 @@ namespace gpopt
EopScalarCast,
EopScalarCoerceToDomain,
EopScalarCoerceViaIO,
+ EopScalarArrayCoerceExpr,
EopScalarCoalesce,
EopScalarArray,
EopScalarArrayCmp,
diff --git a/libgpopt/include/gpopt/operators/CScalarArrayCoerceExpr.h b/libgpopt/include/gpopt/operators/CScalarArrayCoerceExpr.h
new file mode 100644
index 0000000000000000000000000000000000000000..370d1f5945b69040949e30f75a1d86ca64a6b986
--- /dev/null
+++ b/libgpopt/include/gpopt/operators/CScalarArrayCoerceExpr.h
@@ -0,0 +1,179 @@
+//---------------------------------------------------------------------------
+// Greenplum Database
+// Copyright (C) 2017 Pivotal Inc.
+//
+// @filename:
+// CScalarArrayCoerceExpr.h
+//
+// @doc:
+// Scalar Array Coerce Expr operator,
+// the operator will apply type casting for each element in this array
+// using the given element coercion function.
+//
+// @owner:
+//
+// @test:
+//
+//
+//---------------------------------------------------------------------------
+#ifndef GPOPT_CScalarArrayCoerceExpr_H
+#define GPOPT_CScalarArrayCoerceExpr_H
+
+#include "gpos/base.h"
+#include "gpopt/base/COptCtxt.h"
+#include "gpopt/operators/CScalar.h"
+#include "gpopt/base/CDrvdProp.h"
+
+namespace gpopt
+{
+ using namespace gpos;
+
+ //---------------------------------------------------------------------------
+ // @class:
+ // CScalarArrayCoerceExpr
+ //
+ // @doc:
+ // Scalar Array Coerce Expr operator
+ //
+ //---------------------------------------------------------------------------
+ class CScalarArrayCoerceExpr : public CScalar
+ {
+
+ private:
+
+ // catalog MDId of the element function
+ IMDId *m_pmdidElementFunc;
+
+ // catalog MDId of the result type
+ IMDId *m_pmdidResultType;
+
+ // output type modifications
+ INT m_iMod;
+
+ // conversion semantics flag to pass to func
+ BOOL m_fIsExplicit;
+
+ // coercion form
+ ECoercionForm m_ecf;
+
+ // location of token to be coerced
+ INT m_iLoc;
+
+ // private copy ctor
+ CScalarArrayCoerceExpr(const CScalarArrayCoerceExpr &);
+
+ public:
+
+ // ctor
+ CScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ IMDId *pmdidElementFunc,
+ IMDId *pmdidResultType,
+ INT iMod,
+ BOOL fIsExplicit,
+ ECoercionForm edxlcf,
+ INT iLoc
+ );
+
+ // dtor
+ virtual
+ ~CScalarArrayCoerceExpr()
+ {
+ m_pmdidElementFunc->Release();
+ m_pmdidResultType->Release();
+ }
+
+ // return metadata id of element coerce function
+ IMDId *PmdidElementFunc() const
+ {
+ return m_pmdidElementFunc;
+ }
+
+ // the type of the scalar expression
+ virtual
+ IMDId *PmdidType() const
+ {
+ return m_pmdidResultType;
+ }
+
+ // return type modification
+ INT IMod() const
+ {
+ return m_iMod;
+ }
+
+ BOOL FIsExplicit() const
+ {
+ return m_fIsExplicit;
+ }
+
+ // return coercion form
+ ECoercionForm Ecf() const
+ {
+ return m_ecf;
+ }
+
+ // return token location
+ INT ILoc() const
+ {
+ return m_iLoc;
+ }
+
+ virtual
+ EOperatorId Eopid() const
+ {
+ return EopScalarArrayCoerceExpr;
+ }
+
+ // return a string for operator name
+ virtual
+ const CHAR *SzId() const
+ {
+ return "CScalarArrayCoerceExpr";
+ }
+
+ // match function
+ virtual
+ BOOL FMatch(COperator *) const;
+
+ // sensitivity to order of inputs
+ virtual
+ BOOL FInputOrderSensitive() const
+ {
+ return false;
+ }
+
+ // return a copy of the operator with remapped columns
+ virtual
+ COperator *PopCopyWithRemappedColumns
+ (
+ IMemoryPool *, //pmp,
+ HMUlCr *, //phmulcr,
+ BOOL //fMustExist
+ )
+ {
+ return PopCopyDefault();
+ }
+
+ // conversion function
+ static
+ CScalarArrayCoerceExpr *PopConvert
+ (
+ COperator *pop
+ )
+ {
+ GPOS_ASSERT(NULL != pop);
+ GPOS_ASSERT(EopScalarArrayCoerceExpr == pop->Eopid());
+
+ return dynamic_cast(pop);
+ }
+
+ }; // class CScalarArrayCoerceExpr
+
+}
+
+
+#endif // !GPOPT_CScalarArrayCoerceExpr_H
+
+// EOF
diff --git a/libgpopt/include/gpopt/operators/ops.h b/libgpopt/include/gpopt/operators/ops.h
index e29b14020630c152aecbe15c6155b2507e5d44aa..605fdb40843ab15e1cc8eb66ad7eeda21816fd95 100644
--- a/libgpopt/include/gpopt/operators/ops.h
+++ b/libgpopt/include/gpopt/operators/ops.h
@@ -37,6 +37,7 @@
#include "gpopt/operators/CScalarCast.h"
#include "gpopt/operators/CScalarCoerceToDomain.h"
#include "gpopt/operators/CScalarCoerceViaIO.h"
+#include "gpopt/operators/CScalarArrayCoerceExpr.h"
#include "gpopt/operators/CScalarCoalesce.h"
#include "gpopt/operators/CScalarMinMax.h"
#include "gpopt/operators/CScalarSubquery.h"
diff --git a/libgpopt/include/gpopt/translate/CTranslatorDXLToExpr.h b/libgpopt/include/gpopt/translate/CTranslatorDXLToExpr.h
index f527c3f4602dbe9d7188810e29eaad9670eb4dd3..434f59b549492ee601193fc9352b8e1d242a950c 100644
--- a/libgpopt/include/gpopt/translate/CTranslatorDXLToExpr.h
+++ b/libgpopt/include/gpopt/translate/CTranslatorDXLToExpr.h
@@ -332,6 +332,9 @@ namespace gpopt
// translate a DXL scalar coerce a scalar coerce using I/O functions
CExpression *PexprScalarCoerceViaIO(const CDXLNode *pdxlnCoerce);
+ // translate a DXL scalar array coerce expression using given element coerce function
+ CExpression *PexprScalarArrayCoerceExpr(const CDXLNode *pdxlnArrayCoerceExpr);
+
// translate a DXL scalar subquery operator into a scalar subquery expression
CExpression *PexprScalarSubquery(const CDXLNode *pdxlnSubquery);
diff --git a/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h b/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h
index 025a47f6d6f8df2e8854c10f25450b072e674d9b..2293c3ec97b1f9d6f23270b2a3271f7cab8be32c 100644
--- a/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h
+++ b/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h
@@ -597,6 +597,9 @@ namespace gpopt
// translate a scalar coerce using I/O functions
CDXLNode *PdxlnScCoerceViaIO(CExpression *pexprScCoerce);
+ // translate a scalar array coerce expr with element coerce function
+ CDXLNode *PdxlnScArrayCoerceExpr(CExpression *pexprScArrayCoerceExpr);
+
// translate an array
CDXLNode *PdxlnArray(CExpression *pexpr);
diff --git a/libgpopt/src/operators/CScalarArrayCoerceExpr.cpp b/libgpopt/src/operators/CScalarArrayCoerceExpr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b4dca03ab76113d0813cc525b3f18a148217cac6
--- /dev/null
+++ b/libgpopt/src/operators/CScalarArrayCoerceExpr.cpp
@@ -0,0 +1,99 @@
+//---------------------------------------------------------------------------
+// Greenplum Database
+// Copyright (C) 2017 Pivotal Inc.
+//
+// @filename:
+// CScalarArrayCoerceExpr.cpp
+//
+// @doc:
+// Implementation of scalar array coerce expr operator
+//
+// @owner:
+//
+// @test:
+//
+//
+//---------------------------------------------------------------------------
+
+#include "gpos/base.h"
+
+#include "gpopt/base/CDrvdPropScalar.h"
+#include "gpopt/base/CColRefSet.h"
+
+#include "gpopt/mdcache/CMDAccessorUtils.h"
+
+#include "gpopt/operators/CScalarArrayCoerceExpr.h"
+#include "gpopt/operators/CExpressionHandle.h"
+
+#include "naucrates/md/IMDTypeBool.h"
+
+using namespace gpopt;
+using namespace gpmd;
+
+
+//---------------------------------------------------------------------------
+// @function:
+// CScalarArrayCoerceExpr::CScalarArrayCoerceExpr
+//
+// @doc:
+// Ctor
+//
+//---------------------------------------------------------------------------
+CScalarArrayCoerceExpr::CScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ IMDId *pmdidElementFunc,
+ IMDId *pmdidResultType,
+ INT iMod,
+ BOOL fIsExplicit,
+ ECoercionForm ecf,
+ INT iLoc
+ )
+ :
+ CScalar(pmp),
+ m_pmdidElementFunc(pmdidElementFunc),
+ m_pmdidResultType(pmdidResultType),
+ m_iMod(iMod),
+ m_fIsExplicit(fIsExplicit),
+ m_ecf(ecf),
+ m_iLoc(iLoc)
+{
+ GPOS_ASSERT(NULL != pmdidElementFunc);
+
+ GPOS_ASSERT(NULL != pmdidResultType);
+ GPOS_ASSERT(pmdidResultType->FValid());
+}
+
+
+//---------------------------------------------------------------------------
+// @function:
+// CScalarArrayCoerceExpr::FMatch
+//
+// @doc:
+// Match function on operator level
+//
+//---------------------------------------------------------------------------
+BOOL
+CScalarArrayCoerceExpr::FMatch
+ (
+ COperator *pop
+ )
+ const
+{
+ if (pop->Eopid() != Eopid())
+ {
+ return false;
+ }
+
+ CScalarArrayCoerceExpr *popCoerce = CScalarArrayCoerceExpr::PopConvert(pop);
+
+ return popCoerce->PmdidElementFunc()->FEquals(m_pmdidElementFunc) &&
+ popCoerce->PmdidType()->FEquals(m_pmdidResultType) &&
+ popCoerce->IMod() == m_iMod &&
+ popCoerce->FIsExplicit() == m_fIsExplicit &&
+ popCoerce->Ecf() == m_ecf &&
+ popCoerce->ILoc() == m_iLoc;
+}
+
+// EOF
+
diff --git a/libgpopt/src/translate/CTranslatorDXLToExpr.cpp b/libgpopt/src/translate/CTranslatorDXLToExpr.cpp
index e0abff4ca441de84d3a8a817e000398af4d81f6f..956dfb69232b089d741bb90d96da55d2ad7fa4b2 100644
--- a/libgpopt/src/translate/CTranslatorDXLToExpr.cpp
+++ b/libgpopt/src/translate/CTranslatorDXLToExpr.cpp
@@ -172,6 +172,7 @@ CTranslatorDXLToExpr::InitTranslators()
{EdxlopScalarSwitchCase, &gpopt::CTranslatorDXLToExpr::PexprScalarSwitchCase},
{EdxlopScalarCaseTest, &gpopt::CTranslatorDXLToExpr::PexprScalarCaseTest},
{EdxlopScalarCoalesce, &gpopt::CTranslatorDXLToExpr::PexprScalarCoalesce},
+ {EdxlopScalarArrayCoerceExpr, &gpopt::CTranslatorDXLToExpr::PexprScalarArrayCoerceExpr},
{EdxlopScalarCast, &gpopt::CTranslatorDXLToExpr::PexprScalarCast},
{EdxlopScalarCoerceToDomain,&gpopt::CTranslatorDXLToExpr::PexprScalarCoerceToDomain},
{EdxlopScalarCoerceViaIO, &gpopt::CTranslatorDXLToExpr::PexprScalarCoerceViaIO},
@@ -3665,6 +3666,52 @@ CTranslatorDXLToExpr::PexprScalarCoerceViaIO
);
}
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToExpr::PexprScalarArrayCoerceExpr
+//
+// @doc:
+// Create a scalar array coerce expr from a DXL scalar array coerce expr
+//
+//---------------------------------------------------------------------------
+CExpression *
+CTranslatorDXLToExpr::PexprScalarArrayCoerceExpr
+ (
+ const CDXLNode *pdxlnArrayCoerceExpr
+ )
+{
+ GPOS_ASSERT(NULL != pdxlnArrayCoerceExpr);
+
+ CDXLScalarArrayCoerceExpr *pdxlop = CDXLScalarArrayCoerceExpr::PdxlopConvert(pdxlnArrayCoerceExpr->Pdxlop());
+
+ GPOS_ASSERT(1 == pdxlnArrayCoerceExpr->UlArity());
+ CDXLNode *pdxlnChild = (*pdxlnArrayCoerceExpr)[0];
+ CExpression *pexprChild = Pexpr(pdxlnChild);
+
+ IMDId *pmdidElementFunc = pdxlop->PmdidElementFunc();
+ pmdidElementFunc->AddRef();
+
+ IMDId *pmdidResultType = pdxlop->PmdidResultType();
+ pmdidResultType->AddRef();
+
+ EdxlCoercionForm edxlcf = pdxlop->Edxlcf();
+
+ return GPOS_NEW(m_pmp) CExpression
+ (
+ m_pmp,
+ GPOS_NEW(m_pmp) CScalarArrayCoerceExpr
+ (
+ m_pmp,
+ pmdidElementFunc,
+ pmdidResultType,
+ pdxlop->IMod(),
+ pdxlop->FIsExplicit(),
+ (COperator::ECoercionForm) edxlcf, // map Coercion Form directly based on position in enum
+ pdxlop->ILoc()
+ ),
+ pexprChild
+ );
+}
//---------------------------------------------------------------------------
// @function:
diff --git a/libgpopt/src/translate/CTranslatorExprToDXL.cpp b/libgpopt/src/translate/CTranslatorExprToDXL.cpp
index c941f345d468169ddc8230f7b13ba500c73c13bc..301ba245140b398ee363c7b6c228acf5d8163854 100644
--- a/libgpopt/src/translate/CTranslatorExprToDXL.cpp
+++ b/libgpopt/src/translate/CTranslatorExprToDXL.cpp
@@ -155,6 +155,7 @@ CTranslatorExprToDXL::InitScalarTranslators()
{COperator::EopScalarCast, &gpopt::CTranslatorExprToDXL::PdxlnScCast},
{COperator::EopScalarCoerceToDomain, &gpopt::CTranslatorExprToDXL::PdxlnScCoerceToDomain},
{COperator::EopScalarCoerceViaIO, &gpopt::CTranslatorExprToDXL::PdxlnScCoerceViaIO},
+ {COperator::EopScalarArrayCoerceExpr, &gpopt::CTranslatorExprToDXL::PdxlnScArrayCoerceExpr},
{COperator::EopScalarArray, &gpopt::CTranslatorExprToDXL::PdxlnArray},
{COperator::EopScalarArrayCmp, &gpopt::CTranslatorExprToDXL::PdxlnArrayCmp},
{COperator::EopScalarArrayRef, &gpopt::CTranslatorExprToDXL::PdxlnArrayRef},
@@ -6430,6 +6431,52 @@ CTranslatorExprToDXL::PdxlnScCoerceViaIO
return pdxlnCoerce;
}
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorExprToDXL::PdxlnScArrayCoerceExpr
+//
+// @doc:
+// Create a DXL node from an optimizer scalar array coerce expr.
+//
+//---------------------------------------------------------------------------
+CDXLNode *
+CTranslatorExprToDXL::PdxlnScArrayCoerceExpr
+ (
+ CExpression *pexprArrayCoerceExpr
+ )
+{
+ GPOS_ASSERT(NULL != pexprArrayCoerceExpr);
+ CScalarArrayCoerceExpr *popScArrayCoerceExpr = CScalarArrayCoerceExpr::PopConvert(pexprArrayCoerceExpr->Pop());
+
+ IMDId *pmdidElemFunc = popScArrayCoerceExpr->PmdidElementFunc();
+ pmdidElemFunc->AddRef();
+ IMDId *pmdid = popScArrayCoerceExpr->PmdidType();
+ pmdid->AddRef();
+
+ CDXLNode *pdxlnArrayCoerceExpr =
+ GPOS_NEW(m_pmp) CDXLNode
+ (
+ m_pmp,
+ GPOS_NEW(m_pmp) CDXLScalarArrayCoerceExpr
+ (
+ m_pmp,
+ pmdidElemFunc,
+ pmdid,
+ popScArrayCoerceExpr->IMod(),
+ popScArrayCoerceExpr->FIsExplicit(),
+ (EdxlCoercionForm) popScArrayCoerceExpr->Ecf(), // map Coercion Form directly based on position in enum
+ popScArrayCoerceExpr->ILoc()
+ )
+ );
+
+ // translate child
+ GPOS_ASSERT(1 == pexprArrayCoerceExpr->UlArity());
+ CExpression *pexprChild = (*pexprArrayCoerceExpr)[0];
+ CDXLNode *pdxlnChild = PdxlnScalar(pexprChild);
+ pdxlnArrayCoerceExpr->AddChild(pdxlnChild);
+
+ return pdxlnArrayCoerceExpr;
+}
//---------------------------------------------------------------------------
// @function:
diff --git a/libgpopt/src/xforms/CSubqueryHandler.cpp b/libgpopt/src/xforms/CSubqueryHandler.cpp
index 755c1e1540bce4643dd4f4d07d82119a60406104..ed0817c877a8a86cdf261305ab24024e22247733 100644
--- a/libgpopt/src/xforms/CSubqueryHandler.cpp
+++ b/libgpopt/src/xforms/CSubqueryHandler.cpp
@@ -57,6 +57,7 @@ const CSubqueryHandler::SOperatorHandler CSubqueryHandler::m_rgophdlr[] =
{COperator::EopScalarCast, FRecursiveHandler},
{COperator::EopScalarCoerceToDomain, FRecursiveHandler},
{COperator::EopScalarCoerceViaIO, FRecursiveHandler},
+ {COperator::EopScalarArrayCoerceExpr, FRecursiveHandler},
{COperator::EopScalarAggFunc, FRecursiveHandler},
{COperator::EopScalarWindowFunc, FRecursiveHandler},
{COperator::EopScalarArray, FRecursiveHandler},
diff --git a/libnaucrates/CMakeLists.txt b/libnaucrates/CMakeLists.txt
index 05e78b96963ecdbc5d6173d0adc9733d22b6d5df..ea56c0d7a8a57e581acfcfa760e68946327660b4 100644
--- a/libnaucrates/CMakeLists.txt
+++ b/libnaucrates/CMakeLists.txt
@@ -345,6 +345,8 @@ add_library(naucrates
src/operators/CDXLScalarCoerceToDomain.cpp
include/naucrates/dxl/operators/CDXLScalarCoerceViaIO.h
src/operators/CDXLScalarCoerceViaIO.cpp
+ include/naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h
+ src/operators/CDXLScalarArrayCoerceExpr.cpp
include/naucrates/dxl/operators/CDXLScalarComp.h
src/operators/CDXLScalarComp.cpp
include/naucrates/dxl/operators/CDXLScalarConstValue.h
@@ -683,6 +685,8 @@ add_library(naucrates
src/parser/CParseHandlerScalarCoerceToDomain.cpp
include/naucrates/dxl/parser/CParseHandlerScalarCoerceViaIO.h
src/parser/CParseHandlerScalarCoerceViaIO.cpp
+ include/naucrates/dxl/parser/CParseHandlerScalarArrayCoerceExpr.h
+ src/parser/CParseHandlerScalarArrayCoerceExpr.cpp
include/naucrates/dxl/parser/CParseHandlerScalarComp.h
src/parser/CParseHandlerScalarComp.cpp
include/naucrates/dxl/parser/CParseHandlerScalarConstValue.h
diff --git a/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h b/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h
index 417733171d8a6cc04fa215b491ed874c32a49c25..52b765370bd47d517a4f68457cd539b1a160998c 100644
--- a/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h
+++ b/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h
@@ -99,6 +99,7 @@ namespace gpdxl
EdxlopScalarCast,
EdxlopScalarCoerceToDomain,
EdxlopScalarCoerceViaIO,
+ EdxlopScalarArrayCoerceExpr,
EdxlopScalarAggref,
EdxlopScalarArrayComp,
EdxlopScalarBooleanTest,
diff --git a/libnaucrates/include/naucrates/dxl/operators/CDXLOperatorFactory.h b/libnaucrates/include/naucrates/dxl/operators/CDXLOperatorFactory.h
index 637ef7707d4cad1390b490496f3c752e9479276a..ae77b9e04870b05c46c38963d9dccf09de0e86a7 100644
--- a/libnaucrates/include/naucrates/dxl/operators/CDXLOperatorFactory.h
+++ b/libnaucrates/include/naucrates/dxl/operators/CDXLOperatorFactory.h
@@ -322,6 +322,10 @@ namespace gpdxl
static
CDXLScalar *PdxlopCoerceViaIO(CDXLMemoryManager *pmm, const Attributes &attrs);
+ // create a ArrayCoerceExpr
+ static
+ CDXLScalar *PdxlopArrayCoerceExpr(CDXLMemoryManager *pmm, const Attributes &attrs);
+
// create a scalar identifier operator
static
CDXLScalar *PdxlopScalarIdent(CDXLMemoryManager *pmm, const Attributes &attrs);
diff --git a/libnaucrates/include/naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h b/libnaucrates/include/naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5924585367156a4a6731ba7e3d1425089704b97
--- /dev/null
+++ b/libnaucrates/include/naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h
@@ -0,0 +1,154 @@
+//---------------------------------------------------------------------------
+// Greenplum Database
+// Copyright (C) 2017 Pivotal Inc.
+//
+// @filename:
+// CDXLScalarArrayCoerceExpr.h
+//
+// @doc:
+// Class for representing DXL ArrayCoerceExpr operation,
+// the operator will apply type casting for each element in this array
+// using the given element coercion function.
+// @owner:
+//
+// @test:
+//
+//---------------------------------------------------------------------------
+
+#ifndef GPDXL_CDXLScalarArrayCoerceExpr_H
+#define GPDXL_CDXLScalarArrayCoerceExpr_H
+
+#include "gpos/base.h"
+#include "naucrates/dxl/operators/CDXLScalar.h"
+#include "naucrates/md/IMDId.h"
+
+namespace gpdxl
+{
+ using namespace gpos;
+ using namespace gpmd;
+
+ //---------------------------------------------------------------------------
+ // @class:
+ // CDXLScalarArrayCoerceExpr
+ //
+ // @doc:
+ // Class for representing DXL array coerce operator
+ //---------------------------------------------------------------------------
+ class CDXLScalarArrayCoerceExpr : public CDXLScalar
+ {
+ private:
+ // catalog MDId of element coerce function
+ IMDId *m_pmdidElementFunc;
+
+ // catalog MDId of the result type
+ IMDId *m_pmdidResultType;
+
+ // output type modifications
+ INT m_iMod;
+
+ // conversion semantics flag to pass to func
+ BOOL m_fIsExplicit;
+
+ // coercion form
+ EdxlCoercionForm m_edxlcf;
+
+ // location of token to be coerced
+ INT m_iLoc;
+
+ // private copy ctor
+ CDXLScalarArrayCoerceExpr(const CDXLScalarArrayCoerceExpr&);
+
+ public:
+ CDXLScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ IMDId *pmdidElementFunc,
+ IMDId *pmdidResultType,
+ INT iMod,
+ BOOL fIsExplicit,
+ EdxlCoercionForm edxlcf,
+ INT iLoc
+ );
+
+ ~CDXLScalarArrayCoerceExpr();
+
+ // ident accessor
+ virtual
+ Edxlopid Edxlop() const
+ {
+ return EdxlopScalarArrayCoerceExpr;
+ }
+
+
+ // return metadata id of element coerce function
+ IMDId *PmdidElementFunc() const
+ {
+ return m_pmdidElementFunc;
+ }
+
+ // return result type
+ IMDId *PmdidResultType() const
+ {
+ return m_pmdidResultType;
+ }
+
+ // return type modification
+ INT IMod() const
+ {
+ return m_iMod;
+ }
+
+ BOOL FIsExplicit() const
+ {
+ return m_fIsExplicit;
+ }
+
+ // return coercion form
+ EdxlCoercionForm Edxlcf() const
+ {
+ return m_edxlcf;
+ }
+
+ // return token location
+ INT ILoc() const
+ {
+ return m_iLoc;
+ }
+
+ // does the operator return a boolean result
+ virtual
+ BOOL FBoolean(CMDAccessor *pmda) const;
+
+ // name of the DXL operator name
+ virtual
+ const CWStringConst *PstrOpName() const;
+
+ // serialize operator in DXL format
+ virtual
+ void SerializeToDXL(CXMLSerializer *pxmlser, const CDXLNode *pdxln) const;
+
+ // conversion function
+ static
+ CDXLScalarArrayCoerceExpr *PdxlopConvert
+ (
+ CDXLOperator *pdxlop
+ )
+ {
+ GPOS_ASSERT(NULL != pdxlop);
+ GPOS_ASSERT(EdxlopScalarArrayCoerceExpr == pdxlop->Edxlop());
+
+ return dynamic_cast(pdxlop);
+ }
+
+#ifdef GPOS_DEBUG
+ // checks whether the operator has valid structure, i.e. number and
+ // types of child nodes
+ virtual
+ void AssertValid(const CDXLNode *pdxln, BOOL fValidateChildren) const;
+#endif // GPOS_DEBUG
+ };
+}
+
+#endif // !GPDXL_CDXLScalarArrayCoerceExpr_H
+
+// EOF
diff --git a/libnaucrates/include/naucrates/dxl/operators/dxlops.h b/libnaucrates/include/naucrates/dxl/operators/dxlops.h
index da2dd4091675030b95e331f4525932c179c17f02..77f35951832df632dfa52deeff76d970e1a7a0e6 100644
--- a/libnaucrates/include/naucrates/dxl/operators/dxlops.h
+++ b/libnaucrates/include/naucrates/dxl/operators/dxlops.h
@@ -92,6 +92,7 @@
#include "naucrates/dxl/operators/CDXLScalarCast.h"
#include "naucrates/dxl/operators/CDXLScalarCoerceToDomain.h"
#include "naucrates/dxl/operators/CDXLScalarCoerceViaIO.h"
+#include "naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h"
#include "naucrates/dxl/operators/CDXLScalarBooleanTest.h"
#include "naucrates/dxl/operators/CDXLScalarInitPlan.h"
#include "naucrates/dxl/operators/CDXLScalarArray.h"
diff --git a/libnaucrates/include/naucrates/dxl/parser/CParseHandlerFactory.h b/libnaucrates/include/naucrates/dxl/parser/CParseHandlerFactory.h
index 61da8280ce599845384591f8075689485fde240b..ece87301470022a3a22c84f59de11556db7e8cc9 100644
--- a/libnaucrates/include/naucrates/dxl/parser/CParseHandlerFactory.h
+++ b/libnaucrates/include/naucrates/dxl/parser/CParseHandlerFactory.h
@@ -937,6 +937,15 @@ namespace gpdxl
CParseHandlerBase *pphRoot
);
+ // construct a ArrayCoerceExpr parse handler
+ static
+ CParseHandlerBase *PphScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ CParseHandlerManager *pphm,
+ CParseHandlerBase *pphRoot
+ );
+
// construct an init plan parse handler
static
CParseHandlerBase *PphScalarInitPlan
diff --git a/libnaucrates/include/naucrates/dxl/parser/CParseHandlerScalarArrayCoerceExpr.h b/libnaucrates/include/naucrates/dxl/parser/CParseHandlerScalarArrayCoerceExpr.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f03287465db53cc889b63d67ef9dfb843150155
--- /dev/null
+++ b/libnaucrates/include/naucrates/dxl/parser/CParseHandlerScalarArrayCoerceExpr.h
@@ -0,0 +1,83 @@
+//---------------------------------------------------------------------------
+// Greenplum Database
+// Copyright (C) 2014 Pivotal Inc.
+//
+// @filename:
+// CParseHandlerScalarArrayCoerceExpr.h
+//
+// @doc:
+//
+// SAX parse handler class for parsing ArrayCoerceExpr operator.
+//
+// @owner:
+//
+// @test:
+//
+//
+//---------------------------------------------------------------------------
+
+#ifndef GPDXL_CParseHandlerScalarArrayCoerceExpr_H
+#define GPDXL_CParseHandlerScalarArrayCoerceExpr_H
+
+#include "gpos/base.h"
+#include "naucrates/dxl/parser/CParseHandlerScalarOp.h"
+
+#include "naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h"
+
+
+namespace gpdxl
+{
+ using namespace gpos;
+
+ XERCES_CPP_NAMESPACE_USE
+
+ //---------------------------------------------------------------------------
+ // @class:
+ // CParseHandlerScalarArrayCoerceExpr
+ //
+ // @doc:
+ // Parse handler for parsing parsing ArrayCoerceExpr operator
+ //
+ //---------------------------------------------------------------------------
+ class CParseHandlerScalarArrayCoerceExpr : public CParseHandlerScalarOp
+ {
+ private:
+
+ // private copy ctor
+ CParseHandlerScalarArrayCoerceExpr(const CParseHandlerScalarArrayCoerceExpr &);
+
+ // process the start of an element
+ void StartElement
+ (
+ const XMLCh* const xmlszUri, // URI of element's namespace
+ const XMLCh* const xmlszLocalname, // local part of element's name
+ const XMLCh* const xmlszQname, // element's qname
+ const Attributes& attr // element's attributes
+ );
+
+ // process the end of an element
+ void EndElement
+ (
+ const XMLCh* const xmlszUri, // URI of element's namespace
+ const XMLCh* const xmlszLocalname, // local part of element's name
+ const XMLCh* const xmlszQname // element's qname
+ );
+
+ public:
+ // ctor/dtor
+ CParseHandlerScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ CParseHandlerManager *pphm,
+ CParseHandlerBase *pphRoot
+ );
+
+ virtual
+ ~CParseHandlerScalarArrayCoerceExpr(){};
+
+ };
+
+}
+#endif // GPDXL_CParseHandlerScalarArrayCoerceExpr_H
+
+//EOF
diff --git a/libnaucrates/include/naucrates/dxl/parser/parsehandlers.h b/libnaucrates/include/naucrates/dxl/parser/parsehandlers.h
index 48e72198a265835f89edc4bec92ce2c7c6c44251..d2c572943e912a8973af160a2aaafff66e462ab1 100644
--- a/libnaucrates/include/naucrates/dxl/parser/parsehandlers.h
+++ b/libnaucrates/include/naucrates/dxl/parser/parsehandlers.h
@@ -83,6 +83,7 @@
#include "naucrates/dxl/parser/CParseHandlerScalarCast.h"
#include "naucrates/dxl/parser/CParseHandlerScalarCoerceToDomain.h"
#include "naucrates/dxl/parser/CParseHandlerScalarCoerceViaIO.h"
+#include "naucrates/dxl/parser/CParseHandlerScalarArrayCoerceExpr.h"
#include "naucrates/dxl/parser/CParseHandlerScalarSubquery.h"
#include "naucrates/dxl/parser/CParseHandlerScalarBitmapBoolOp.h"
diff --git a/libnaucrates/include/naucrates/dxl/xml/dxltokens.h b/libnaucrates/include/naucrates/dxl/xml/dxltokens.h
index 5560f992696b27bbd8e8ec204a7b338f22a03c10..898bbfeab6ad36ca99eac653818dd8ce9840bc8a 100644
--- a/libnaucrates/include/naucrates/dxl/xml/dxltokens.h
+++ b/libnaucrates/include/naucrates/dxl/xml/dxltokens.h
@@ -163,6 +163,7 @@ namespace gpdxl
EdxltokenScalarCast,
EdxltokenScalarCoerceToDomain,
EdxltokenScalarCoerceViaIO,
+ EdxltokenScalarArrayCoerceExpr,
EdxltokenScalarSortCol,
EdxltokenScalarSortColList,
EdxltokenScalarGroupingColList,
@@ -260,10 +261,12 @@ namespace gpdxl
EdxltokenConstTuple,
EdxltokenDatum,
- // CoerceToDomain and CoerceViaIO related tokens
+ // CoerceToDomain and CoerceViaIO and ArrayCoerceExpr related tokens
EdxltokenTypeMod,
EdxltokenCoercionForm,
EdxltokenLocation,
+ EdxltokenElementFunc,
+ EdxltokenIsExplicit,
EdxltokenJoinType,
EdxltokenJoinInner,
diff --git a/libnaucrates/src/operators/CDXLOperatorFactory.cpp b/libnaucrates/src/operators/CDXLOperatorFactory.cpp
index d3f40afb36307514687559299b7217f7bad73e55..497f8af50721c55fe0580a00257b95e26f288fca 100644
--- a/libnaucrates/src/operators/CDXLOperatorFactory.cpp
+++ b/libnaucrates/src/operators/CDXLOperatorFactory.cpp
@@ -1083,6 +1083,33 @@ CDXLOperatorFactory::PdxlopCoerceViaIO
return GPOS_NEW(pmp) CDXLScalarCoerceViaIO(pmp, pmdidType, iMod, (EdxlCoercionForm) ulCoercionForm, iLoc);
}
+//---------------------------------------------------------------------------
+// @function:
+// CDXLOperatorFactory::PdxlopArrayCoerceExpr
+//
+// @doc:
+// Construct a scalar array coerce expression
+//
+//---------------------------------------------------------------------------
+CDXLScalar *
+CDXLOperatorFactory::PdxlopArrayCoerceExpr
+ (
+ CDXLMemoryManager *pmm,
+ const Attributes &attrs
+ )
+{
+ IMemoryPool *pmp = pmm->Pmp();
+
+ IMDId *pmdidElementFunc = PmdidFromAttrs(pmm, attrs, EdxltokenElementFunc, EdxltokenScalarArrayCoerceExpr);
+ IMDId *pmdidType = PmdidFromAttrs(pmm, attrs, EdxltokenTypeId, EdxltokenScalarArrayCoerceExpr);
+ INT iMod = IValueFromAttrs(pmm, attrs, EdxltokenTypeMod, EdxltokenScalarArrayCoerceExpr);
+ BOOL fIsExplicit = FValueFromAttrs(pmm, attrs, EdxltokenIsExplicit, EdxltokenScalarArrayCoerceExpr);
+ ULONG ulCoercionForm = UlValueFromAttrs(pmm, attrs, EdxltokenCoercionForm, EdxltokenScalarArrayCoerceExpr);
+ INT iLoc = IValueFromAttrs(pmm, attrs, EdxltokenLocation, EdxltokenScalarArrayCoerceExpr);
+
+ return GPOS_NEW(pmp) CDXLScalarArrayCoerceExpr(pmp, pmdidElementFunc, pmdidType, iMod, fIsExplicit, (EdxlCoercionForm) ulCoercionForm, iLoc);
+}
+
//---------------------------------------------------------------------------
// @function:
// CDXLOperatorFactory::PdxlopConstValue
diff --git a/libnaucrates/src/operators/CDXLScalarArrayCoerceExpr.cpp b/libnaucrates/src/operators/CDXLScalarArrayCoerceExpr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed627e72b4b7fa261908e91ee5e0f0ac3991b1b3
--- /dev/null
+++ b/libnaucrates/src/operators/CDXLScalarArrayCoerceExpr.cpp
@@ -0,0 +1,165 @@
+//---------------------------------------------------------------------------
+// Greenplum Database
+// Copyright (C) 2017 Pivotal Inc.
+//
+// @filename:
+// CDXLScalarArrayCoerceExpr.cpp
+//
+// @doc:
+// Implementation of DXL scalar array coerce expr
+//
+// @owner:
+//
+// @test:
+//
+//---------------------------------------------------------------------------
+
+#include "naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h"
+#include "naucrates/dxl/operators/CDXLNode.h"
+#include "naucrates/dxl/xml/dxltokens.h"
+#include "naucrates/dxl/xml/CXMLSerializer.h"
+
+#include "gpopt/mdcache/CMDAccessor.h"
+
+using namespace gpopt;
+using namespace gpos;
+using namespace gpdxl;
+
+//---------------------------------------------------------------------------
+// @function:
+// CDXLScalarArrayCoerceExpr::CDXLScalarArrayCoerceExpr
+//
+// @doc:
+// Ctor
+//
+//---------------------------------------------------------------------------
+CDXLScalarArrayCoerceExpr::CDXLScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ IMDId *pmdidElementFunc,
+ IMDId *pmdidResultType,
+ INT iMod,
+ BOOL fIsExplicit,
+ EdxlCoercionForm edxlcf,
+ INT iLoc
+ )
+ :
+ CDXLScalar(pmp),
+ m_pmdidElementFunc(pmdidElementFunc),
+ m_pmdidResultType(pmdidResultType),
+ m_iMod(iMod),
+ m_fIsExplicit(fIsExplicit),
+ m_edxlcf(edxlcf),
+ m_iLoc(iLoc)
+{
+ GPOS_ASSERT(NULL != pmdidElementFunc);
+ GPOS_ASSERT(NULL != pmdidResultType);
+ GPOS_ASSERT(pmdidResultType->FValid());
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CDXLScalarArrayCoerceExpr::~CDXLScalarArrayCoerceExpr
+//
+// @doc:
+// Dtor
+//
+//---------------------------------------------------------------------------
+CDXLScalarArrayCoerceExpr::~CDXLScalarArrayCoerceExpr()
+{
+ m_pmdidElementFunc->Release();
+ m_pmdidResultType->Release();
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CDXLScalarArrayCoerceExpr::FBoolean
+//
+// @doc:
+// Does the operator return a boolean result
+//
+//---------------------------------------------------------------------------
+BOOL
+CDXLScalarArrayCoerceExpr::FBoolean
+ (
+ CMDAccessor *pmda
+ )
+ const
+{
+ return (IMDType::EtiBool == pmda->Pmdtype(m_pmdidResultType)->Eti());
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CDXLScalarArrayCoerceExpr::PstrOpName
+//
+// @doc:
+// Operator name
+//
+//---------------------------------------------------------------------------
+const CWStringConst *
+CDXLScalarArrayCoerceExpr::PstrOpName() const
+{
+ return CDXLTokens::PstrToken(EdxltokenScalarArrayCoerceExpr);
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CDXLScalarArrayCoerceExpr::SerializeToDXL
+//
+// @doc:
+// Serialize operator in DXL format
+//
+//---------------------------------------------------------------------------
+void
+CDXLScalarArrayCoerceExpr::SerializeToDXL
+ (
+ CXMLSerializer *pxmlser,
+ const CDXLNode *pdxln
+ )
+ const
+{
+ const CWStringConst *pstrElemName = PstrOpName();
+
+ pxmlser->OpenElement(CDXLTokens::PstrToken(EdxltokenNamespacePrefix), pstrElemName);
+
+ m_pmdidElementFunc->Serialize(pxmlser, CDXLTokens::PstrToken(EdxltokenElementFunc));
+ m_pmdidResultType->Serialize(pxmlser, CDXLTokens::PstrToken(EdxltokenTypeId));
+
+ pxmlser->AddAttribute(CDXLTokens::PstrToken(EdxltokenTypeMod), m_iMod);
+ pxmlser->AddAttribute(CDXLTokens::PstrToken(EdxltokenIsExplicit), m_fIsExplicit);
+ pxmlser->AddAttribute(CDXLTokens::PstrToken(EdxltokenCoercionForm), (ULONG) m_edxlcf);
+ pxmlser->AddAttribute(CDXLTokens::PstrToken(EdxltokenLocation), m_iLoc);
+
+ pdxln->SerializeChildrenToDXL(pxmlser);
+ pxmlser->CloseElement(CDXLTokens::PstrToken(EdxltokenNamespacePrefix), pstrElemName);
+}
+
+#ifdef GPOS_DEBUG
+//---------------------------------------------------------------------------
+// @function:
+// CDXLScalarArrayCoerceExpr::AssertValid
+//
+// @doc:
+// Checks whether operator node is well-structured
+//
+//---------------------------------------------------------------------------
+void
+CDXLScalarArrayCoerceExpr::AssertValid
+ (
+ const CDXLNode *pdxln,
+ BOOL fValidateChildren
+ ) const
+{
+ GPOS_ASSERT(1 == pdxln->UlArity());
+
+ CDXLNode *pdxlnChild = (*pdxln)[0];
+ GPOS_ASSERT(EdxloptypeScalar == pdxlnChild->Pdxlop()->Edxloperatortype());
+
+ if (fValidateChildren)
+ {
+ pdxlnChild->Pdxlop()->AssertValid(pdxlnChild, fValidateChildren);
+ }
+}
+#endif // GPOS_DEBUG
+// EOF
diff --git a/libnaucrates/src/parser/CParseHandlerFactory.cpp b/libnaucrates/src/parser/CParseHandlerFactory.cpp
index 69172c86c753ba5711a35d40a55c62cf885a0718..695a30ac9bb43a8ed3839817361789c5cbbf8f3e 100644
--- a/libnaucrates/src/parser/CParseHandlerFactory.cpp
+++ b/libnaucrates/src/parser/CParseHandlerFactory.cpp
@@ -185,6 +185,7 @@ CParseHandlerFactory::Init
{EdxltokenScalarCast, &PphScalarCast},
{EdxltokenScalarCoerceToDomain, PphScalarCoerceToDomain},
{EdxltokenScalarCoerceViaIO, PphScalarCoerceViaIO},
+ {EdxltokenScalarArrayCoerceExpr, PphScalarArrayCoerceExpr},
{EdxltokenScalarHashExpr, &PphHashExpr},
{EdxltokenScalarHashCondList, &PphCondList},
{EdxltokenScalarMergeCondList, &PphCondList},
@@ -2032,6 +2033,25 @@ CParseHandlerFactory::PphScalarCoerceViaIO
return GPOS_NEW(pmp) CParseHandlerScalarCoerceViaIO(pmp, pphm, pphRoot);
}
+//---------------------------------------------------------------------------
+// @function:
+// CParseHandlerFactory::PphScalarArrayCoerceExpr
+//
+// @doc:
+// Creates a parse handler for parsing an array coerce expression operator
+//
+//---------------------------------------------------------------------------
+CParseHandlerBase *
+CParseHandlerFactory::PphScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ CParseHandlerManager *pphm,
+ CParseHandlerBase *pphRoot
+ )
+{
+ return GPOS_NEW(pmp) CParseHandlerScalarArrayCoerceExpr(pmp, pphm, pphRoot);
+}
+
//---------------------------------------------------------------------------
// @function:
// CParseHandlerFactory::PphScalarInitPlan
diff --git a/libnaucrates/src/parser/CParseHandlerScalarArrayCoerceExpr.cpp b/libnaucrates/src/parser/CParseHandlerScalarArrayCoerceExpr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..155270b9774808c615e4e3cb89a1f66eb7b250b5
--- /dev/null
+++ b/libnaucrates/src/parser/CParseHandlerScalarArrayCoerceExpr.cpp
@@ -0,0 +1,126 @@
+//---------------------------------------------------------------------------
+// Greenplum Database
+// Copyright (C) 2014 Pivotal Inc.
+//
+// @filename:
+// CParseHandlerScalarArrayCoerceExpr.cpp
+//
+// @doc:
+//
+// Implementation of the SAX parse handler class for parsing scalar array coerce expression operator.
+//
+// @owner:
+//
+// @test:
+//
+//
+//---------------------------------------------------------------------------
+
+#include "naucrates/dxl/parser/CParseHandlerScalarOp.h"
+#include "naucrates/dxl/parser/CParseHandlerFactory.h"
+#include "naucrates/dxl/CDXLUtils.h"
+#include "naucrates/dxl/operators/CDXLOperatorFactory.h"
+
+#include "naucrates/dxl/parser/CParseHandlerScalarArrayCoerceExpr.h"
+
+
+using namespace gpdxl;
+
+
+XERCES_CPP_NAMESPACE_USE
+
+//---------------------------------------------------------------------------
+// @function:
+// CParseHandlerScalarArrayCoerceExpr::CParseHandlerScalarArrayCoerceExpr
+//
+// @doc:
+// Ctor
+//
+//---------------------------------------------------------------------------
+CParseHandlerScalarArrayCoerceExpr::CParseHandlerScalarArrayCoerceExpr
+ (
+ IMemoryPool *pmp,
+ CParseHandlerManager *pphm,
+ CParseHandlerBase *pphRoot
+ )
+ :
+ CParseHandlerScalarOp(pmp, pphm, pphRoot)
+{
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CParseHandlerScalarArrayCoerceExpr::StartElement
+//
+// @doc:
+// Processes a Xerces start element event
+//
+//---------------------------------------------------------------------------
+void
+CParseHandlerScalarArrayCoerceExpr::StartElement
+ (
+ const XMLCh* const, // xmlszUri,
+ const XMLCh* const xmlszLocalname,
+ const XMLCh* const, // xmlszQname
+ const Attributes& attrs
+ )
+{
+ if(0 == XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenScalarArrayCoerceExpr), xmlszLocalname))
+ {
+ if (NULL != m_pdxln)
+ {
+ CWStringDynamic *pstr = CDXLUtils::PstrFromXMLCh(m_pphm->Pmm(), xmlszLocalname);
+ GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, pstr->Wsz());
+ }
+
+ // parse and create scalar coerce
+ CDXLScalarArrayCoerceExpr *pdxlop = (CDXLScalarArrayCoerceExpr*) CDXLOperatorFactory::PdxlopArrayCoerceExpr(m_pphm->Pmm(), attrs);
+
+ m_pdxln = GPOS_NEW(m_pmp) CDXLNode(m_pmp, pdxlop);
+
+ // parse handler for child scalar node
+ CParseHandlerBase *pphChild = CParseHandlerFactory::Pph(m_pmp, CDXLTokens::XmlstrToken(EdxltokenScalar), m_pphm, this);
+ m_pphm->ActivateParseHandler(pphChild);
+
+ // store parse handler
+ this->Append(pphChild);
+ }
+ else
+ {
+ CWStringDynamic *pstr = CDXLUtils::PstrFromXMLCh(m_pphm->Pmm(), xmlszLocalname);
+ GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, pstr->Wsz());
+ }
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CParseHandlerScalarArrayCoerceExpr::EndElement
+//
+// @doc:
+// Processes a Xerces end element event
+//
+//---------------------------------------------------------------------------
+void
+CParseHandlerScalarArrayCoerceExpr::EndElement
+ (
+ const XMLCh* const, // xmlszUri,
+ const XMLCh* const xmlszLocalname,
+ const XMLCh* const // xmlszQname
+ )
+{
+ if(0 != XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenScalarArrayCoerceExpr), xmlszLocalname))
+ {
+ CWStringDynamic *pstr = CDXLUtils::PstrFromXMLCh(m_pphm->Pmm(), xmlszLocalname);
+ GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, pstr->Wsz());
+ }
+ GPOS_ASSERT(1 == this->UlLength());
+
+ // add constructed child from child parse handlers
+ CParseHandlerScalarOp *pphChild = dynamic_cast((*this)[0]);
+ AddChildFromParseHandler(pphChild);
+
+ // deactivate handler
+ m_pphm->DeactivateHandler();
+}
+
+// EOF
diff --git a/libnaucrates/src/xml/dxltokens.cpp b/libnaucrates/src/xml/dxltokens.cpp
index 9f7193e9e60afd2b5d9828c377420de2216d79a2..63bce51d0bf89b807505f5723ab63c87b4525e93 100644
--- a/libnaucrates/src/xml/dxltokens.cpp
+++ b/libnaucrates/src/xml/dxltokens.cpp
@@ -205,6 +205,7 @@ CDXLTokens::Init
{EdxltokenScalarCast, GPOS_WSZ_LIT("Cast")},
{EdxltokenScalarCoerceToDomain, GPOS_WSZ_LIT("CoerceToDomain")},
{EdxltokenScalarCoerceViaIO, GPOS_WSZ_LIT("CoerceViaIO")},
+ {EdxltokenScalarArrayCoerceExpr, GPOS_WSZ_LIT("ArrayCoerceExpr")},
{EdxltokenScalarSortCol, GPOS_WSZ_LIT("SortingColumn")},
{EdxltokenScalarSortColList, GPOS_WSZ_LIT("SortingColumnList")},
{EdxltokenScalarGroupingColList, GPOS_WSZ_LIT("GroupingColumns")},
@@ -267,6 +268,8 @@ CDXLTokens::Init
{EdxltokenTypeMod, GPOS_WSZ_LIT("TypeModification")},
{EdxltokenCoercionForm, GPOS_WSZ_LIT("CoercionForm")},
{EdxltokenLocation, GPOS_WSZ_LIT("Location")},
+ {EdxltokenElementFunc, GPOS_WSZ_LIT("ElementFunc")},
+ {EdxltokenIsExplicit, GPOS_WSZ_LIT("IsExplicit")},
{EdxltokenJoinType, GPOS_WSZ_LIT("JoinType")},
{EdxltokenJoinInner, GPOS_WSZ_LIT("Inner")},
diff --git a/server/src/unittest/gpopt/minidump/CICGTest.cpp b/server/src/unittest/gpopt/minidump/CICGTest.cpp
index 26daa8ee31aa5d310fe018ceb14c41f035779a83..da152335a395db0db05e4783d20b099154b275dc 100644
--- a/server/src/unittest/gpopt/minidump/CICGTest.cpp
+++ b/server/src/unittest/gpopt/minidump/CICGTest.cpp
@@ -40,6 +40,7 @@ ULONG CICGTest::m_ulNegativeIndexApplyTestCounter = 0;
// minidump files
const CHAR *rgszFileNames[] =
{
+ "../data/dxl/minidump/ArrayCoerceExpr.mdp",
"../data/dxl/minidump/DisableLargeTableBroadcast.mdp",
"../data/dxl/minidump/InferPredicatesForLimit.mdp",
"../data/dxl/minidump/OR-WithIsNullPred.mdp",