提交 8b95abb0 编写于 作者: B Bhunvesh Chaudhary 提交者: Bhuvnesh

Implement DXL Representation for VALUESSCAN [#147773843]

Postgres and thus (GPDB Planner) supports Values via an operator called ValueScan.
```
explain SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);
                          QUERY PLAN
--------------------------------------------------------------
 Values Scan on "*VALUES*"  (cost=0.00..0.04 rows=1 width=36)
 Optimizer status: legacy query optimizer
(2 rows)
```
However, inside Orca we expand each row in the Values list into a
Result node that projects constants.
Thus the above query with three rows having 2 columns is
represented as a plan by GPORCA as an append with three Result nodes.
Each of the Result nodes is a CTG with project elements.
```
explain SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);
                   QUERY PLAN
-------------------------------------------------
 Append  (cost=0.00..0.00 rows=1 width=12)
   ->  Result  (cost=0.00..0.00 rows=1 width=12)
   ->  Result  (cost=0.00..0.00 rows=1 width=12)
   ->  Result  (cost=0.00..0.00 rows=1 width=12)
 Settings:  optimizer=on
 Optimizer status: PQO version 2.32.0
(6 rows)
```

This commit introduces a new value scan operator and instead of
generating multiple result node, ORCA will now generate a value scan
node. The resulting plan will look like:

```
                                          QUERY PLAN
----------------------------------------------------------------------------------------------
 Values Scan on "Values"  (cost=0.00..0.44 rows=37000 width=4)
 Optimizer status: PQO version 2.37.0
(2 rows)
```

This enhancement bring in significant performance improvement in total
runtime of the queries involving high number of constant values.
Signed-off-by: NEkta Khanna <ekhanna@pivotal.io>
上级 2c4e0a9d
<?xml version="1.0" encoding="UTF-8"?>
<dxl:DXLMessage xmlns:dxl="http://greenplum.com/dxl/2010/12/">
<dxl:Plan Id="0" SpaceSize="0">
<dxl:Values>
<dxl:Properties>
<dxl:Cost StartupCost="0" TotalCost="0.000008" Rows="2.000000" Width="4"/>
</dxl:Properties>
<dxl:ProjList>
<dxl:ProjElem ColId="0" Alias="column1">
<dxl:Ident ColId="0" ColName="column1" TypeMdid="0.23.1.0"/>
</dxl:ProjElem>
</dxl:ProjList>
<dxl:ValuesList>
<dxl:ConstValue TypeMdid="0.23.1.0" IsNull="false" IsByValue="true" Value="1"/>
</dxl:ValuesList>
<dxl:ValuesList>
<dxl:ConstValue TypeMdid="0.23.1.0" IsNull="false" IsByValue="true" Value="1"/>
</dxl:ValuesList>
</dxl:Values>
</dxl:Plan>
</dxl:DXLMessage>
......@@ -677,7 +677,6 @@ namespace gpopt
DrgPdatum *pdrgpdatumValues
);
// create a DXL project elem node from a proj element expression
CDXLNode *PdxlnProjElem(const CExpression *pexprProjElem);
......
......@@ -489,6 +489,16 @@ namespace gpopt
CDXLNode *pdxlnChild
);
// create a DXL ValuesScan node
static
CDXLNode *PdxlnValuesScan
(
IMemoryPool *pmp,
CDXLPhysicalProperties *pdxlprop,
CDXLNode *pdxlnPrL,
DrgPdrgPdatum *pdrgpdrgdatum
);
// build hashmap based on a column array, where the key is the column
// and the value is the index of that column in the array
static
......
......@@ -2068,7 +2068,7 @@ CTranslatorExprToDXL::PdxlnResultFromConstTableGet
{
GPOS_ASSERT(NULL != pexprCTG);
CPhysicalConstTableGet *popCTG = CPhysicalConstTableGet::PopConvert(pexprCTG->Pop());
CPhysicalConstTableGet *popCTG = CPhysicalConstTableGet::PopConvert(pexprCTG->Pop());
// construct project list from the const table get values
DrgPcr *pdrgpcrCTGOutput = popCTG->PdrgpcrOutput();
......@@ -2092,8 +2092,7 @@ CTranslatorExprToDXL::PdxlnResultFromConstTableGet
}
else
{
// TODO: - Feb 29, 2012; add support for CTGs with multiple rows
GPOS_ASSERT(1 == ulRows);
GPOS_ASSERT(1 <= ulRows);
pdrgpdatum = (*pdrgpdrgdatum)[0];
pdrgpdatum->AddRef();
CDXLNode *pdxlnCond = NULL;
......@@ -2104,18 +2103,44 @@ CTranslatorExprToDXL::PdxlnResultFromConstTableGet
}
}
pdxlnPrL = PdxlnProjListFromConstTableGet(pdrgpcr, pdrgpcrCTGOutput, pdrgpdatum);
pdrgpdatum->Release();
// if CTG has multiple rows then it has to be a valuescan of constants,
// else, a Result node is created
if (ulRows > 1)
{
GPOS_ASSERT(NULL != pdrgpcrCTGOutput);
return CTranslatorExprToDXLUtils::PdxlnResult
(
m_pmp,
Pdxlprop(pexprCTG),
pdxlnPrL,
PdxlnFilter(NULL),
pdxlnOneTimeFilter,
NULL //pdxlnChild
);
CColRefSet *pcrsOutput = GPOS_NEW(m_pmp) CColRefSet(m_pmp);
pcrsOutput->Include(pdrgpcrCTGOutput);
pdxlnPrL = PdxlnProjList(pcrsOutput, pdrgpcr);
pcrsOutput->Release();
CDXLNode *pdxlnValuesScan = CTranslatorExprToDXLUtils::PdxlnValuesScan
(
m_pmp,
Pdxlprop(pexprCTG),
pdxlnPrL,
pdrgpdrgdatum
);
pdxlnOneTimeFilter->Release();
pdrgpdatum->Release();
return pdxlnValuesScan;
}
else
{
pdxlnPrL = PdxlnProjListFromConstTableGet(pdrgpcr, pdrgpcrCTGOutput, pdrgpdatum);
pdrgpdatum->Release();
return CTranslatorExprToDXLUtils::PdxlnResult
(
m_pmp,
Pdxlprop(pexprCTG),
pdxlnPrL,
PdxlnFilter(NULL),
pdxlnOneTimeFilter,
NULL //pdxlnChild
);
}
}
//---------------------------------------------------------------------------
......
......@@ -1708,6 +1708,52 @@ CTranslatorExprToDXLUtils::PdxlnResult
return pdxlnResult;
}
// create a DXL Value Scan node
CDXLNode *
CTranslatorExprToDXLUtils::PdxlnValuesScan
(
IMemoryPool *pmp,
CDXLPhysicalProperties *pdxlprop,
CDXLNode *pdxlnPrL,
DrgPdrgPdatum *pdrgpdrgdatum
)
{
CDXLPhysicalValuesScan *pdxlop = GPOS_NEW(pmp) CDXLPhysicalValuesScan(pmp);
CDXLNode *pdxlnValuesScan = GPOS_NEW(pmp) CDXLNode(pmp, pdxlop);
pdxlnValuesScan->SetProperties(pdxlprop);
pdxlnValuesScan->AddChild(pdxlnPrL);
const ULONG ulTuples = pdrgpdrgdatum->UlLength();
for (ULONG ulTuplePos = 0; ulTuplePos < ulTuples; ulTuplePos++)
{
DrgPdatum *pdrgpdatum = (*pdrgpdrgdatum)[ulTuplePos];
pdrgpdatum->AddRef();
const ULONG ulCols = pdrgpdatum->UlLength();
CDXLScalarValuesList *values = GPOS_NEW(pmp) CDXLScalarValuesList(pmp);
CDXLNode *pdxlnValueList = GPOS_NEW(pmp) CDXLNode(pmp, values);
for (ULONG ulColPos = 0; ulColPos < ulCols; ulColPos++)
{
IDatum *pdatum = (*pdrgpdatum)[ulColPos];
CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
const IMDType *pmdtype = pmda->Pmdtype(pdatum->Pmdid());
CDXLNode *pdxlnValue = GPOS_NEW(pmp) CDXLNode(pmp, pmdtype->PdxlopScConst(pmp, pdatum));
pdxlnValueList->AddChild(pdxlnValue);
}
pdrgpdatum->Release();
pdxlnValuesScan->AddChild(pdxlnValueList);
}
#ifdef GPOS_DEBUG
pdxlop->AssertValid(pdxlnValuesScan, true /* fValidateChildren */);
#endif
return pdxlnValuesScan;
}
//---------------------------------------------------------------------------
// @function:
// CTranslatorExprToDXLUtils::PdxlnPartitionSelector
......
......@@ -288,6 +288,8 @@ add_library(naucrates
src/operators/CDXLPhysicalRedistributeMotion.cpp
include/naucrates/dxl/operators/CDXLPhysicalResult.h
src/operators/CDXLPhysicalResult.cpp
include/naucrates/dxl/operators/CDXLPhysicalValuesScan.h
src/operators/CDXLPhysicalValuesScan.cpp
include/naucrates/dxl/operators/CDXLPhysicalRoutedDistributeMotion.h
src/operators/CDXLPhysicalRoutedDistributeMotion.cpp
include/naucrates/dxl/operators/CDXLPhysicalRowTrigger.h
......@@ -400,6 +402,8 @@ add_library(naucrates
src/operators/CDXLScalarPartDefault.cpp
include/naucrates/dxl/operators/CDXLScalarPartListValues.h
src/operators/CDXLScalarPartListValues.cpp
include/naucrates/dxl/operators/CDXLScalarValuesList.h
src/operators/CDXLScalarValuesList.cpp
include/naucrates/dxl/operators/CDXLScalarPartListNullTest.h
src/operators/CDXLScalarPartListNullTest.cpp
include/naucrates/dxl/operators/CDXLScalarPartOid.h
......@@ -636,6 +640,8 @@ add_library(naucrates
src/parser/CParseHandlerPhysicalTVF.cpp
include/naucrates/dxl/parser/CParseHandlerPhysicalWindow.h
src/parser/CParseHandlerPhysicalWindow.cpp
include/naucrates/dxl/parser/CParseHandlerValuesScan.h
src/parser/CParseHandlerValuesScan.cpp
include/naucrates/dxl/parser/CParseHandlerPlan.h
src/parser/CParseHandlerPlan.cpp
include/naucrates/dxl/parser/CParseHandlerProjElem.h
......@@ -754,6 +760,8 @@ add_library(naucrates
src/parser/CParseHandlerScalarWindowFrameEdge.cpp
include/naucrates/dxl/parser/CParseHandlerScalarWindowRef.h
src/parser/CParseHandlerScalarWindowRef.cpp
include/naucrates/dxl/parser/CParseHandlerScalarValuesList.h
src/parser/CParseHandlerScalarValuesList.cpp
include/naucrates/dxl/parser/CParseHandlerSearchStage.h
src/parser/CParseHandlerSearchStage.cpp
include/naucrates/dxl/parser/CParseHandlerSearchStrategy.h
......
......@@ -122,8 +122,10 @@ namespace gpdxl
EdxlopScalarPartBoundOpen,
EdxlopScalarPartListValues,
EdxlopScalarPartListNullTest,
EdxlopScalarValuesList,
EdxlopPhysicalResult,
EdxlopPhysicalValuesScan,
EdxlopPhysicalProjection,
EdxlopPhysicalTableScan,
EdxlopPhysicalBitmapTableScan,
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CDXLPhysicalValuesScan.h
//
// @doc:
// Class for representing DXL physical Values scan
//---------------------------------------------------------------------------
#ifndef GPDXL_CDXLPhysicalValuesScan_H
#define GPDXL_CDXLPhysicalValuesScan_H
#include "gpos/base.h"
#include "naucrates/dxl/operators/CDXLPhysical.h"
namespace gpdxl
{
enum EdxlnVal
{
EdxlValIndexProjList = 0,
EdxlValIndexConstStart,
EdxlValIndexSentinel
};
// class for representing DXL physical Values scan
class CDXLPhysicalValuesScan : public CDXLPhysical
{
private:
// private copy ctor
CDXLPhysicalValuesScan(CDXLPhysicalValuesScan&);
public:
// ctor
CDXLPhysicalValuesScan
(
IMemoryPool *pmp
);
// dtor
virtual
~CDXLPhysicalValuesScan();
// get operator type
Edxlopid Edxlop() const;
// get operator name
const CWStringConst *PstrOpName() const;
// serialize operator in DXL format
virtual
void SerializeToDXL(CXMLSerializer *pxmlser, const CDXLNode *pdxln) const;
// conversion function
static
CDXLPhysicalValuesScan *PdxlopConvert(CDXLOperator *pdxlop);
#ifdef GPOS_DEBUG
// checks whether the operator has valid structure, i.e. number and
// types of child nodes
void AssertValid(const CDXLNode *, BOOL fValidateChildren) const;
#endif // GPOS_DEBUG
};
}
#endif // !GPDXL_CDXLPhysicalValuesScan_H
// EOF
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CDXLScalarValuesList.h
//
// @doc:
// Class for representing DXL value list operator.
//---------------------------------------------------------------------------
#ifndef GPDXL_CDXLScalarValuesList_H
#define GPDXL_CDXLScalarValuesList_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 for representing DXL value list operator
class CDXLScalarValuesList : public CDXLScalar
{
private:
// private copy ctor
CDXLScalarValuesList(CDXLScalarValuesList&);
public:
// ctor
CDXLScalarValuesList(IMemoryPool *pmp);
// dtor
virtual
~CDXLScalarValuesList();
// ident accessors
Edxlopid Edxlop() const;
// name of the DXL operator
const CWStringConst *PstrOpName() const;
// serialize operator in DXL format
virtual
void SerializeToDXL(CXMLSerializer *pxmlser, const CDXLNode *pdxln) const;
// conversion function
static
CDXLScalarValuesList *PdxlopConvert(CDXLOperator *pdxlop);
// does the operator return a boolean result
virtual
BOOL FBoolean(CMDAccessor * /*pmda*/) const;
#ifdef GPOS_DEBUG
// checks whether the operator has valid structure, i.e. number and
// types of child nodes
void AssertValid(const CDXLNode *pdxln, BOOL fValidateChildren) const;
#endif // GPOS_DEBUG
};
}
#endif // !GPDXL_CDXLScalarValuesList_H
// EOF
......@@ -49,6 +49,7 @@
#include "naucrates/dxl/operators/CDXLPhysicalAssert.h"
#include "naucrates/dxl/operators/CDXLPhysicalCTEConsumer.h"
#include "naucrates/dxl/operators/CDXLPhysicalCTEProducer.h"
#include "naucrates/dxl/operators/CDXLPhysicalValuesScan.h"
#include "naucrates/dxl/operators/CDXLTableDescr.h"
#include "naucrates/dxl/operators/CDXLIndexDescr.h"
......@@ -121,6 +122,7 @@
#include "naucrates/dxl/operators/CDXLScalarPartBoundOpen.h"
#include "naucrates/dxl/operators/CDXLScalarPartListValues.h"
#include "naucrates/dxl/operators/CDXLScalarPartListNullTest.h"
#include "naucrates/dxl/operators/CDXLScalarValuesList.h"
#include "naucrates/dxl/operators/CDXLLogicalTVF.h"
#include "naucrates/dxl/operators/CDXLLogicalGet.h"
......
......@@ -1604,6 +1604,24 @@ namespace gpdxl
CParseHandlerBase *pphRoot
);
// construct a scalar values list parse handler
static
CParseHandlerBase *PphScalarValuesList
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
);
// construct a values scan parse handler
static
CParseHandlerBase *PphValuesScan
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
);
public:
// initialize mappings of tokens to parse handlers
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CParseHandlerScalarValuesList.h
//
// @doc:
// SAX parse handler class for parsing scalar value list.
//---------------------------------------------------------------------------
#ifndef GPDXL_CParseHandlerScalarValuesList_H
#define GPDXL_CParseHandlerScalarValuesList_H
#include "gpos/base.h"
#include "naucrates/dxl/parser/CParseHandlerOp.h"
namespace gpdxl
{
using namespace gpos;
XERCES_CPP_NAMESPACE_USE
// Parse handler for parsing a value list operator
class CParseHandlerScalarValuesList : public CParseHandlerOp
{
private:
// private copy ctor
CParseHandlerScalarValuesList(const CParseHandlerScalarValuesList &);
// 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
CParseHandlerScalarValuesList
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
);
};
}
#endif // !GPDXL_CParseHandlerScalarValuesList_H
// EOF
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CParseHandlerValuesScan.h
//
// @doc:
// SAX parse handler class for parsing ValuesScan operator nodes.
//---------------------------------------------------------------------------
#ifndef GPDXL_CParseHandlerValuesScan_H
#define GPDXL_CParseHandlerValuesScan_H
#include "gpos/base.h"
#include "naucrates/dxl/parser/CParseHandlerPhysicalOp.h"
#include "naucrates/dxl/operators/CDXLPhysicalValuesScan.h"
namespace gpdxl
{
using namespace gpos;
XERCES_CPP_NAMESPACE_USE
//---------------------------------------------------------------------------
// @class:
// CParseHandlerValuesScan
//
// @doc:
// Parse handler for parsing a ValuesScan operator
//
//---------------------------------------------------------------------------
class CParseHandlerValuesScan : public CParseHandlerPhysicalOp
{
private:
// the ValuesScan operator
CDXLPhysicalValuesScan *m_pdxlop;
// private copy ctor
CParseHandlerValuesScan(const CParseHandlerValuesScan &);
// set up initial handlers
void SetupInitialHandlers();
// 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
CParseHandlerValuesScan
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
);
};
}
#endif // !GPDXL_CParseHandlerValuesScan_H
// EOF
......@@ -89,6 +89,7 @@
#include "naucrates/dxl/parser/CParseHandlerLogicalTVF.h"
#include "naucrates/dxl/parser/CParseHandlerPhysicalTVF.h"
#include "naucrates/dxl/parser/CParseHandlerValuesScan.h"
#include "naucrates/dxl/parser/CParseHandlerPhysicalDML.h"
#include "naucrates/dxl/parser/CParseHandlerPhysicalSplit.h"
......@@ -157,6 +158,7 @@
#include "naucrates/dxl/parser/CParseHandlerScalarPartBoundOpen.h"
#include "naucrates/dxl/parser/CParseHandlerScalarPartListValues.h"
#include "naucrates/dxl/parser/CParseHandlerScalarPartListNullTest.h"
#include "naucrates/dxl/parser/CParseHandlerScalarValuesList.h"
#include "naucrates/dxl/parser/CParseHandlerLogicalConstTable.h"
......
......@@ -105,6 +105,7 @@ namespace gpdxl
EdxltokenPhysicalPartitionSelector,
EdxltokenPhysicalPartitionSelectorLevels,
EdxltokenPhysicalPartitionSelectorScanId,
EdxltokenPhysicalValuesScan,
EdxltokenPhysicalCTEProducer,
EdxltokenPhysicalCTEConsumer,
......@@ -215,6 +216,7 @@ namespace gpdxl
EdxltokenScalarPropagationExpr,
EdxltokenScalarPrintableFilter,
EdxltokenScalarBitmapIndexProbe,
EdxltokenScalarValuesList,
EdxltokenWindowFrame,
EdxltokenScalarWindowFrameLeadingEdge,
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CDXLPhysicalValuesScan.cpp
//
// @doc:
// Implementation of DXL physical values scan operator
//---------------------------------------------------------------------------
#include "naucrates/dxl/operators/CDXLPhysicalValuesScan.h"
#include "naucrates/dxl/operators/CDXLNode.h"
#include "naucrates/dxl/xml/CXMLSerializer.h"
using namespace gpos;
using namespace gpdxl;
// ctor
CDXLPhysicalValuesScan::CDXLPhysicalValuesScan
(
IMemoryPool *pmp
)
:
CDXLPhysical(pmp)
{}
// dtor
CDXLPhysicalValuesScan::~CDXLPhysicalValuesScan
(
)
{}
// operator type
Edxlopid
CDXLPhysicalValuesScan::Edxlop() const
{
return EdxlopPhysicalValuesScan;
}
// operator name
const CWStringConst *
CDXLPhysicalValuesScan::PstrOpName() const
{
return CDXLTokens::PstrToken(EdxltokenPhysicalValuesScan);
}
CDXLPhysicalValuesScan *
CDXLPhysicalValuesScan::PdxlopConvert
(
CDXLOperator *pdxlop
)
{
GPOS_ASSERT(NULL != pdxlop);
GPOS_ASSERT(EdxlopPhysicalValuesScan ==pdxlop->Edxlop());
return dynamic_cast<CDXLPhysicalValuesScan *>(pdxlop);
}
// serialize operator in DXL format
void
CDXLPhysicalValuesScan::SerializeToDXL
(
CXMLSerializer *pxmlser,
const CDXLNode *pdxln
)
const
{
const CWStringConst *pstrElemName = PstrOpName();
pxmlser->OpenElement(CDXLTokens::PstrToken(EdxltokenNamespacePrefix), pstrElemName);
// serialize properties
pdxln->SerializePropertiesToDXL(pxmlser);
// serialize children
pdxln->SerializeChildrenToDXL(pxmlser);
pxmlser->CloseElement(CDXLTokens::PstrToken(EdxltokenNamespacePrefix), pstrElemName);
}
#ifdef GPOS_DEBUG
// checks whether operator node is well-structured
void
CDXLPhysicalValuesScan::AssertValid
(
const CDXLNode *pdxln,
BOOL fValidateChildren
)
const
{
GPOS_ASSERT(EdxloptypePhysical == pdxln->Pdxlop()->Edxloperatortype());
const ULONG ulArity = pdxln->UlArity();
GPOS_ASSERT(EdxlValIndexSentinel <= ulArity);
for (ULONG ul = 0; ul < ulArity; ul++)
{
CDXLNode *pdxlnChild = (*pdxln)[ul];
GPOS_ASSERT(EdxloptypeScalar == pdxlnChild->Pdxlop()->Edxloperatortype());
if (fValidateChildren)
{
pdxlnChild->Pdxlop()->AssertValid(pdxlnChild, fValidateChildren);
}
}
}
#endif // GPOS_DEBUG
// EOF
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CDXLScalarValuesList.cpp
//
// @doc:
// Implementation of DXL value list operator
//---------------------------------------------------------------------------
#include "naucrates/dxl/operators/CDXLScalarValuesList.h"
#include "naucrates/dxl/operators/CDXLNode.h"
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/xml/CXMLSerializer.h"
using namespace gpos;
using namespace gpdxl;
// constructs a value list node
CDXLScalarValuesList::CDXLScalarValuesList
(
IMemoryPool *pmp
)
:
CDXLScalar(pmp)
{
}
// destructor
CDXLScalarValuesList::~CDXLScalarValuesList()
{
}
// operator type
Edxlopid
CDXLScalarValuesList::Edxlop() const
{
return EdxlopScalarValuesList;
}
// operator name
const CWStringConst *
CDXLScalarValuesList::PstrOpName() const
{
return CDXLTokens::PstrToken(EdxltokenScalarValuesList);
}
// serialize operator in DXL format
void
CDXLScalarValuesList::SerializeToDXL
(
CXMLSerializer *pxmlser,
const CDXLNode *pdxln
)
const
{
GPOS_CHECK_ABORT;
const CWStringConst *pstrElemName = PstrOpName();
pxmlser->OpenElement(CDXLTokens::PstrToken(EdxltokenNamespacePrefix), pstrElemName);
pdxln->SerializeChildrenToDXL(pxmlser);
pxmlser->CloseElement(CDXLTokens::PstrToken(EdxltokenNamespacePrefix), pstrElemName);
GPOS_CHECK_ABORT;
}
// conversion function
CDXLScalarValuesList *
CDXLScalarValuesList::PdxlopConvert
(
CDXLOperator *pdxlop
)
{
GPOS_ASSERT(NULL != pdxlop);
GPOS_ASSERT(EdxlopScalarValuesList == pdxlop->Edxlop());
return dynamic_cast<CDXLScalarValuesList*>(pdxlop);
}
// does the operator return a boolean result
BOOL
CDXLScalarValuesList::FBoolean
(
CMDAccessor * //pmda
)
const
{
return false;
}
#ifdef GPOS_DEBUG
// checks whether operator node is well-structured
void
CDXLScalarValuesList::AssertValid
(
const CDXLNode *pdxln,
BOOL fValidateChildren
)
const
{
const ULONG ulArity = pdxln->UlArity();
for (ULONG ul = 0; ul < ulArity; ++ul)
{
CDXLNode *pdxlnConstVal = (*pdxln)[ul];
GPOS_ASSERT(EdxloptypeScalar == pdxlnConstVal->Pdxlop()->Edxloperatortype());
if (fValidateChildren)
{
pdxlnConstVal->Pdxlop()->AssertValid(pdxlnConstVal, fValidateChildren);
}
}
}
#endif // GPOS_DEBUG
// EOF
......@@ -285,7 +285,9 @@ CParseHandlerFactory::Init
{EdxltokenCostParams, &PphCostParams},
{EdxltokenCostParam, &PphCostParam},
{EdxltokenScalarExpr, &PphScalarExpr}
{EdxltokenScalarExpr, &PphScalarExpr},
{EdxltokenScalarValuesList, &PphScalarValuesList},
{EdxltokenPhysicalValuesScan, &PphValuesScan}
};
......@@ -3570,4 +3572,28 @@ CParseHandlerFactory::PphMDGPDBCheckConstraint
return GPOS_NEW(pmp) CParseHandlerMDGPDBCheckConstraint(pmp, pphm, pphRoot);
}
// creates a parse handler for parsing a Values List operator
CParseHandlerBase *
CParseHandlerFactory::PphScalarValuesList
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
)
{
return GPOS_NEW(pmp) CParseHandlerScalarValuesList(pmp, pphm, pphRoot);
}
// creates a parse handler for parsing a Values Scan operator
CParseHandlerBase *
CParseHandlerFactory::PphValuesScan
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
)
{
return GPOS_NEW(pmp) CParseHandlerValuesScan(pmp, pphm, pphRoot);
}
// EOF
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CParseHandlerScalarValuesList.cpp
//
// @doc:
// Implementation of the SAX parse handler class for parsing value list.
//---------------------------------------------------------------------------
#include "naucrates/dxl/parser/CParseHandlerScalarValuesList.h"
#include "naucrates/dxl/parser/CParseHandlerScalarOp.h"
#include "naucrates/dxl/parser/CParseHandlerFactory.h"
#include "naucrates/dxl/operators/CDXLScalarValuesList.h"
#include "naucrates/dxl/operators/CDXLOperatorFactory.h"
#include "naucrates/dxl/parser/CParseHandlerUtils.h"
using namespace gpdxl;
XERCES_CPP_NAMESPACE_USE
// ctor
CParseHandlerScalarValuesList::CParseHandlerScalarValuesList
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
)
:
CParseHandlerOp(pmp, pphm, pphRoot)
{
}
// invoked by Xerces to process an opening tag
void
CParseHandlerScalarValuesList::StartElement
(
const XMLCh* const xmlszUri,
const XMLCh* const xmlszLocalname,
const XMLCh* const xmlszQname,
const Attributes& attrs
)
{
if (0 == XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenScalarValuesList), xmlszLocalname))
{
CDXLScalarValuesList *pdxlop = GPOS_NEW(m_pmp) CDXLScalarValuesList(m_pmp);
m_pdxln = GPOS_NEW(m_pmp) CDXLNode(m_pmp, pdxlop);
}
else if (0 == XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenScalarConstValue), xmlszLocalname))
{
CParseHandlerBase *pphScConstValue = CParseHandlerFactory::Pph(m_pmp, xmlszLocalname, m_pphm, this);
m_pphm->ActivateParseHandler(pphScConstValue);
this->Append(pphScConstValue);
pphScConstValue->startElement(xmlszUri, xmlszLocalname, xmlszQname, attrs);
}
else
{
CWStringDynamic *pstr = CDXLUtils::PstrFromXMLCh(m_pphm->Pmm(), xmlszLocalname);
GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, pstr->Wsz());
}
}
// invoked by Xerces to process a closing tag
void
CParseHandlerScalarValuesList::EndElement
(
const XMLCh* const, // xmlszUri,
const XMLCh* const, //xmlszLocalname,
const XMLCh* const // xmlszQname
)
{
const ULONG ulArity = this->UlLength();
for (ULONG ul = 0; ul < ulArity; ul++)
{
CParseHandlerScalarOp *pphChild = dynamic_cast<CParseHandlerScalarOp *>((*this)[ul]);
AddChildFromParseHandler(pphChild);
}
m_pphm->DeactivateHandler();
}
// EOF
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CParseHandlerValuesScan.cpp
//
// @doc:
//
// Implementation of the SAX parse handler class for parsing value scan
// operator
//---------------------------------------------------------------------------
#include "naucrates/dxl/parser/CParseHandlerFactory.h"
#include "naucrates/dxl/parser/CParseHandlerValuesScan.h"
#include "naucrates/dxl/parser/CParseHandlerProjList.h"
#include "naucrates/dxl/parser/CParseHandlerScalarValuesList.h"
#include "naucrates/dxl/parser/CParseHandlerProperties.h"
#include "naucrates/dxl/parser/CParseHandlerPhysicalOp.h"
#include "naucrates/dxl/parser/CParseHandlerUtils.h"
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/operators/CDXLOperatorFactory.h"
using namespace gpdxl;
XERCES_CPP_NAMESPACE_USE
// ctor
CParseHandlerValuesScan::CParseHandlerValuesScan
(
IMemoryPool *pmp,
CParseHandlerManager *pphm,
CParseHandlerBase *pphRoot
)
:
CParseHandlerPhysicalOp(pmp, pphm, pphRoot)
{
}
// processes a Xerces start element event
void
CParseHandlerValuesScan::StartElement
(
const XMLCh* const xmlszUri,
const XMLCh* const xmlszLocalname,
const XMLCh* const xmlszQname,
const Attributes &attrs
)
{
if (0 == XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenPhysicalValuesScan), xmlszLocalname))
{
m_pdxlop = GPOS_NEW(m_pmp) CDXLPhysicalValuesScan(m_pmp);
// parse handler for the proj list
CParseHandlerBase *pphPrL = CParseHandlerFactory::Pph(m_pmp, CDXLTokens::XmlstrToken(EdxltokenScalarProjList), m_pphm, this);
m_pphm->ActivateParseHandler(pphPrL);
//parse handler for the properties of the operator
CParseHandlerBase *pphProp = CParseHandlerFactory::Pph(m_pmp, CDXLTokens::XmlstrToken(EdxltokenProperties), m_pphm, this);
m_pphm->ActivateParseHandler(pphProp);
// store parse handlers
this->Append(pphProp);
this->Append(pphPrL);
}
else
{
// parse scalar child
CParseHandlerBase *pphChild = CParseHandlerFactory::Pph(m_pmp, CDXLTokens::XmlstrToken(EdxltokenScalarValuesList), m_pphm, this);
m_pphm->ActivateParseHandler(pphChild);
// store parse handler
this->Append(pphChild);
pphChild->startElement(xmlszUri, xmlszLocalname, xmlszQname, attrs);
}
}
// processes a Xerces end element event
void
CParseHandlerValuesScan::EndElement
(
const XMLCh* const, // xmlszUri,
const XMLCh* const xmlszLocalname,
const XMLCh* const // xmlszQname
)
{
if (0 != XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenPhysicalValuesScan), xmlszLocalname))
{
CWStringDynamic *pstr = CDXLUtils::PstrFromXMLCh(m_pphm->Pmm(), xmlszLocalname);
GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, pstr->Wsz());
}
const ULONG ulArity = this->UlLength();
GPOS_ASSERT(3 <= ulArity);
m_pdxln = GPOS_NEW(m_pmp) CDXLNode(m_pmp, m_pdxlop);
// valuesscan has properties element as its first child
CParseHandlerProperties *pphProp = dynamic_cast<CParseHandlerProperties *>((*this)[0]);
// set statistics and physical properties
CParseHandlerUtils::SetProperties(m_pdxln, pphProp);
// valuesscan has project list element as its second child
CParseHandlerProjList *pphPrL = dynamic_cast<CParseHandlerProjList*>((*this)[1]);
AddChildFromParseHandler(pphPrL);
// valuesscan child value list begins with third child
for (ULONG ul = 2; ul < ulArity; ul++)
{
CParseHandlerScalarValuesList *pphPScValuesList = dynamic_cast<CParseHandlerScalarValuesList *>((*this)[ul]);
AddChildFromParseHandler(pphPScValuesList);
}
// deactivate handler
m_pphm->DeactivateHandler();
}
// EOF
......@@ -119,6 +119,7 @@ CDXLTokens::Init
{EdxltokenPhysicalAggregate, GPOS_WSZ_LIT("Aggregate")},
{EdxltokenPhysicalSubqueryScan, GPOS_WSZ_LIT("SubqueryScan")},
{EdxltokenPhysicalResult, GPOS_WSZ_LIT("Result")},
{EdxltokenPhysicalValuesScan, GPOS_WSZ_LIT("Values")},
{EdxltokenPhysicalAppend, GPOS_WSZ_LIT("Append")},
{EdxltokenPhysicalMaterialize, GPOS_WSZ_LIT("Materialize")},
{EdxltokenPhysicalSequence, GPOS_WSZ_LIT("Sequence")},
......@@ -257,6 +258,7 @@ CDXLTokens::Init
{EdxltokenScalarSubPlanParamList, GPOS_WSZ_LIT("ParamList")},
{EdxltokenScalarSubPlanParam, GPOS_WSZ_LIT("Param")},
{EdxltokenScalarSubPlanTestExpr, GPOS_WSZ_LIT("TestExpr")},
{EdxltokenScalarValuesList, GPOS_WSZ_LIT("ValuesList")},
{EdxltokenValue, GPOS_WSZ_LIT("Value")},
{EdxltokenTypeId, GPOS_WSZ_LIT("TypeMdid")},
......
......@@ -83,7 +83,7 @@ CParseHandlerTest::m_rgszPlanDXLFileNames[] =
"../data/dxl/parse_tests/q71-DynamicBitmapTableScan.xml",
"../data/dxl/parse_tests/q72-BitmapBoolOp.xml",
"../data/dxl/parse_tests/q74-DirectDispatchInfo.xml",
"../data/dxl/parse_tests/q76-ValuesScan.xml",
};
// files for tests involving dxl representation of queries
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册