blob: 460c16baaddaca39ee6648161b07ee6b3d3dd63c [file] [log] [blame]
/* -*-C++-*- */
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: StmtDDLCreate.C
* Description: Methods for classes representing DDL Create Statements
*
* Also contains definitions of non-inline methods of
* classes relating to view usages.
*
*
* Created: 3/9/95
* Language: C++
*
*
*
*
*****************************************************************************
*/
#define SQLPARSERGLOBALS_FLAGS // must precede all #include's
#include <stdlib.h>
#ifndef NDEBUG
#include <iostream>
#endif
#include "AllElemDDLPartition.h"
#include "AllElemDDLParam.h"
#include "AllElemDDLUdr.h"
#include "AllStmtDDLCreate.h"
#include "BaseTypes.h"
#include "ComDiags.h"
#include "ComOperators.h"
#include "ComMisc.h"
#include "ComDistribution.h"
#include "ElemDDLConstraintCheck.h"
#include "ElemDDLConstraintPK.h"
#include "ElemDDLConstraintRI.h"
#include "ElemDDLConstraintUnique.h"
#include "ElemDDLFileAttrClause.h"
#include "ElemDDLGrantee.h"
#include "ElemDDLLibClientFilename.h"
#include "ElemDDLLibClientName.h"
#include "ElemDDLList.h"
#include "ElemDDLLocation.h"
#include "ElemDDLParallelExec.h"
#include "ElemDDLPartitionList.h"
#include "ElemDDLSchemaName.h"
#include "ElemDDLStoreOptions.h"
#include "ElemDDLWithCheckOption.h"
#include "ElemDDLIndexPopulateOption.h"
#include "ItemConstValueArray.h"
#include "StmtDDLAddConstraintPK.h"
#include "StmtDDLCreateLibrary.h"
#include "StmtDDLCreateSynonym.h"
#include "ElemDDLMVFileAttrClause.h"
#include "StmtDDLCreateExceptionTable.h"
#include "StmtDDLCommentOn.h"
#include "MVInfo.h"
#include "NumericType.h"
#ifndef SQLPARSERGLOBALS_CONTEXT_AND_DIAGS
#define SQLPARSERGLOBALS_CONTEXT_AND_DIAGS
#endif
#include "SqlParserGlobals.h" // must be last #include
// -----------------------------------------------------------------------
// ComUudfParamKind translation
// -----------------------------------------------------------------------
// Keep getting the folowing error on NSK platform when i define
// the following definitions in w:/common/ComMisc.cpp so i move
// them to here.
// *** RLD ERROR ***: Unresolved Text Symbo
// ComGetUudfParamKindAsLit__F16ComUudfParamKindR8NAString
// in file /G/fc0001/kdl0208d/mxcmp.
static
const literalAndEnumStruct ComUudfParamKindXlateArray [] =
{
{COM_UUDF_PARAM_OMITTED, COM_UUDF_PARAM_OMITTED_LIT},
{COM_UUDF_PARAM_ACTION, COM_UUDF_PARAM_ACTION_LIT},
{COM_UUDF_PARAM_SAS_FORMAT, COM_UUDF_PARAM_SAS_FORMAT_LIT},
{COM_UUDF_PARAM_SAS_LOCALE, COM_UUDF_PARAM_SAS_LOCALE_LIT},
{COM_UUDF_PARAM_SAS_MODEL_INPUT_TABLE, COM_UUDF_PARAM_SAS_MODEL_INPUT_TABLE_LIT}
};
// define the enum-to-literal function
static
void ComGetUudfParamKindAsLit ( const ComUudfParamKind pv_enumValue // in
, NAString &pr_literal // out
)
{
NABoolean lv_found;
char la_lit[100];
enumToLiteral ( ComUudfParamKindXlateArray
, occurs(ComUudfParamKindXlateArray)
, pv_enumValue
, la_lit
, lv_found
);
ComASSERT(lv_found);
pr_literal = la_lit;
}
// -----------------------------------------------------------------------
// definitions of file-scope function ParIsTracingViewUsages()
// -----------------------------------------------------------------------
NABoolean ParIsTracingViewUsages()
{
return (getenv("SQLMX_TRACE_VIEW_USAGES") NEQ NULL);
}
// -----------------------------------------------------------------------
// definitions of non-inline methods for class ParViewTableColsUsage
// -----------------------------------------------------------------------
//
// default constructor
//
//
// initialize constructor
//
ParViewTableColsUsage::ParViewTableColsUsage(const ColRefName &colName, CollHeap * h)
: tableName_(colName.getCorrNameObj().getQualifiedNameObj(), h),
columnName_(colName.getColName(), h)
{}
//
// virtual destructor
//
ParViewTableColsUsage::~ParViewTableColsUsage()
{
}
//
// operator
//
NABoolean
ParViewTableColsUsage::operator==(const ParViewTableColsUsage &rhs) const
{
if (this EQU &rhs)
{
return TRUE;
}
return (getColumnName() EQU rhs.getColumnName() AND
getTableQualName() EQU rhs.getTableQualName());
}
// -----------------------------------------------------------------------
// definitions of non-inline methods for class ParViewTableColsUsageList
// -----------------------------------------------------------------------
//
// constructor
//
ParViewTableColsUsageList::ParViewTableColsUsageList(CollHeap *heap)
: LIST(ParViewTableColsUsage *)(heap),
heap_(heap)
{
}
//
// virtual destructor
//
ParViewTableColsUsageList::~ParViewTableColsUsageList()
{
for (CollIndex i = 0; i < entries(); i++)
{
delete &operator[](i);
// NADELETE(&operator[](i), ParViewTableColsUsage, heap_);
}
}
//
// accessor
//
ParViewTableColsUsage * const
ParViewTableColsUsageList::find(const ColRefName &colName)
{
for (CollIndex i = 0; i < entries(); i++)
{
if (operator[](i).getColumnName() EQU colName.getColName() AND
operator[](i).getTableQualName() EQU colName.getCorrNameObj().
getQualifiedNameObj())
{
return &operator[](i);
}
}
return NULL;
}
//
// mutator
//
NABoolean
ParViewTableColsUsageList::insert(const ColRefName &colName)
{
ParViewTableColsUsage * pCu = find(colName);
if (pCu EQU NULL) // not found
{
// ok to insert
pCu = new(heap_) ParViewTableColsUsage(colName);
CMPASSERT(pCu NEQ NULL);
LIST(ParViewTableColsUsage *)::insert(pCu);
#ifndef NDEBUG
if (ParIsTracingViewUsages())
{
NAString traceStr = "v-tcu: " +
colName.getCorrNameObj().getQualifiedNameObj().
getQualifiedNameAsAnsiString() +
"." + ToAnsiIdentifier(colName.getColName());
cout << traceStr << endl;
// *SqlParser_Diags << DgSqlCode(3066) // kludge to print trace message
// << DgString0(traceStr);
}
#endif
return TRUE; // inserted successfully
}
else // found
{
return FALSE; // does nothing
}
}
// -----------------------------------------------------------------------
// Definitions of non-inline methods of class ParViewColTablesUsage
// -----------------------------------------------------------------------
//
// constructors
//
ParViewColTablesUsage::ParViewColTablesUsage(
const CollIndex usingViewColumnNumber,
const ExtendedQualName &usedObjectName,
CollHeap * h)
: usingViewColumnNumber_(usingViewColumnNumber),
usedObjectName_(usedObjectName, h)
{}
//
// virtual destructor
//
ParViewColTablesUsage::~ParViewColTablesUsage()
{
}
//
// operator
//
NABoolean
ParViewColTablesUsage::operator==(const ParViewColTablesUsage &rhs) const
{
if (this EQU &rhs)
{
return TRUE;
}
return (getUsingViewColumnNumber() EQU rhs.getUsingViewColumnNumber() AND
getUsedObjectName() EQU rhs.getUsedObjectName());
}
// -----------------------------------------------------------------------
// Definitions of non-inline methods of class ParViewColTablesUsageList
// -----------------------------------------------------------------------
//
// constructor
//
ParViewColTablesUsageList::ParViewColTablesUsageList(CollHeap *heap)
: LIST(ParViewColTablesUsage *)(heap),
heap_(heap)
{
}
//
// virtual destructor
//
ParViewColTablesUsageList::~ParViewColTablesUsageList()
{
for (CollIndex i = 0; i < entries(); i++)
{
delete &operator[](i);
// NADELETE(&operator[](i), ParViewColTablesUsage, heap_);
}
}
//
// accessor
//
ParViewColTablesUsage * const
ParViewColTablesUsageList::find(const CollIndex usingViewColNum)
{
for (CollIndex i = 0; i < entries(); i++)
{
if (operator[](i).getUsingViewColumnNumber() EQU usingViewColNum)
{
return &operator[](i);
}
}
return NULL;
}
const ParViewColTablesUsage * const
ParViewColTablesUsageList::find(const CollIndex usingViewColNum) const
{
for (CollIndex i = 0; i < entries(); i++)
{
if (operator[](i).getUsingViewColumnNumber() EQU usingViewColNum)
{
return &operator[](i);
}
}
return NULL;
}
//
// mutator
//
NABoolean
ParViewColTablesUsageList::insert(const CollIndex usingViewColumnNumber,
const ExtendedQualName &usedObjectName)
{
ParViewColTablesUsage *vctu = find(usingViewColumnNumber);
if (vctu EQU NULL) // not found
{
// ok to insert
vctu = new(heap_) ParViewColTablesUsage(usingViewColumnNumber,
usedObjectName);
CMPASSERT(vctu NEQ NULL);
LIST(ParViewColTablesUsage *)::insert(vctu);
#ifndef NDEBUG
if (ParIsTracingViewUsages())
{
NAString traceStr = "vct-u: " +
LongToNAString((Lng32)usingViewColumnNumber) +
" " +
usedObjectName.getQualifiedNameObj().getQualifiedNameAsAnsiString();
cout << traceStr << endl;
// *SqlParser_Diags << DgSqlCode(3066) // kludge to print trace message
// << DgString0(traceStr);
}
#endif
return TRUE;
}
return FALSE; // does nothing
}
// -----------------------------------------------------------------------
// Definitions of non-inline methods of class ParViewColTableColsUsage
// -----------------------------------------------------------------------
//
// constructors
//
ParViewColTableColsUsage::ParViewColTableColsUsage(CollHeap * h)
: usingViewColumnNumber_(0),
usedObjectColumnName_(h)
{}
ParViewColTableColsUsage::ParViewColTableColsUsage(
const CollIndex usingViewColumnNumber,
const ColRefName &usedObjectColumnName,
CollHeap * h)
: usingViewColumnNumber_(usingViewColumnNumber),
usedObjectColumnName_(usedObjectColumnName, h)
{}
//
// virtual destructor
//
ParViewColTableColsUsage::~ParViewColTableColsUsage()
{
}
//
// operator
//
NABoolean
ParViewColTableColsUsage::operator==(const ParViewColTableColsUsage &rhs) const
{
if (this EQU &rhs)
{
return TRUE;
}
return (getUsingViewColumnNumber() EQU rhs.getUsingViewColumnNumber() AND
getUsedObjectColumnName() EQU rhs.getUsedObjectColumnName());
}
// -----------------------------------------------------------------------
// Definitions of non-inline methods of class ParViewColTableColsUsageList
// -----------------------------------------------------------------------
//
// constructor
//
ParViewColTableColsUsageList::ParViewColTableColsUsageList(CollHeap *heap)
: LIST(ParViewColTableColsUsage *)(heap),
heap_(heap)
{
}
//
// virtual destructor
//
ParViewColTableColsUsageList::~ParViewColTableColsUsageList()
{
for (CollIndex i = 0; i < entries(); i++)
{
delete &operator[](i);
// NADELETE(&operator[](i), ParViewColTableColsUsage, heap_);
}
}
//
// accessors
//
ParViewColTableColsUsage * const
ParViewColTableColsUsageList::find(const CollIndex usingViewColNum)
{
for (CollIndex i = 0; i < entries(); i++)
{
if (operator[](i).getUsingViewColumnNumber() EQU usingViewColNum)
{
return &operator[](i);
}
}
return NULL;
}
ParViewColTableColsUsage * const
ParViewColTableColsUsageList::find(const CollIndex usingViewColNum,
const ColRefName &usedColRefName)
{
for (CollIndex i = 0; i < entries(); i++)
{
ParViewColTableColsUsage *const u = &(operator[](i));
const ColRefName &uColRefName = u->getUsedObjectColumnName();
if (u->getUsingViewColumnNumber() EQU usingViewColNum AND
uColRefName.getCorrNameObj().getQualifiedNameObj() EQU
usedColRefName.getCorrNameObj().getQualifiedNameObj() AND
uColRefName.getColName() EQU usedColRefName.getColName())
{
return u;
}
}
return NULL;
}
const CollIndex
ParViewColTableColsUsageList::getIndex(const CollIndex usingViewColNum) const
{
for (CollIndex i = 0; i < entries(); i++)
{
if (operator[](i).getUsingViewColumnNumber() EQU usingViewColNum)
{
return i;
}
}
return NULL_COLL_INDEX;
}
const CollIndex
ParViewColTableColsUsageList::getIndexOfNextElem(const CollIndex
usingViewColNum) const
{
for (CollIndex i = 0; i < entries(); i++)
{
if (operator[](i).getUsingViewColumnNumber() > usingViewColNum)
{
return i;
}
}
return NULL_COLL_INDEX;
}
//
// mutators
//
void
ParViewColTableColsUsageList::clear()
{
ParViewColTableColsUsage *temp1;
for (CollIndex i = 0; i < entries(); i++)
{
// NADELETE(&operator[](i), ParViewColTableColsUsage, heap_);
//#define NADELETE(p,C,h) \
temp1 = &operator[](i);
if (temp1)
{
if (heap_)
{
delete temp1;
// (temp1)->~ParViewColTableColsUsage();
// (heap_)->deallocateMemory((void*)temp1);
}
else
{
(delete (ParViewColTableColsUsage *)temp1);
}
}
#if 0
(void) (!(&operator[](i))
||
(
(
(h) ?
((&operator[](i))->~ParViewColTableColsUsage(), (heap_)->deallocateMemory((void*)&operator[](i)))
:
(delete (void*)&operator[](i))
),
0
)
)
#endif // 0
}
LIST(ParViewColTableColsUsage *)::clear();
}
NABoolean
ParViewColTableColsUsageList::insert(const CollIndex usingViewColumnNumber,
const ColRefName &usedObjectColumnName)
{
ParViewColTableColsUsage *vctcu = find(usingViewColumnNumber);
if (vctcu EQU NULL OR // not found
find(usingViewColumnNumber,
usedObjectColumnName) EQU NULL)
{
// ok to insert
ParViewColTableColsUsage *u = new(heap_)
ParViewColTableColsUsage(usingViewColumnNumber, usedObjectColumnName);
CMPASSERT(u NEQ NULL);
if (vctcu NEQ NULL) // more than 1 elem. with same usingViewColumnNumber
{
LIST(ParViewColTableColsUsage *)::insertAt(
getIndex(usingViewColumnNumber), u);
}
else
{
CollIndex iOfNextElem(getIndexOfNextElem(usingViewColumnNumber));
if (iOfNextElem EQU NULL_COLL_INDEX) // usingViewColumnNumber is biggest
{
LIST(ParViewColTableColsUsage *)::insert(u); // append to end of list
}
else
{
LIST(ParViewColTableColsUsage *)::insertAt(iOfNextElem, u);
}
}
#ifndef NDEBUG
if (ParIsTracingViewUsages())
{
NAString traceStr = "vctcu: " +
LongToNAString((Lng32)usingViewColumnNumber) +
" " +
usedObjectColumnName.getCorrNameObj().
getQualifiedNameObj().getQualifiedNameAsAnsiString()
+ "." +
ToAnsiIdentifier(usedObjectColumnName.getColName());
cout << traceStr << endl;
// *SqlParser_Diags << DgSqlCode(3066) // kludge to print trace message
// << DgString0(traceStr);
}
#endif
return TRUE;
}
return FALSE;
}
// -----------------------------------------------------------------------
// Definitions of non-inline methods of class ParViewUsages
// -----------------------------------------------------------------------
//
// constructor
//
ParViewUsages::ParViewUsages(CollHeap *heap)
: curViewColNum_(NULL_COLL_INDEX),
isItmColRefInColInRowVals_(FALSE),
isViewSurelyNotUpdatable_(FALSE),
usedTableNameList_(heap),
usedColRefList_(heap),
viewColTablesUsageList_(heap),
viewColTableColsUsageList_(heap)
{
}
//
// virtual destructor
//
ParViewUsages::~ParViewUsages()
{
}
const ParViewColTableColsUsageList &
ParViewUsages::getViewColTableColsUsageList() const
{
return viewColTableColsUsageList_;
}
ParViewColTableColsUsageList &
ParViewUsages::getViewColTableColsUsageList()
{
return viewColTableColsUsageList_;
}
// -----------------------------------------------------------------------
// Methods for class StmtDDLCreateSynonym
// -----------------------------------------------------------------------
//
// Constructor
//
StmtDDLCreateSynonym::StmtDDLCreateSynonym(const QualifiedName & synonymName,
const QualifiedName & objectReference,
ElemDDLNode *pOwner)
: StmtDDLNode(DDL_CREATE_SYNONYM),
synonymName_(synonymName, PARSERHEAP()),
objectReference_(objectReference, PARSERHEAP())
{
if (pOwner)
{
pOwner_ = pOwner->castToElemDDLGrantee();
ComASSERT(pOwner_ NEQ NULL);
}
else
pOwner_ = NULL;
}
//
// Virtual Destructor
// garbage collection is being done automatically by the NAString Class
//
StmtDDLCreateSynonym::~StmtDDLCreateSynonym()
{
if (pOwner_)
delete pOwner_;
}
//
// cast
//
StmtDDLCreateSynonym *
StmtDDLCreateSynonym::castToStmtDDLCreateSynonym()
{
return this;
}
//
// mutators
//
//
// for tracing
//
const NAString
StmtDDLCreateSynonym::displayLabel1() const
{
return NAString("Synonym name: " ) + getSynonymName();
}
const NAString
StmtDDLCreateSynonym::displayLabel2() const
{
return NAString("Object Reference: ") + getObjectReference();
}
const NAString
StmtDDLCreateSynonym::getText() const
{
return "StmtDDLCreateSynonym";
}
// -----------------------------------------------------------------------
// Methods for class StmtDDLCreateExceptionTable
// -----------------------------------------------------------------------
//
// Constructor
//
StmtDDLCreateExceptionTable::StmtDDLCreateExceptionTable(const QualifiedName & exceptionName,
const QualifiedName & objectReference)
: StmtDDLNode(DDL_CREATE_EXCEPTION_TABLE),
exceptionName_(exceptionName, PARSERHEAP()),
objectReference_(objectReference, PARSERHEAP())
{
}
//
// Virtual Destructor
// garbage collection is being done automatically by the NAString Class
//
StmtDDLCreateExceptionTable::~StmtDDLCreateExceptionTable()
{}
//
// cast
//
StmtDDLCreateExceptionTable *
StmtDDLCreateExceptionTable::castToStmtDDLCreateExceptionTable()
{
return this;
}
//
// for tracing
//
const NAString
StmtDDLCreateExceptionTable::displayLabel1() const
{
return NAString("Exception table name: " ) + getExceptionName();
}
const NAString
StmtDDLCreateExceptionTable::displayLabel2() const
{
return NAString("Object Reference: ") + getObjectReference();
}
const NAString
StmtDDLCreateExceptionTable::getText() const
{
return "StmtDDLCreateExceptionTable";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateCatalog
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateCatalog::StmtDDLCreateCatalog(const NAString & aCatalogName,
ElemDDLNode * pAttributeList)
: StmtDDLNode(DDL_CREATE_CATALOG),
catalogName_(aCatalogName, PARSERHEAP()),
isLocationClauseSpec_(FALSE),
locationName_(PARSERHEAP()),
locationNameInputFormat_(ComLocationName::INPUT_NOT_SPECIFIED),
locationNameType_(ElemDDLLocation::LOCATION_DEFAULT_NAME_TYPE),
pLocationNode_(NULL),
attributeList_(pAttributeList)
{
//
// Traverse the Create Catalog Attribute List sub-tree tp
// look for specified attributes. Set the corresponding data
// members accordingly. Also check for duplicate clauses.
//
if (pAttributeList NEQ NULL)
{
for (CollIndex i = 0; i < pAttributeList->entries(); i++)
{
setAttribute((*pAttributeList)[i]);
}
}
} // StmtDDLCreateCatalog::StmtDDLCreateCatalog()
//
// virtual destructor
//
StmtDDLCreateCatalog::~StmtDDLCreateCatalog()
{
// delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
}
//
// cast
//
StmtDDLCreateCatalog *
StmtDDLCreateCatalog::castToStmtDDLCreateCatalog()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateCatalog::getArity() const
{
return MAX_STMT_DDL_CREATE_CATALOG_ARITY;
}
ExprNode *
StmtDDLCreateCatalog::getChild(Lng32 index)
{
ComASSERT(index EQU INDEX_CREATE_CATALOG_ATTRIBUTE_LIST);
return attributeList_;
}
//
// mutators
//
void
StmtDDLCreateCatalog::setChild(Lng32 index, ExprNode * pChildNode)
{
ComASSERT(index EQU INDEX_CREATE_CATALOG_ATTRIBUTE_LIST);
if (pChildNode NEQ NULL)
{
attributeList_ = pChildNode->castToElemDDLNode();
}
else
{
attributeList_ = NULL;
}
}
//
// Get the information in the parse node pointed by parameter
// pAttrNode. Update the corresponding data members (in this
// class) accordingly. Also check for duplicate clauses.
//
void
StmtDDLCreateCatalog::setAttribute(ElemDDLNode * pAttrNode)
{
ComASSERT(pAttrNode NEQ NULL);
//
// Currently, the Create Catalog statement accepts only
// one optional clause, the Location clause.
//
if (pAttrNode->castToElemDDLLocation() NEQ NULL)
{
//
// Location clause was specified
//
if (isLocationClauseSpec_)
{
// Duplicate LOCATION clauses.
*SqlParser_Diags << DgSqlCode(-3098);
}
//
// Does not need to check the syntax of the specified location
// name. The constructor of class ElemDDLLocation has already
// done that.
//
// Copies the information about the location name to this
// node for easier access.
//
ElemDDLLocation * pLocation = pAttrNode->castToElemDDLLocation();
ComASSERT(pLocation NEQ NULL);
if (NOT pLocation->getPartitionName().isNull())
*SqlParser_Diags << DgSqlCode(-3405);
isLocationClauseSpec_ = TRUE;
locationName_ = pLocation->getLocationName();
locationNameInputFormat_ = pLocation->getLocationNameInputFormat();
locationNameType_ = pLocation->getLocationNameType();
pLocationNode_ = pLocation;
}
else
{
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
}
}
//
// methods for tracing
//
const NAString
StmtDDLCreateCatalog::displayLabel1() const
{
return NAString("Catalog name: ") + getCatalogName();
}
const NAString
StmtDDLCreateCatalog::displayLabel2() const
{
if (NOT getLocationName().isNull())
{
return NAString("Location name: ") + getLocationName();
}
else
{
return NAString("Location name not specified.");
}
}
const NAString
StmtDDLCreateCatalog::displayLabel3() const
{
if (NOT getLocationName().isNull())
{
ElemDDLLocation location(getLocationNameType(), getLocationName());
return (NAString("Location name type: ") +
location.getLocationNameTypeAsNAString());
}
else
{
return NAString();
}
}
const NAString
StmtDDLCreateCatalog::getText() const
{
return "StmtDDLCreateCatalog";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateComponentPrivilege
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateComponentPrivilege::StmtDDLCreateComponentPrivilege(
const NAString & aComponentPrivilegeName,
const NAString & aComponentPrivilegeAbbreviation,
const NAString & aComponentName,
const NABoolean isSystem,
const NAString & aComponentPrivilegeDetailInformation,
CollHeap * heap) // default is PARSERHEAP()
: StmtDDLNode(DDL_CREATE_COMPONENT_PRIVILEGE),
componentPrivilegeName_(aComponentPrivilegeName, heap),
componentPrivilegeAbbreviation_(aComponentPrivilegeAbbreviation, heap),
componentName_(aComponentName, heap),
isSystem_(isSystem),
componentPrivilegeDetailInformation_(aComponentPrivilegeDetailInformation, heap)
{
}
//
// virtual destructor
//
StmtDDLCreateComponentPrivilege::~StmtDDLCreateComponentPrivilege()
{
}
//
// virtual safe cast-down function
//
StmtDDLCreateComponentPrivilege *
StmtDDLCreateComponentPrivilege::castToStmtDDLCreateComponentPrivilege()
{
return this;
}
//
// methods for tracing
//
const NAString
StmtDDLCreateComponentPrivilege::displayLabel1() const
{
NAString aLabel("Component privilege name: ");
aLabel += getComponentPrivilegeName();
aLabel += " - Component privilege abbreviation: ";
aLabel += getComponentPrivilegeAbbreviation();
return aLabel;
}
const NAString
StmtDDLCreateComponentPrivilege::displayLabel2() const
{
NAString aLabel("Component name: ");
aLabel += getComponentName();
if (isSystem_)
{
aLabel += " (SYSTEM)";
}
aLabel += " - Component privilege detail information: ";
aLabel += getComponentPrivilegeDetailInformation();
return aLabel;
}
const NAString
StmtDDLCreateComponentPrivilege::getText() const
{
return "StmtDDLCreateComponentPrivilege";
}
//----------------------------------------------------------------------------
// MV - RG (refresh groups)
// ---------------------------------------------------------------------------
// methods for class StmtDDLCreateMvRGroup - refresh groups
// ---------------------------------------------------------------------------
// initialize constructor
StmtDDLCreateMvRGroup::StmtDDLCreateMvRGroup(
const QualifiedName & mvRGroupName,
CollHeap * heap )
:StmtDDLNode(DDL_CREATE_MV_REFRESH_GROUP),
mvRGroupQualName_(mvRGroupName, heap) //,
// mvRGroupName_(mvRGroupQualName_.getQualifiedNameAsAnsiString())
{
// XXXXXXXXXMVSXXXXXXXXXXXXXXX
}
// virtual destructor
StmtDDLCreateMvRGroup::~StmtDDLCreateMvRGroup()
{
}
// cast
StmtDDLCreateMvRGroup *
StmtDDLCreateMvRGroup::castToStmtDDLCreateMvRGroup()
{
return this;
}
const NAString
StmtDDLCreateMvRGroup::displayLabel1() const
{
return NAString("MV name: ") + getMvRGroupName();
}
const NAString
StmtDDLCreateMvRGroup::getText() const
{
return "StmtDDLCreateMvRGroup";
}
/**********************************************************/
/**** B E G I N ****/
/**********************************************************/
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateTrigger
// -----------------------------------------------------------------------
// Constructor
StmtDDLCreateTrigger::StmtDDLCreateTrigger(
const QualifiedName & aTriggerName,
ParNameLocList * nameLocList,
NABoolean isAfter,
NABoolean hasRowOrTableInRefClause,
ComOperation iud_event,
ElemDDLNode * columnList,
const QualifiedName & aTableName,
NAString * oldName,
NAString * newName,
NABoolean isStatement,
ElemDDLNode * pOwner,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_TRIGGER),
triggerQualName_(aTriggerName, heap),
nameLocListPtr_(nameLocList), // copy ptr
startPos_(nameLocList->getTextStartPosition()),
endPos_(0), // will be set during parsing by ParSetTextEndPos()
isAfter_(isAfter),
hasCSInAction_(FALSE),
hasRowORTableInRefClause_(hasRowOrTableInRefClause),
iudEvent_(iud_event),
tableQualName_(aTableName, heap),
isStatement_(isStatement),
oldName_(oldName),
newName_(newName),
pActionExpression_(NULL), // Initialize to NULL, set it later
pColumnList_(NULL),
columnRefArray_(heap)
{
setChild(TRIGGER_OPTIONAL_UPDATE_COLUMN_LIST, columnList);
setChild(TRIGGER_OPTIONAL_OWNER, pOwner);
// set the other child (action tree) later !!
}
// "patch" the create trigger node -- add the action tree
// (done after the ctor for StmtDDLCreateTrigger -- cause the parsing of the
// action uses the StmtDDLCreateTrigger object to get the referencing info)
void StmtDDLCreateTrigger::setAction( RelExpr * actionExpression )
{
setChild(TRIGGER_ACTION_EXPRESSION, actionExpression );
}
//
// virtual destructor
//
StmtDDLCreateTrigger::~StmtDDLCreateTrigger()
{
// delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
// delete the name loc list
if ( nameLocListPtr_ NEQ NULL) delete nameLocListPtr_ ;
// delete the old/new strings
if ( oldName_ ) delete oldName_ ;
if ( newName_ ) delete newName_ ;
}
//
// cast virtual function
//
StmtDDLCreateTrigger *
StmtDDLCreateTrigger::castToStmtDDLCreateTrigger()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateTrigger::getArity() const
{
return MAX_STMT_DDL_CREATE_TRIGGER_ARITY;
}
ExprNode *
StmtDDLCreateTrigger::getChild(Lng32 index)
{
ComASSERT(index >= 0 AND index < getArity());
switch (index)
{
case TRIGGER_OPTIONAL_UPDATE_COLUMN_LIST :
return pColumnList_;
case TRIGGER_ACTION_EXPRESSION :
return pActionExpression_ ;
case TRIGGER_OPTIONAL_OWNER :
return pOwner_;
default : // can't be 'cause index was checked ...
ABORT("internal logic error");
break ;
}
return NULL; // for the compiler's peace of mind; can't be anyway ...
}
//
// mutators
//
void
StmtDDLCreateTrigger::setChild(Lng32 index, ExprNode * pChildNode)
{
ComASSERT(index >= 0 AND index < getArity());
switch (index) {
case TRIGGER_OPTIONAL_UPDATE_COLUMN_LIST :
if (pChildNode NEQ NULL) {
pColumnList_ = pChildNode->castToElemDDLNode();
ComASSERT(pColumnList_ NEQ NULL);
}
else pColumnList_ = NULL;
break;
case TRIGGER_ACTION_EXPRESSION :
if (pChildNode NEQ NULL) {
pActionExpression_ = pChildNode->castToRelExpr();
ComASSERT(pActionExpression_ NEQ NULL);
}
else pActionExpression_ = NULL;
break;
case TRIGGER_OPTIONAL_OWNER:
if (pChildNode NEQ NULL) {
ElemDDLNode *pTemp = pChildNode->castToElemDDLNode();
ComASSERT(pTemp NEQ NULL);
ElemDDLGrantee *pOwner = pTemp->castToElemDDLGrantee();
ComASSERT(pOwner NEQ NULL);
pOwner_ = pOwner;
}
else pOwner_ = NULL;
break;
default : // can't be 'cause index was checked ...
ABORT("internal logic error");
}
}
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLCreateTrigger::synthesize()
{
ExprNode * columnList = getChild(TRIGGER_OPTIONAL_UPDATE_COLUMN_LIST) ;
if ( columnList NEQ NULL ) { // In case there are (update) columns defined
ComASSERT( getIUDEvent() EQU COM_UPDATE ) ; // only update can have cols
ElemDDLNode *pColumnList = columnList->castToElemDDLNode();
ComASSERT( pColumnList NEQ NULL ) ;
//
// Initialize columnRefArray_ so the user can access
// the information in the Column Reference parse nodes
// easier.
//
CollIndex i;
CollIndex nbrColList = pColumnList->entries();
for (i = 0; i < nbrColList; i++) {
ElemDDLColRef *nextElem = (*pColumnList)[i]->castToElemDDLColRef() ;
ComASSERT( nextElem NEQ NULL);
columnRefArray_.insert( nextElem );
}
} // if
} // StmtDDLCreateTrigger::synthesize()
//
// methods for tracing
//
const NAString
StmtDDLCreateTrigger::displayLabel1() const
{
return NAString("Trigger name: ") + getTriggerName();
}
const NAString
StmtDDLCreateTrigger::displayLabel2() const
{
return NAString("Table name: ") + getTableName();
}
NATraceList
StmtDDLCreateTrigger::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
detailText = "Trigger name: ";
detailText += getTriggerName();
detailTextList.append(detailText);
detailText = "Table name: ";
detailText += getTableName();
detailTextList.append(detailText);
CollIndex i, nbrCols;
ElemDDLColRefArray colsList;
ElemDDLColRef * col;
colsList = getColRefArray();
nbrCols = colsList.entries();
if (nbrCols EQU 0)
{
detailTextList.append("No columns.");
}
else
{
detailText = "Column list [";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " column(s)]:";
detailTextList.append(detailText);
for (i = 0; i < nbrCols; i++)
{
col = colsList[i];
detailText = "[column ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", col->getDetailInfo());
}
} // else (nbrCols EQU 0) of column references
//
// miscellaneous options
//
detailText = "is After? ";
detailText += YesNo(isAfter());
detailTextList.append(detailText);
detailText = "is Statement? ";
detailText += YesNo(isStatement());
detailTextList.append(detailText);
return detailTextList;
} // StmtDDLCreateTrigger::getDetailInfo()
const NAString
StmtDDLCreateTrigger::getText() const
{
return "StmtDDLCreateTrigger";
}
/**********************************************************/
/**** E N D ****/
/**********************************************************/
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateIndex
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateIndex::StmtDDLCreateIndex(NABoolean isUnique,
const NAString & anIndexName,
const QualifiedName & aTableName,
ElemDDLNode * pColumnList,
NABoolean posIgnore,
ElemDDLNode * pOptionList,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_INDEX),
isUnique_(isUnique),
indexName_(anIndexName, heap),
indexQualName_(heap),
origTableQualName_(heap),
tableQualName_(aTableName, heap),
locationName_(heap),
partitionName_(heap),
isLocationClauseSpec_(FALSE),
locationNameType_(ElemDDLLocation::LOCATION_DEFAULT_NAME_TYPE),
partitioningScheme_ (COM_NO_PARTITIONING),
guardianLocation_(heap),
isPartitionClauseSpec_(FALSE),
isPartitionByClauseSpec_(FALSE),
isDivisionClauseSpec_(FALSE),
pDivisionClauseParseNode_(NULL),
isHbaseOptionsSpec_(FALSE),
pHbaseOptionsParseNode_(NULL),
pSaltOptions_(NULL),
isParallelExec_(FALSE),
configFileName_(heap),
isParallelExecutionClauseSpec_(FALSE),
isAttributeClauseSpec_(FALSE),
pPrimaryPartition_(NULL),
columnRefArray_(heap),
partitionArray_(heap),
partitionKeyColRefArray_(heap),
isPopulated_(TRUE), // default is always populated.
isNoPopulated_(FALSE),
populateCount_(0),
noPopulateCount_(0),
isIndexOnGhostTable_(FALSE),
posIgnore_(posIgnore),
isNumRowsSpecified_(FALSE),
numRows_(-1)
{
setChild(INDEX_COLUMN_REF_LIST, pColumnList);
setChild(INDEX_OPTION_LIST, pOptionList);
}
//
// virtual destructor
//
StmtDDLCreateIndex::~StmtDDLCreateIndex()
{
// Delete the Primary Partition parse node. This parse node
// is not part of the parse tree. The former was created
// during the construction of the Create Index parse node
// (this object).
delete pPrimaryPartition_;
// delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
}
//
// cast virtual function
//
StmtDDLCreateIndex *
StmtDDLCreateIndex::castToStmtDDLCreateIndex()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateIndex::getArity() const
{
return MAX_STMT_DDL_CREATE_INDEX_ARITY;
}
ExprNode *
StmtDDLCreateIndex::getChild(Lng32 index)
{
ComASSERT(index >= 0 AND index < getArity());
return children_[index];
}
const NAString
StmtDDLCreateIndex::getTableName() const
{
return tableQualName_.getQualifiedNameAsAnsiString();
}
//
// mutators
//
void
StmtDDLCreateIndex::setChild(Lng32 index, ExprNode * pChildNode)
{
ComASSERT(index >= 0 AND index < getArity());
if (pChildNode EQU NULL)
{
children_[index] = NULL;
}
else
{
children_[index] = pChildNode->castToElemDDLNode();
}
}
//
// Copies information in the specified file attributes clause
// to the data member fileAttributes_.
//
void
StmtDDLCreateIndex::setFileAttributes(ElemDDLFileAttrClause * pFileAttrClause)
{
ComASSERT(pFileAttrClause NEQ NULL);
if (isAttributeClauseSpec_)
{
// Duplicate file ATTRIBUTE(S) clauses.
*SqlParser_Diags << DgSqlCode(-3099);
}
isAttributeClauseSpec_ = TRUE;
ElemDDLNode * pFileAttrs = pFileAttrClause->getFileAttrDefBody();
ComASSERT(pFileAttrs NEQ NULL);
for (CollIndex i = 0; i < pFileAttrs->entries(); i++)
{
getFileAttributes().setFileAttr((*pFileAttrs)[i]->castToElemDDLFileAttr());
}
} // StmtDDLCreateIndex::setFileAttributes()
void
StmtDDLCreateIndex::setIndexOption(ElemDDLNode * pIndexOption)
{
switch (pIndexOption->getOperatorType())
{
case ELM_FILE_ATTR_CLAUSE_ELEM :
setFileAttributes(pIndexOption->castToElemDDLFileAttrClause());
break;
case ELM_LOCATION_ELEM :
//
// Currently, Location clause only contains one location element
// (represented by class ElemDDLLocation); therefore, there is no
// need to define class ElemDDLLocationClause to check for duplicate
// Location clauses.
//
ComASSERT(pIndexOption->castToElemDDLLocation() NEQ NULL);
if (isLocationClauseSpec_)
{
// Duplicate LOCATION clauses.
*SqlParser_Diags << DgSqlCode(-3098);
}
isLocationClauseSpec_ = TRUE;
{
ElemDDLLocation * pLocation = pIndexOption->castToElemDDLLocation();
locationName_ = pLocation->getLocationName();
locationNameType_ = pLocation->getLocationNameType();
partitionName_ = pLocation->getPartitionName();
}
break;
case ELM_WITH_POPULATE_OPTION_ELEM :
{
ElemDDLIndexPopulateOption * pPopulateIndex = pIndexOption->castToElemDDLIndexPopulateOption();
//10-030303-4626-begin
populateCount_ += pPopulateIndex->getPopulateOptionCount();
noPopulateCount_ += pPopulateIndex->getNoPopulateOptionCount();
if((populateCount_ >= 1) && (noPopulateCount_ >= 1))
{
//10-030303-4626-end
// Error message. Populate and no populate can't coexist in the same clause.
*SqlParser_Diags << DgSqlCode (-3155);
}
else
{
//10-030303-4626-begin
if((populateCount_ > 1) || (noPopulateCount_ > 1))
{
// Error message. Mutiple Populate OR No Populate
// can't exist in the same clause.
*SqlParser_Diags << DgSqlCode (-3183) << DgString0(" [NO] POPULATE ");
}
else
{
// No Syntax errors.
isNoPopulated_ = pPopulateIndex->getNoPopulateOption();
isPopulated_ = pPopulateIndex->getPopulateOption();
}
//10-030303-4626-end
}
}
break;
case ELM_PARTITION_CLAUSE_ELEM :
setPartitions(pIndexOption->castToElemDDLPartitionClause());
break;
case ELM_DIVISION_CLAUSE_ELEM :
ComASSERT(pIndexOption->castToElemDDLDivisionClause() NEQ NULL);
if (isDivisionClauseSpecified())
{
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("DIVISION");
}
pDivisionClauseParseNode_ =
pIndexOption->castToElemDDLDivisionClause();
isDivisionClauseSpec_ = TRUE;
break;
case ELM_PARALLEL_EXEC_ELEM :
{
ElemDDLParallelExec * pParallelExec =
pIndexOption->castToElemDDLParallelExec();
ComASSERT(pParallelExec NEQ NULL);
if (isParallelExecutionClauseSpecified())
{
// Duplicate PARALLEL EXECUTION clauses.
*SqlParser_Diags << DgSqlCode(-3102);
}
isParallelExecutionClauseSpec_ = TRUE;
configFileName_ = pParallelExec->getConfigFileName();
isParallelExec_ = pParallelExec->isParallelExecEnabled();
}
break;
case ELM_FILE_ATTR_POS_TABLE_SIZE_ELEM:
{
if (pIndexOption->castToElemDDLFileAttrPOSTableSize()->getNumRows() != -1)
{
if (isNumRowsSpecified_)
{
// Duplicate phrases.
*SqlParser_Diags << DgSqlCode(-3407);
}
numRows_ =
pIndexOption->castToElemDDLFileAttrPOSTableSize()->getNumRows();
isNumRowsSpecified_ = TRUE;
}
}
break;
case ELM_HBASE_OPTIONS_ELEM:
{
if (isHbaseOptionsSpecified())
{
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("HBASE_OPTIONS");
}
pHbaseOptionsParseNode_ =
pIndexOption->castToElemDDLHbaseOptions();
isHbaseOptionsSpec_ = TRUE;
}
break ;
case ELM_SALT_OPTIONS_ELEM:
{
if (pSaltOptions_)
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183) << DgString0("SALT");
else
pSaltOptions_ = pIndexOption->castToElemDDLSaltOptionsClause();
}
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
}
}
//
// Copies the information in the specified Partition clause
// to this object.
//
void
StmtDDLCreateIndex::setPartitions(ElemDDLPartitionClause * pPartitionClause)
{
ComASSERT(pPartitionClause NEQ NULL);
if (isPartitionSpecified())
{
// Duplicate PARTITION clauses.
*SqlParser_Diags << DgSqlCode(-3103);
}
isPartitionClauseSpec_ = TRUE;
//
// Initializes pPartitions to point to the parse node representing
// the definition of a partition (class ElemDDLPartition) or
// a list of partition definitions (class ElemDDLPartitionList).
//
ElemDDLNode * pPartitions = pPartitionClause->getPartitionDefBody();
//
// Copy the partitioning type from the partition clause
//
partitioningScheme_ = pPartitionClause->getPartitionType();
//
// Constructs the primary partition node and then inserts
// its pointer at the beginning of the partitionArray_.
//
// Note that the partition clause does not include the
// definition of the primary partition.
//
// The kind of the primary partition node must be the
// same as that of the secondary partition node.
//
// Note that for indexes with only a single partition,
// pPartitions contains the NULL pointer value.
//
if (pPartitions EQU NULL)
setPrimaryPartition(NULL);
else
// (*pPartitions)[0] points to the parse node
// representing the first secondary partition.
setPrimaryPartition((*pPartitions)[0]);
//
// Scans the list of the definitions of the secondary
// partition. Copies the information to the partitionArray_.
//
if (pPartitions NEQ NULL)
for (CollIndex i = 0; i < pPartitions->entries(); i++)
{
setSecondaryPartition((*pPartitions)[i]->castToElemDDLPartition());
}
//
// Initializes pPartitionByOption to point to the parse node
// representing the definition of partition by columns (class
// ElemDDLPartitionByOpt).
//
ElemDDLNode *pPartitionByOption = pPartitionClause->getPartitionByOption();
if(pPartitionByOption NEQ NULL)
{
// If the Partition By Option is specified, set the flag and copy
// the pointers to column parse nodes to partitionKeyColRefArray_.
if(pPartitionByOption->castToElemDDLPartitionByOpt() NEQ NULL)
{
isPartitionByClauseSpec_ = TRUE;
switch (pPartitionByOption->getOperatorType())
{
case ELM_PARTITION_BY_COLUMN_LIST_ELEM :
ComASSERT(pPartitionByOption->castToElemDDLPartitionByColumnList()
NEQ NULL);
{
//
// Copies array of pointers pointing to Column parse nodes to
// PartitionKeyColRefArray_ so the user of this object can access
// the information easier.
//
ElemDDLNode * pPartitionByCols = pPartitionByOption->
castToElemDDLPartitionByColumnList()->getPartitionKeyColumnList();
NABoolean columnOrderingSpecified = FALSE;
for (CollIndex index = 0; index < pPartitionByCols->entries(); index++)
{
ComASSERT((*pPartitionByCols)[index]->castToElemDDLColRef() NEQ NULL);
// Report error if ordering was specified for any column.
if ((*pPartitionByCols)[index]->castToElemDDLColRef()->isColumnOrderingSpecified())
{
// It is not allowed to specify ordering for columns of a partitioning key clause.
// Report an error only once for the column list - not for each offending column.
if (NOT columnOrderingSpecified)
{
*SqlParser_Diags << DgSqlCode(-3199)
<< DgString0((*pPartitionByCols)[index]->castToElemDDLColRef()->getColumnName());
columnOrderingSpecified = TRUE;
}
}
partitionKeyColRefArray_.insert(
(*pPartitionByCols)[index]->castToElemDDLColRef());
}
}
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
}
} // if(pPartitionByOption NEQ NULL)
}
//
// Constructs the primary partition node and then inserts its pointer
// at the beginning of the partitionArray_. The kind of the primary
// partition must match that of the secondary partition[s].
//
// This method is only invoked when the partition clause appears.
//
void
StmtDDLCreateIndex::setPrimaryPartition(ElemDDLNode * pFirstSecondaryPartition)
{
if (pFirstSecondaryPartition EQU NULL) // single partition
{
if (getPartitioningScheme() EQU COM_HASH_V1_PARTITIONING ||
getPartitioningScheme() EQU COM_HASH_V2_PARTITIONING)
// The HASH PARTITION or HASH2 PARTITION clause was specified.
pPrimaryPartition_ = new(PARSERHEAP())ElemDDLPartitionSystem();
else
pPrimaryPartition_ = new(PARSERHEAP())ElemDDLPartitionRange();
}
else
switch (pFirstSecondaryPartition->getOperatorType())
{
case ELM_PARTITION_RANGE_ELEM :
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionRange();
break;
case ELM_PARTITION_SYSTEM_ELEM :
// We use ElemDDLPartitionSystem parse node for HASH partitions.
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionSystem();
break;
//
// Other future partitioning schemes
//
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
}
partitionArray_.insert(pPrimaryPartition_);
}
void
StmtDDLCreateIndex::setSecondaryPartition(ElemDDLPartition * pPartition)
{
ComASSERT(pPartition NEQ NULL);
//
// Inserts the specified secondary partition node to the end
// of the partitionArray_. Note that secondary partitions
// are defined in the partition clause.
//
switch (pPartition->getOperatorType())
{
case ELM_PARTITION_RANGE_ELEM :
case ELM_PARTITION_SYSTEM_ELEM :
//
// Note that class ElemDDLPartitionRange is derived
// from class ElemDDLPartitionSystem, and the latter
// is derived from class ElemDDLPartition.
//
ComASSERT(pPartition->castToElemDDLPartitionSystem() NEQ NULL);
if (pPartition->castToElemDDLPartitionSystem()->getOption()
NEQ ElemDDLPartition::ADD_OPTION)
{
// Only ADD option allowed in PARTITION clause in CREATE TABLE statement.
*SqlParser_Diags << DgSqlCode(-3104);
}
partitionArray_.insert(pPartition->castToElemDDLPartition());
break;
//
// Other future partitioning schemes; e.g., hash partitioning
//
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch (pPartition->getOperatorType())
} // StmtDDLCreateIndex::setSecondaryPartition()
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLCreateIndex::synthesize()
{
indexQualName_ = QualifiedName(getIndexName(),
tableQualName_.getSchemaName(),
tableQualName_.getCatalogName(),
PARSERHEAP());
if (isVolatile())
indexQualName_.setIsVolatile(TRUE);
ComASSERT(getChild(INDEX_COLUMN_REF_LIST) NEQ NULL);
ElemDDLNode *pColumnList =
getChild(INDEX_COLUMN_REF_LIST)->castToElemDDLNode();
ComASSERT(pColumnList NEQ NULL);
//
// Initialize columnRefArray_ so the user can access
// the information in the Column Reference parse nodes
// easier.
//
CollIndex i;
CollIndex nbrColList = pColumnList->entries();
for (i = 0; i < nbrColList; i++)
{
ComASSERT((*pColumnList)[i]->castToElemDDLColRef() NEQ NULL);
columnRefArray_.insert((*pColumnList)[i]->castToElemDDLColRef());
}
//
// Collect information in the Index option parse nodes
// if they exist. An index option can be a file attribute
// or a load option.
//
if (getChild(INDEX_OPTION_LIST) NEQ NULL)
{
ElemDDLNode *pOptionList =
getChild(INDEX_OPTION_LIST)->castToElemDDLNode();
ComASSERT(pOptionList NEQ NULL);
if (pOptionList->castToElemDDLOptionList() NEQ NULL)
{
CollIndex nbrOptList = pOptionList->entries();
for (i = 0; i < nbrOptList; i++)
{
setIndexOption((*pOptionList)[i]);
}
}
else
{
//
// only a single option (which may be an array of file
// attributes) encountered.
//
setIndexOption(pOptionList);
}
}
//
// If partition clause does not appear, the partitionArray_
// is still empty; constructs the primary partition node and
// then inserts its pointer to the array.
//
if (partitionArray_.entries() EQU 0)
{
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionRange();
partitionArray_.insert(pPrimaryPartition_);
}
//
// The information specified in the location clause and
// load option clauses (e.g., dslack and islack) is for
// the primary partition, copy it to the primary partition
// node.
//
// the pRangePart is empty if first key option is ommitted.
// Shall we assert the pRangePart NEQ NULL ? Internal error
// will occur if the user does not specified the first key
// in the create index with partition clause.
// Note that all of the following methods are defined on the ElemDDLPartitionSystem object.
ElemDDLPartitionSystem * pSystemPart =
pPrimaryPartition_->castToElemDDLPartitionSystem();
// ComASSERT(pSystemPart NEQ NULL);
//
// location
//
if (isLocationSpecified())
{
pSystemPart->setLocationName(getLocationName());
pSystemPart->setLocationNameType(getLocationNameType());
pSystemPart->setPartitionName(getPartitionName());
}
//
// file attributes
//
const ParDDLFileAttrsCreateIndex & fileAttrs = getFileAttributes();
if (fileAttrs.isMaxSizeSpecified())
{
pSystemPart->setIsMaxSizeSpecified(fileAttrs.isMaxSizeSpecified());
pSystemPart->setIsMaxSizeUnbounded(fileAttrs.isMaxSizeUnbounded());
pSystemPart->setMaxSize (fileAttrs.getMaxSize());
pSystemPart->setMaxSizeUnit (fileAttrs.getMaxSizeUnit());
}
if (fileAttrs.isExtentSpecified())
{
pSystemPart->setIsExtentSpecified(fileAttrs.isExtentSpecified());
pSystemPart->setPriExt (fileAttrs.getPriExt());
pSystemPart->setSecExt (fileAttrs.getSecExt());
}
if (fileAttrs.isMaxExtentSpecified())
{
pSystemPart->setIsMaxExtentSpecified(fileAttrs.isMaxExtentSpecified());
pSystemPart->setMaxExt (fileAttrs.getMaxExt());
}
//
// Check to see if the index is a range partitioned index.
// If it is then the FIRST-KEY option is required.
//
if (partitionArray_.entries() > 1 ) // PARTITION clause specified
{
for (CollIndex i = 0; i < getPartitionArray().entries(); i++)
if (getPartitionArray()[i]->castToElemDDLPartitionRange() EQU NULL)
{ // FIRST KEY phrase(s) not specified in PARTITION clause
if (partitioningScheme_ NEQ COM_HASH_V1_PARTITIONING && // Range partition requires FIRST KEY
partitioningScheme_ NEQ COM_HASH_V2_PARTITIONING)
{
*SqlParser_Diags << DgSqlCode(-3139);
break;
}
}
else
{
// No FIRST KEY allowed with HASH PARTITION
if (partitioningScheme_ EQU COM_HASH_V1_PARTITIONING ||
partitioningScheme_ EQU COM_HASH_V2_PARTITIONING)
{
*SqlParser_Diags << DgSqlCode(-3153);
break;
}
}
}
} // StmtDDLCreateIndex::synthesize()
//
// methods for tracing
//
const NAString
StmtDDLCreateIndex::displayLabel1() const
{
return NAString("Index name: ") + getIndexName();
}
const NAString
StmtDDLCreateIndex::displayLabel2() const
{
return NAString("Table name: ") + getTableName();
}
NATraceList
StmtDDLCreateIndex::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
detailText = "Index name: ";
detailText += getIndexName();
detailTextList.append(detailText);
detailText = "Table name: ";
detailText += getTableName();
detailTextList.append(detailText);
CollIndex i, nbrCols;
const ElemDDLColRefArray & colsList = getColRefArray();
ElemDDLColRef * col;
nbrCols = colsList.entries();
if (nbrCols EQU 0)
{
detailTextList.append("No columns.");
}
else
{
detailText = "Column list [";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " column(s)]:";
detailTextList.append(detailText);
for (i = 0; i < nbrCols; i++)
{
col = colsList[i];
detailText = "[column ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", col->getDetailInfo());
}
} // else (nbrCols EQU 0) of column references
//
// miscellaneous options
//
detailText = "is unique? ";
detailText += YesNo(isUniqueSpecified());
detailTextList.append(detailText);
//
// file attributes
//
detailTextList.append("File attributes: ");
ParDDLFileAttrsCreateIndex fileAttribs = getFileAttributes();
detailTextList.append(" ", fileAttribs.getDetailInfo());
//
// load options
//
detailTextList.append("Load options: ");
detailText = " par exec spec? ";
detailText += YesNo(isParallelExecutionClauseSpecified());
detailTextList.append(detailText);
detailText = " par exec on? ";
detailText += YesNo(isParallelExecutionEnabled());
detailTextList.append(detailText);
if (isParallelExecutionEnabled())
{
detailText = " config file: ";
detailText += getParallelExecConfigFileName();
detailTextList.append(detailText);
}
//
// partition information
//
CollIndex nbrParts;
const ElemDDLPartitionArray & partsList = getPartitionArray();
ElemDDLPartitionSystem * part;
nbrParts = partsList.entries();
if (nbrParts EQU 0)
{
detailTextList.append("No partitions.");
}
else
{
detailText = "Partition list [";
detailText += LongToNAString((Lng32)nbrParts);
detailText += " partition(s)]: ";
detailTextList.append(detailText);
for (i = 0; i < nbrParts; i++)
{
part = partsList[i]->castToElemDDLPartitionSystem();
if (part EQU NULL)
{
//
// Note that class ElemDDLPartitionRange is
// derived from class ElemDDLPartitionSystem
//
// Only support range and system partitioning.
*SqlParser_Diags << DgSqlCode(-3105) ;
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
}
detailText = "[partition ";
detailText += LongToNAString((Lng32)i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", part->getDetailInfo());
} //for (j = 0; j < nbrParts; j++)
} // else (nbrParts NEQ 0)
return detailTextList;
} // StmtDDLCreateIndex::getDetailInfo()
const NAString
StmtDDLCreateIndex::getText() const
{
return "StmtDDLCreateIndex";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLPopulateIndex
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLPopulateIndex::StmtDDLPopulateIndex(NABoolean populateAll,
NABoolean populateAllUnique,
const NAString & anIndexName,
const QualifiedName & aTableName,
CollHeap * heap)
: StmtDDLNode(DDL_POPULATE_INDEX),
populateAll_(populateAll),
populateAllUnique_(populateAllUnique),
indexName_(anIndexName, heap),
indexQualName_(heap),
origTableQualName_(heap),
tableQualName_(aTableName, heap)
{
}
//
// virtual destructor
//
StmtDDLPopulateIndex::~StmtDDLPopulateIndex()
{
}
//
// cast virtual function
//
StmtDDLPopulateIndex *
StmtDDLPopulateIndex::castToStmtDDLPopulateIndex()
{
return this;
}
//
// accessors
//
Int32
StmtDDLPopulateIndex::getArity() const
{
return 0;
}
ExprNode *
StmtDDLPopulateIndex::getChild(Lng32 index)
{
return NULL;
}
const NAString
StmtDDLPopulateIndex::getTableName() const
{
return tableQualName_.getQualifiedNameAsAnsiString();
}
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLPopulateIndex::synthesize()
{
indexQualName_ = QualifiedName(getIndexName(),
tableQualName_.getSchemaName(),
tableQualName_.getCatalogName(),
PARSERHEAP());
} // StmtDDLPopulateIndex::synthesize()
//
// methods for tracing
//
const NAString
StmtDDLPopulateIndex::displayLabel1() const
{
return NAString("Index name: ") + getIndexName();
}
const NAString
StmtDDLPopulateIndex::displayLabel2() const
{
return NAString("Table name: ") + getTableName();
}
const NAString
StmtDDLPopulateIndex::getText() const
{
return "StmtDDLPopulateIndex";
}
// -----------------------------------------------------------------------
// Methods for class StmtDDLCreateLibrary
// -----------------------------------------------------------------------
//
// Constructor
//
StmtDDLCreateLibrary::StmtDDLCreateLibrary(
NABoolean isSystem,
const QualifiedName & libraryName,
const NAString & libraryFilename,
ElemDDLNode * clientName,
ElemDDLNode * clientFilename,
ElemDDLNode * pOwner,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_LIBRARY),
isSystem_(isSystem),
libraryName_(libraryName,heap),
fileName_(libraryFilename),
clientName_("",heap),
clientFilename_("",heap),
pOwner_(NULL)
{
ElemDDLLibClientName *clientNameNode = NULL;
ElemDDLLibClientFilename *clientFilenameNode = NULL;
if (clientName != NULL)
{
clientNameNode = clientName->castToElemDDLLibClientName();
if (clientNameNode != NULL)
clientName_ = clientNameNode->getClientName();
}
if (clientFilename != NULL)
{
clientFilenameNode = clientFilename->castToElemDDLLibClientFilename();
if (clientFilenameNode != NULL)
clientFilename_ = clientFilenameNode->getFilename();
}
if (pOwner)
{
pOwner_ = pOwner->castToElemDDLGrantee();
ComASSERT(pOwner_ NEQ NULL);
}
else
pOwner_ = NULL;
}
//
// Virtual Destructor
// garbage collection is being done automatically by the NAString Class
//
StmtDDLCreateLibrary::~StmtDDLCreateLibrary()
{
if (pOwner_)
delete pOwner_;
}
//
// cast
//
StmtDDLCreateLibrary *
StmtDDLCreateLibrary::castToStmtDDLCreateLibrary()
{
return this;
}
//
// mutators
//
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLCreateLibrary::synthesize()
{
}
//
// for tracing
//
const NAString
StmtDDLCreateLibrary::displayLabel1() const
{
return NAString("Library name: " ) + getLibraryName();
}
const NAString
StmtDDLCreateLibrary::displayLabel2() const
{
return NAString("Library filename: ") + getLibraryName();
}
const NAString
StmtDDLCreateLibrary::getText() const
{
return "StmtDDLCreateLibrary";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateRoutine
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateRoutine::StmtDDLCreateRoutine(const QualifiedName & aRoutineName,
const QualifiedName & anActionName,
ElemDDLNode * pParamList,
ElemDDLNode * pReturnsList,
ElemDDLNode * pPassThroughParamList,
ElemDDLNode * pOptionList,
ComRoutineType rType,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_ROUTINE),
routineQualName_(aRoutineName, heap),
actionQualName_(anActionName, heap),
routineType_(rType),
isLocationClauseSpec_(FALSE),
locationName_(heap),
locationNameType_(ElemDDLLocation::LOCATION_DEFAULT_NAME_TYPE),
guardianLocation_(heap),
languageType_(COM_UNKNOWN_ROUTINE_LANGUAGE),
languageTypeSpecified_(FALSE),
deterministic_(FALSE),
deterministicSpecified_(FALSE),
sqlAccess_(COM_CONTAINS_SQL),
sqlAccessSpecified_(FALSE),
callOnNull_(TRUE),
callOnNullSpecified_(FALSE),
isolate_(TRUE),
isolateSpecified_(FALSE),
paramStyle_(COM_STYLE_GENERAL),
paramStyleSpecified_(FALSE),
transactionAttributes_(COM_TRANSACTION_REQUIRED),
transactionAttributesSpecified_(FALSE),
finalCall_(FALSE),
finalCallSpecified_(FALSE),
parallelism_(COM_ROUTINE_NO_PARALLELISM),
parallelismSpecified_(FALSE),
maxResults_(0),
maxResultSetsSpecified_(FALSE),
stateAreaSize_(0),
stateAreaSizeSpecified_(FALSE),
udrAttributes_("", heap),
udrAttributesSpecified_(FALSE),
libraryName_("", heap),
libraryNameSpecified_(FALSE),
externalPath_("", heap),
externalPathSpecified_(FALSE),
externalFile_("", heap),
externalName_("", heap),
externalNameSpecified_(FALSE),
pOwner_(NULL),
javaClassName_("", heap),
javaMethodName_("", heap),
javaSignature_("", heap),
paramStyleVersion_(1),
paramStyleVersionSpecified_(FALSE),
initialCpuCost_(-1),
initialCpuCostSpecified_(FALSE),
initialIoCost_(-1),
initialIoCostSpecified_(FALSE),
initialMsgCost_(-1),
initialMsgCostSpecified_(FALSE),
normalCpuCost_(-1),
normalCpuCostSpecified_(FALSE),
normalIoCost_(-1),
normalIoCostSpecified_(FALSE),
normalMsgCost_(-1),
normalMsgCostSpecified_(FALSE),
isUniversal_(FALSE),
isUniversalSpecified_(FALSE),
canCollapse_(FALSE),
canCollapseSpecified_(FALSE),
userVersion_("", heap),
userVersionSpecified_(FALSE),
externalSecurity_(COM_ROUTINE_EXTERNAL_SECURITY_INVOKER),
externalSecuritySpecified_(FALSE),
actionPosition_(-1),
actionPositionSpecified_(FALSE),
executionMode_(COM_ROUTINE_SAFE_EXECUTION),
executionModeSpecified_(FALSE),
uudfParamKindList_(heap),
uudfParamKindListSpecified_(FALSE),
uniqueOutputValues_(heap),
numberOfUniqueOutputValuesSpecified_(FALSE),
specialAttributesText_("", heap),
specialAttributesSpecified_(FALSE),
firstReturnedParamPosWithinParamArray_(-1)
{
setChild(INDEX_ROUTINE_PARAM_LIST, pParamList);
setChild(INDEX_ROUTINE_RETURNS_LIST, pReturnsList);
setChild(INDEX_ROUTINE_PASSTHROUGH_LIST, pPassThroughParamList);
setChild(INDEX_ROUTINE_OPTION_LIST, pOptionList);
setChild(INDEX_ROUTINE_UUDF_PARAM_KIND_LIST, NULL);
if (routineType_ NEQ COM_PROCEDURE_TYPE) // Different default values for UDF
{
paramStyleVersion_ = 1;
deterministic_ = FALSE;
sqlAccess_ = COM_NO_SQL;
transactionAttributes_ = COM_UNKNOWN_ROUTINE_TRANSACTION_ATTRIBUTE;
finalCall_ = TRUE;
parallelism_ = COM_ROUTINE_ANY_PARALLELISM;
stateAreaSize_ = 0; // NO STATE AREA
}
}
//
// virtual destructor
//
StmtDDLCreateRoutine::~StmtDDLCreateRoutine()
{
// delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
if (pOwner_)
delete pOwner_;
}
//
// cast virtual function
//
StmtDDLCreateRoutine *
StmtDDLCreateRoutine::castToStmtDDLCreateRoutine()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateRoutine::getArity() const
{
return MAX_STMT_DDL_CREATE_ROUTINE_ARITY;
}
ExprNode *
StmtDDLCreateRoutine::getChild(Lng32 index)
{
ComASSERT(index >= 0 AND index < getArity());
return children_[index];
}
//
// mutators
//
void
StmtDDLCreateRoutine::setChild(Lng32 index, ExprNode * pChildNode)
{
ComASSERT(index >= 0 AND index < getArity());
if (pChildNode EQU NULL)
{
children_[index] = NULL;
}
else
{
children_[index] = pChildNode->castToElemDDLNode();
}
}
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLCreateRoutine::synthesize()
{
switch (getRoutineType())
{
case COM_PROCEDURE_TYPE:
routineQualName_.setObjectNameSpace(COM_TABLE_NAME);
break;
case COM_ACTION_UDF_TYPE:
routineQualName_.setObjectNameSpace(COM_UDF_NAME);
actionQualName_.setObjectNameSpace(COM_UUDF_ACTION_NAME);
break;
case COM_TABLE_UDF_TYPE:
routineQualName_.setObjectNameSpace(COM_TABLE_NAME);
break;
default:
//
// Note that getRoutineType() returns COM_UNKNOWN_ROUTINE_TYPE for the
// ALTER FUNCTION statement case. The catman/CatExecAlterRoutine layer
// will look up the information from the metadata tables to determine
// whether the function is a scalar and universal function.
//
routineQualName_.setObjectNameSpace(COM_UDF_NAME);
break;
}
if (getChild(INDEX_ROUTINE_PARAM_LIST) NEQ NULL)
{
if (getRoutineType() EQU COM_UNIVERSAL_UDF_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3260);
// Do not have to exit/return here.
// Continue so we can do as much checking as possible.
}
else
{
ElemDDLNode *pParamList =
getChild(INDEX_ROUTINE_PARAM_LIST)->castToElemDDLNode();
CollIndex i0;
CollIndex nbrParamList = pParamList->entries();
ElemDDLParamDef * pParamDef0 = NULL;
for (i0 = 0; i0 < nbrParamList; i0++)
{
pParamDef0 = (*pParamList)[i0]->castToElemDDLParamDef();
ComASSERT(pParamDef0 NEQ NULL);
if ((getRoutineType() == COM_PROCEDURE_TYPE) AND
(pParamDef0->getParamDataType()->getTypeQualifier() == NA_NUMERIC_TYPE))
{
if (((NumericType *)pParamDef0->getParamDataType())->isUnsigned())
{
*SqlParser_Diags << DgSqlCode(-3208);
return;
}
}
if ((getRoutineType() == COM_SCALAR_UDF_TYPE) AND
((pParamDef0->getParamDirection() == COM_OUTPUT_PARAM) OR
(pParamDef0->getParamDirection() == COM_INOUT_PARAM)))
{
*SqlParser_Diags << DgSqlCode(-15001);
return;
}
paramArray_.insert(pParamDef0);
} // for
} // getRoutineType() NEQ COM_UNIVERSAL_UDF_TYPE
} // end ROUTINE_PARAM_LIST not null
if (getChild(INDEX_ROUTINE_RETURNS_LIST) NEQ NULL)
{
if (getRoutineType() == COM_PROCEDURE_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3261);
// Do not have to exit/return here.
// Continue so we can do as much checking as possible.
}
else // NOT an SPJ
{
// Note that we append the returned parameters - specified in the
// RETURN[S] clause - to the end of the formal parameter list.
// Keep track of the position where the RETURNed formal parameter
// list starts to mark the boundary.
firstReturnedParamPosWithinParamArray_ = paramArray_.entries();
ElemDDLNode *pReturnsList =
getChild(INDEX_ROUTINE_RETURNS_LIST)->castToElemDDLNode();
NABoolean isOnlyOutParamModeSupportedMsgAlreadyIssued2 = FALSE;
CollIndex i2;
CollIndex nbrReturnsList = pReturnsList->entries();
ElemDDLParamDef* pParamDef2 = NULL;
for (i2 = 0; i2 < nbrReturnsList; i2++)
{
pParamDef2 = (*pReturnsList)[i2]->castToElemDDLParamDef();
ComASSERT(pParamDef2 NEQ NULL);
paramArray_.insert(pParamDef2);
if (NOT isOnlyOutParamModeSupportedMsgAlreadyIssued2 AND
pParamDef2->getParamDirection() NEQ COM_OUTPUT_PARAM)
{
*SqlParser_Diags << DgSqlCode(-3262);
isOnlyOutParamModeSupportedMsgAlreadyIssued2 = TRUE;
}
} // for (i2 = 0; i2 < nbrReturnsList; i2++)
} // NOT an SPJ
} // end INDEX_ROUTINE_RETURNS_LIST not null
if (getChild(INDEX_ROUTINE_PASSTHROUGH_LIST) NEQ NULL)
{
if (getRoutineType() == COM_PROCEDURE_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3263);
return;
}
ElemDDLNode *pPassThroughList =
getChild(INDEX_ROUTINE_PASSTHROUGH_LIST)->castToElemDDLNode();
CollIndex i4 = 0;
CollIndex nbrPassThroughList = pPassThroughList->entries();
ElemDDLPassThroughParamDef * passThroughDef = NULL;
for (i4 = 0; i4 < nbrPassThroughList; i4++)
{
passThroughDef = (*pPassThroughList)[i4]->castToElemDDLPassThroughParamDef();
ComASSERT(passThroughDef NEQ NULL);
passThroughParamArray_.insert(passThroughDef); // [ ADD ] PASS THROUGH INPUTS
} // for (i4 = 0; i4 < nbrPassThroughList; i4++)
} // end INDEX_ROUTINE_PASSTHROUGH_LIST not null
if (getChild(INDEX_ROUTINE_OPTION_LIST) NEQ NULL)
{
ElemDDLNode *pOptionList =
getChild(INDEX_ROUTINE_OPTION_LIST)->castToElemDDLNode();
ComASSERT(pOptionList NEQ NULL);
if (pOptionList->castToElemDDLOptionList() NEQ NULL)
{
for (CollIndex i6 = 0; i6 < pOptionList->entries(); i6++)
{
setRoutineOption((*pOptionList)[i6]);
}
}
else
{
//
// pOptionList points to a single Create Routine option
//
setRoutineOption(pOptionList);
}
} // if (pOptionList NEQ NULL)
//
// More semantic checks
//
if ( NOT isStmtDDLAlterRoutineParseNode() AND
NOT externalNameSpecified_ AND getRoutineType() NEQ COM_ACTION_UDF_TYPE )
{
*SqlParser_Diags << DgSqlCode(-3205);
if (getRoutineType() == COM_PROCEDURE_TYPE) // keep the old behavior to avoid regression
return;
}
// ---------------------------------------------------------------------
// SPJ
// ---------------------------------------------------------------------
if (getRoutineType() == COM_PROCEDURE_TYPE)
{
if ( ! externalPathSpecified_ && ! libraryNameSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3201);
return;
}
if ( ! languageTypeSpecified_ )
{
*SqlParser_Diags << DgSqlCode(-3203);
return;
}
if (stateAreaSizeSpecified_ || parallelismSpecified_ || finalCallSpecified_)
{
*SqlParser_Diags << DgSqlCode(-15001);
return;
}
if ( (maxResults_ < 0) || ( maxResults_ > 255) )
{
*SqlParser_Diags << DgSqlCode(-3219);
return;
}
// For LANGUAGE JAVA case,
// parse the specified External Name, which is of the form:
// <class-name>.<method-name> [ <signature> ]
// Trim any leading and trailing blanks
externalName_ = externalName_.strip(NAString::both);
size_t namSize = externalName_.length() - 1;
if ( namSize < 2 )
{
*SqlParser_Diags << DgSqlCode(-3204);
return;
}
size_t pos = externalName_.first('('); // Find first left paren
if ( pos NEQ NA_NPOS )
{
// Found left paren. So a signature was specified.
javaSignature_ = externalName_(pos, (externalName_.length()-pos));
externalName_.remove (pos);
externalName_ = externalName_.strip(); // Strip trailing blanks
namSize = externalName_.length() - 1; // Remaining name
if ( namSize < 2 )
{
*SqlParser_Diags << DgSqlCode(-3204);
return;
}
}
// Find the method-name portion.
if ((pos=externalName_.last('.')) EQU NA_NPOS)
{
*SqlParser_Diags << DgSqlCode(-3204); // Badly formed
return;
}
else
{
javaMethodName_ = externalName_(pos+1, (externalName_.length()-pos-1));
javaClassName_ = externalName_.remove (pos);
};
if ( ( javaMethodName_.length() < 1 ) ||
( javaClassName_.length() < 1 ) )
{
*SqlParser_Diags << DgSqlCode(-3204); // Badly formed
return;
}
} // end if (getRoutineType() == COM_PROCEDURE_TYPE)
// ---------------------------------------------------------------------
// UDF or (routine) action
// ---------------------------------------------------------------------
if (getRoutineType() NEQ COM_PROCEDURE_TYPE) // is a function or routine action
{
// Note that getRoutineType() returns COM_UNKNOWN_ROUTINE_TYPE for the
// ALTER FUNCTION statement case. The catman/CatExecAlterRoutine layer
// will look up the information from the metadata tables to determine
// whether the function is a scalar and universal function.
NABoolean isErrorFound = FALSE;
if (NOT isStmtDDLAlterRoutineParseNode() // registration of a routine
AND getRoutineType() EQU COM_UNIVERSAL_UDF_TYPE)
{
ElemDDLNode *pUudfParamKindListParseTree =
getChild(INDEX_ROUTINE_UUDF_PARAM_KIND_LIST)->castToElemDDLNode();
if (pUudfParamKindListParseTree NEQ NULL)
{
for (CollIndex i7 = 0; i7 < pUudfParamKindListParseTree->entries(); i7++)
{
ElemDDLUudfParamDef *pUudfParamKind =
(*pUudfParamKindListParseTree)[i7]->castToElemDDLUudfParamDef();
ComUudfParamKind uudfParamKind = pUudfParamKind->getUudfParamKind();
switch (uudfParamKind)
{
case COM_UUDF_PARAM_OMITTED:
break;
case COM_UUDF_PARAM_ACTION:
if (actionPositionSpecified_)
{
if (NOT isErrorFound)
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate ACTION clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("ACTION");
isErrorFound = TRUE;
}
}
actionPosition_ = i7 + 1;
actionPositionSpecified_ = TRUE;
break;
default:
{
for (CollIndex i9 = 0; i9 < uudfParamKindList_.entries(); i9++)
{
if (NOT isErrorFound AND
uudfParamKindList_[i9] EQU uudfParamKind)
{
NAString paramKindName;
ComGetUudfParamKindAsLit ( uudfParamKind // in
, paramKindName // out
);
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate <param kind> clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0(paramKindName.data());
isErrorFound = TRUE;
}
}
if (uudfParamKind EQU COM_UUDF_PARAM_SAS_FORMAT)
{
if (NOT isErrorFound AND
actionPositionSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3264);
isErrorFound = TRUE;
}
actionPosition_ = i7 + 1;
}
} // default
break;
} // switch
uudfParamKindList_.insert(pUudfParamKind->getUudfParamKind());
} // for (CollIndex i7 = 0; ... )
if (NOT isErrorFound)
{
// Manufacture and insert new entries to the (empty) formal
// parameter definition list for the universal fucnction.
ComASSERT(paramArray_.entries() EQU 0);
ElemDDLParamDef * pParamDef2 = NULL;
ElemDDLParamName * pParamName2 = NULL;
NAType * pParamDataType2 = NULL;
for (CollIndex i2 = 0; i2 < uudfParamKindList_.entries(); i2++)
{
switch (uudfParamKindList_[i2])
{
case COM_UUDF_PARAM_ACTION:
pParamName2 = new(STMTHEAP) ElemDDLParamName("ACTION");
pParamDataType2 = new(STMTHEAP) SQLVarChar (STMTHEAP, 1024 // long maxLength
, FALSE // NABoolean allowSQLnull
);
break;
case COM_UUDF_PARAM_SAS_FORMAT:
pParamName2 = new(STMTHEAP) ElemDDLParamName("SAS_FORMAT");
pParamDataType2 = new(STMTHEAP) SQLVarChar (STMTHEAP, 1024 // long maxLength
, FALSE // NABoolean allowSQLnull
);
break;
case COM_UUDF_PARAM_SAS_LOCALE:
pParamName2 = new(STMTHEAP) ElemDDLParamName("SAS_LOCALE");
pParamDataType2 = new(STMTHEAP) SQLInt (STMTHEAP, TRUE // NABoolean allowNegValues
, FALSE // NABoolean allowSQLnull
);
break;
case COM_UUDF_PARAM_SAS_MODEL_INPUT_TABLE:
pParamName2 = new(STMTHEAP) ElemDDLParamName("SAS_MODEL_INPUT_TABLE");
pParamDataType2 = new(STMTHEAP) SQLVarChar (STMTHEAP, 1024 // long maxLength
, FALSE // NABoolean allowSQLnull
);
break;
default:
case COM_UUDF_PARAM_OMITTED: // any dummy data type would do
pParamName2 = NULL;
pParamDataType2 = new(STMTHEAP) SQLChar (STMTHEAP, 1 // long maxLength
, FALSE // NABoolean allowSQLnull
);
break;
} // switch
pParamDef2 = new(STMTHEAP) ElemDDLParamDef ( pParamDataType2
, pParamName2 // optional_param_name
, COM_INPUT_PARAM
, STMTHEAP
);
paramArray_.insert(pParamDef2);
} // for (CollIndex i2 = 0; ...
} // if no error found
} // if (pUudfParamKindListParseTree NEQ NULL)
} // if is the registration of a universal function
if (externalNameSpecified_)
{
// Trim any leading and trailing blanks
externalName_ = externalName_.strip(NAString::both);
if (externalName_.isNull())
{
*SqlParser_Diags << DgSqlCode(-3204); // Badly formed
isErrorFound = TRUE;
}
}
if (externalPathSpecified_ AND getRoutineType() EQU COM_ACTION_UDF_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3265);
isErrorFound = TRUE;
}
if (isLocationClauseSpec_ AND ( isStmtDDLAlterRoutineParseNode() OR getRoutineType() EQU COM_ACTION_UDF_TYPE ))
{
*SqlParser_Diags << DgSqlCode(-3279);
isErrorFound = TRUE;
}
if (isolateSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3266);
isErrorFound = TRUE;
}
if (transactionAttributesSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3267);
isErrorFound = TRUE;
}
if (maxResultSetsSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3268);
isErrorFound = TRUE;
}
if (languageTypeSpecified_)
{
if (isStmtDDLAlterRoutineParseNode() OR getRoutineType() EQU COM_ACTION_UDF_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3277);
isErrorFound = TRUE;
}
else if (getRoutineType() NEQ COM_TABLE_UDF_TYPE AND languageType_ EQU COM_LANGUAGE_JAVA)
{
*SqlParser_Diags << DgSqlCode(-3269);
isErrorFound = TRUE;
}
}
if (paramStyleSpecified_)
{
if (isStmtDDLAlterRoutineParseNode() OR getRoutineType() EQU COM_ACTION_UDF_TYPE )
{
*SqlParser_Diags << DgSqlCode(-3278);
isErrorFound = TRUE;
}
else
{
switch (paramStyle_)
{
case COM_STYLE_JAVA_CALL:
*SqlParser_Diags << DgSqlCode(-3270);
isErrorFound = TRUE;
break;
case COM_STYLE_SQL:
if (getRoutineType() EQU COM_TABLE_UDF_TYPE OR
getRoutineType() EQU COM_ACTION_UDF_TYPE OR
getRoutineType() EQU COM_UNIVERSAL_UDF_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3280);
isErrorFound = TRUE;
}
break;
case COM_STYLE_SQLROW:
if (getRoutineType() EQU COM_SCALAR_UDF_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3281);
isErrorFound = TRUE;
}
break;
default:
break;
} // switch
}
} // if (paramStyleSpecified_)
if ( sqlAccessSpecified_ AND sqlAccess_ NEQ COM_NO_SQL)
{
*SqlParser_Diags << DgSqlCode(-3271);
isErrorFound = TRUE;
}
if (getRoutineType() EQU COM_TABLE_UDF_TYPE &&
(finalCallSpecified_ OR stateAreaSizeSpecified_))
{
*SqlParser_Diags << DgSqlCode(-3287);
if (finalCallSpecified_)
*SqlParser_Diags << DgString0("FINAL CALL");
else
*SqlParser_Diags << DgString0("STATE AREA SIZE");
isErrorFound = TRUE;
}
if ( (stateAreaSize_ < 0) || ( stateAreaSize_ > 16000) )
{
*SqlParser_Diags << DgSqlCode(-3272);
isErrorFound = TRUE;
}
if (finalCallSpecified_)
{
if (getRoutineType() EQU COM_ACTION_UDF_TYPE)
{
*SqlParser_Diags << DgSqlCode(-3273);
isErrorFound = TRUE;
}
else if (finalCall_ EQU FALSE)
{
*SqlParser_Diags << DgSqlCode(-3274);
isErrorFound = TRUE;
}
}
if (numberOfUniqueOutputValuesSpecified_ AND
NOT isStmtDDLAlterRoutineParseNode()) // registration of a routine
{
if (NOT isReturnClauseSpecified() AND uniqueOutputValues_.entries() > 0)
{
*SqlParser_Diags << DgSqlCode(-3275);
isErrorFound = TRUE;
}
if (getRoutineType() NEQ COM_UNIVERSAL_UDF_TYPE)
{
size_t numberOfOutputParams = getParamArray().entries()
- getFirstReturnedParamPosWithinParamArray();
if (numberOfOutputParams < uniqueOutputValues_.entries())
{
*SqlParser_Diags << DgSqlCode(-3276);
isErrorFound = TRUE;
}
}
} // if (numberOfUniqueOutputValuesSpecified_ AND registration of a routine)
if (isErrorFound)
return; // play it safe
} // if (getRoutineType() NEQ COM_PROCEDURE_TYPE)
} // StmtDDLCreateRoutine::synthesize()
void
StmtDDLCreateRoutine::setRoutineOption(ElemDDLNode * pRoutineOption)
{
ComASSERT(pRoutineOption NEQ NULL);
switch (pRoutineOption->getOperatorType())
{
case ELM_LOCATION_ELEM :
{
if (isLocationClauseSpec_)
{
// Duplicate LOCATION clauses.
*SqlParser_Diags << DgSqlCode(-3098);
}
isLocationClauseSpec_ = TRUE;
ElemDDLLocation * pLocation = pRoutineOption->castToElemDDLLocation();
if (NOT pLocation->getPartitionName().isNull())
*SqlParser_Diags << DgSqlCode(-3405);
locationName_ = pLocation->getLocationName();
locationNameType_ = pLocation->getLocationNameType();
}
break;
case ELM_UDR_DETERMINISTIC :
{
if (deterministicSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("[NOT] DETERMINISTIC");
}
ElemDDLUdrDeterministic * pDeterministic = pRoutineOption->
castToElemDDLUdrDeterministic();
deterministic_ = pDeterministic->getDeterministic();
deterministicSpecified_ = TRUE;
}
break;
case ELM_UDR_EXTERNAL_NAME :
{
if (externalNameSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("EXTERNAL NAME");
}
ElemDDLUdrExternalName * pExternalName = pRoutineOption->
castToElemDDLUdrExternalName();
externalName_ = pExternalName->getExternalName();
externalNameSpecified_ = TRUE;
}
break;
case ELM_UDR_EXTERNAL_PATH :
{
if (externalPathSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("EXTERNAL PATH");
}
if (libraryNameSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("LIBRARY");
}
ElemDDLUdrExternalPath * pExternalPath = pRoutineOption->
castToElemDDLUdrExternalPath();
externalPath_ = pExternalPath->getExternalPath();
externalPathSpecified_ = TRUE;
}
break;
case ELM_UDR_ISOLATE :
{
if (isolateSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("[NO] ISOLATE");
}
ElemDDLUdrIsolate * pIsolate = pRoutineOption->castToElemDDLUdrIsolate();
isolate_ = pIsolate->getIsolate();
isolateSpecified_ = TRUE;
}
break;
case ELM_UDR_LANGUAGE :
{
if (languageTypeSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("LANGUAGE");
}
ElemDDLUdrLanguage * pLanguage = pRoutineOption->
castToElemDDLUdrLanguage();
languageType_ = pLanguage->getLanguage();
languageTypeSpecified_ = TRUE;
}
break;
case ELM_UDR_LIBRARY :
{
if (libraryNameSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("LIBRARY");
}
if (externalPathSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("EXTERNAL PATH");
}
ElemDDLUdrLibrary * pLibrary = pRoutineOption->
castToElemDDLUdrLibrary();
BindWA *pBindWA = new(STMTHEAP) BindWA(ActiveSchemaDB(),
CmpCommon::context(),
TRUE/*inDDL*/);
pLibrary->bindNode(pBindWA);
libraryName_ = pLibrary->getLibraryName();
libraryNameSpecified_ = TRUE;
delete pBindWA;
}
break;
case ELM_UDR_MAX_RESULTS :
{
if (maxResultSetsSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("DYNAMIC RESULT SETS");
}
ElemDDLUdrMaxResults * pMaxResults = pRoutineOption->
castToElemDDLUdrMaxResults();
maxResults_ = (ComSInt32)pMaxResults->getMaxResults();
maxResultSetsSpecified_ = TRUE;
}
break;
case ELM_UDR_PARAM_STYLE :
{
if (paramStyleSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("PARAMETER STYLE");
}
ElemDDLUdrParamStyle * pParamStyle = pRoutineOption->
castToElemDDLUdrParamStyle();
paramStyle_ = pParamStyle->getParamStyle();
paramStyleSpecified_ = TRUE;
}
break;
case ELM_UDR_SQL_ACCESS :
{
if (sqlAccessSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("SQL access mode");
}
ElemDDLUdrSqlAccess * pSqlAccess = pRoutineOption->
castToElemDDLUdrSqlAccess();
sqlAccess_ = pSqlAccess->getSqlAccess();
sqlAccessSpecified_ = TRUE;
}
break;
case ELM_UDR_TRANSACTION_ATTRIBUTES :
{
if (transactionAttributesSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("transaction attributes");
}
ElemDDLUdrTransaction * pTransactionAttributes = pRoutineOption->
castToElemDDLUdrTransaction();
transactionAttributes_ = pTransactionAttributes->
getTransactionAttributes();
}
break;
case ELM_UDR_EXTERNAL_SECURITY :
{
if (externalSecuritySpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("EXTERNAL SECURITY");
}
ElemDDLUdrExternalSecurity * pExternalSecurity = pRoutineOption->
castToElemDDLUdrExternalSecurity();
externalSecurity_ = pExternalSecurity->getExternalSecurity();
externalSecuritySpecified_ = TRUE;
}
break;
case ELM_UDF_EXECUTION_MODE :
{
if (executionModeSpecified_)
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate EXECUTION MODE clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("EXECUTION MODE");
}
ElemDDLUdfExecutionMode * pExecMode = pRoutineOption->castToElemDDLUdfExecutionMode();
executionMode_ = pExecMode->getExecutionMode();
executionModeSpecified_ = TRUE;
}
break;
case ELM_UDF_FINAL_CALL :
{
if (finalCallSpecified_)
{
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("[NO] FINAL CALL");
}
ElemDDLUdfFinalCall * pFinalCall = pRoutineOption->castToElemDDLUdfFinalCall();
finalCall_ = pFinalCall->getFinalCall();
finalCallSpecified_ = TRUE;
}
break;
case ELM_UDF_PARALLELISM :
{
if (parallelismSpecified_)
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate PARALLELISM clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("PARALLELISM");
}
ElemDDLUdfParallelism * pParallelism = pRoutineOption->castToElemDDLUdfParallelism();
parallelism_ = pParallelism->getParallelism();
parallelismSpecified_ = TRUE;
}
break;
case ELM_UDF_SPECIAL_ATTRIBUTES :
{
if (specialAttributesSpecified_)
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate ATTRIBUTES clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("ATTRIBUTES");
}
ElemDDLUdfSpecialAttributes * pUdfSpecialAttrs = pRoutineOption->
castToElemDDLUdfSpecialAttributes();
specialAttributesText_ = pUdfSpecialAttrs->getSpecialAttributesText();
specialAttributesSpecified_ = TRUE;
}
break;
case ELM_UDF_STATE_AREA_SIZE :
{
if (stateAreaSizeSpecified_)
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate STATE AREA clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("STATE AREA");
}
ElemDDLUdfStateAreaSize * pStateAreaSize = pRoutineOption->
castToElemDDLUdfStateAreaSize();
stateAreaSize_ = (ComSInt32)pStateAreaSize->getStateAreaSize();
stateAreaSizeSpecified_ = TRUE;
}
break;
case ELM_UDF_OPTIMIZATION_HINT :
{
ElemDDLUdfOptimizationHint * pOptHint = pRoutineOption->
castToElemDDLUdfOptimizationHint();
NAString udfAttrName;
switch (pOptHint->getOptimizationKind())
{
case COM_UDF_INITIAL_CPU_COST :
if (initialCpuCostSpecified_)
udfAttrName = "INITIAL CPU COST";
initialCpuCost_ = pOptHint->getCost();
initialCpuCostSpecified_ = TRUE;
break;
case COM_UDF_INITIAL_IO_COST :
if (initialIoCostSpecified_)
udfAttrName = "INITIAL IO COST";
initialIoCost_ = pOptHint->getCost();
initialIoCostSpecified_ = TRUE;
break;
case COM_UDF_INITIAL_MESSAGE_COST :
if (initialMsgCostSpecified_)
udfAttrName = "INITIAL MESSAGE COST";
initialMsgCost_ = pOptHint->getCost();
initialMsgCostSpecified_ = TRUE;
break;
case COM_UDF_NORMAL_CPU_COST :
if (normalCpuCostSpecified_)
udfAttrName = "NORMAL CPU COST";
normalCpuCost_ = pOptHint->getCost();
normalCpuCostSpecified_ = TRUE;
break;
case COM_UDF_NORMAL_IO_COST :
if (normalIoCostSpecified_)
udfAttrName = "NORMAL IO COST";
normalIoCost_ = pOptHint->getCost();
normalIoCostSpecified_ = TRUE;
break;
case COM_UDF_NORMAL_MESSAGE_COST :
if (normalMsgCostSpecified_)
udfAttrName = "NORMAL MESSAGE COST";
normalMsgCost_ = pOptHint->getCost();
normalMsgCostSpecified_ = TRUE;
break;
case COM_UDF_NUMBER_OF_UNIQUE_OUTPUT_VALUES :
if (numberOfUniqueOutputValuesSpecified_ )
udfAttrName = "NUMBER OF UNIQUE OUTPUT VALUES";
uniqueOutputValues_ = pOptHint->getUniqueOutputValues();
numberOfUniqueOutputValuesSpecified_ = TRUE;
break;
default :
{
NAAbort(__FILE__, __LINE__, "internal logic error");
}
break;
} // switch
if (NOT udfAttrName.isNull())
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate <attribute name> clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0(udfAttrName.data());
}
}
break;
case ELM_UDF_VERSION_TAG :
{
if (userVersionSpecified_)
{
// 3183 ZZZZZ 99999 BEGINNER MAJOR DBADMIN Duplicate $0~string0 clauses were specified.
// *** ERROR[3183] Duplicate VERSION TAG clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("VERSION TAG");
}
ElemDDLUdfVersionTag * pUdfVesionTag = pRoutineOption->castToElemDDLUdfVersionTag();
userVersion_ = pUdfVesionTag->getVersionTag();
userVersionSpecified_ = TRUE;
}
break;
default :
{
NAAbort(__FILE__, __LINE__, "internal logic error");
}
break;
} // switch
} // StmtDDLRoutineTable::setRoutineOption()
//
// methods for tracing
//
const NAString
StmtDDLCreateRoutine::displayLabel1() const
{
return NAString("Routine name: ") + getRoutineName();
}
const NAString
StmtDDLCreateRoutine::displayLabel2() const
{
return NAString("Table name: ") + getRoutineName();
}
NATraceList
StmtDDLCreateRoutine::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
detailText = "Routine name: ";
detailText += getRoutineName();
detailTextList.append(detailText);
CollIndex i, nbrParams;
const ElemDDLParamDefArray & paramsList = getParamArray();
ElemDDLParamDef * param;
nbrParams = paramsList.entries();
if (nbrParams EQU 0)
{
detailTextList.append("No params.");
}
else
{
detailText = "Param list [";
detailText += LongToNAString((Lng32)nbrParams);
detailText += " param(s)]:";
detailTextList.append(detailText);
for (i = 0; i < nbrParams; i++)
{
param = paramsList[i];
detailText = "[param ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", param->getDetailInfo());
}
} // else (nbrParams EQU 0) of params
return detailTextList;
} // StmtDDLCreateRoutine::getDetailInfo()
const NAString
StmtDDLCreateRoutine::getText() const
{
return "StmtDDLCreateRoutine";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateSchema
// -----------------------------------------------------------------------
//
// initialize constructor
//
StmtDDLCreateSchema::StmtDDLCreateSchema(
const ElemDDLSchemaName & aSchemaNameParseNode,
ComSchemaClass schemaClass,
CharType* pCharType,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_SCHEMA),
schemaName_(heap),
schemaQualName_(aSchemaNameParseNode.getSchemaName(), heap),
authorizationID_(aSchemaNameParseNode.getAuthorizationID(), heap),
schemaClass_(schemaClass),
pCharType_(pCharType),
createIfNotExists_(FALSE)
{
}
//
// virtual destructor
//
StmtDDLCreateSchema::~StmtDDLCreateSchema()
{
delete pCharType_;
}
//
// cast virtual function
//
StmtDDLCreateSchema *
StmtDDLCreateSchema::castToStmtDDLCreateSchema()
{
return this;
}
//
// accessors
//
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLCreateSchema::synthesize()
{
if (schemaQualName_.getCatalogName().isNull())
{
schemaName_ = ToAnsiIdentifier(schemaQualName_.getSchemaName());
}
else
{
schemaName_ = ToAnsiIdentifier(schemaQualName_.getCatalogName()) + "." +
ToAnsiIdentifier(schemaQualName_.getSchemaName());
}
// If the schema name specified is reserved name, users cannot create them.
// They can only be created internally.
if ((! Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) &&
(ComIsTrafodionReservedSchemaName(schemaQualName_.getSchemaName())))
{
// error.
*SqlParser_Diags << DgSqlCode(-1430)
<< DgSchemaName(schemaName_);
}
} // StmtDDLCreateSchema::synthesize()
//
// methods for tracing
//
const NAString
StmtDDLCreateSchema::displayLabel1() const
{
return NAString("Schema name: ") + getSchemaName();
}
const NAString
StmtDDLCreateSchema::displayLabel2() const
{
if (NOT getAuthorizationID().isNull())
{
return NAString("Authorization ID: ") + getAuthorizationID();
}
else
{
return NAString("Authorization identifier not specified.");
}
}
const NAString
StmtDDLCreateSchema::getText() const
{
return "StmtDDLCreateSchema";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateSequence
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateSequence::StmtDDLCreateSequence(const QualifiedName & seqQualName,
ElemDDLSGOptions * pSGOptions,
ComBoolean alter,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_SEQUENCE),
seqQualName_(seqQualName, heap),
pSGOptions_(pSGOptions),
alter_(alter)
{
}
StmtDDLCreateSequence::~StmtDDLCreateSequence()
{
}
//
// cast virtual function
//
StmtDDLCreateSequence *
StmtDDLCreateSequence::castToStmtDDLCreateSequence()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateSequence::getArity() const
{
return 0;
}
ExprNode *
StmtDDLCreateSequence::getChild(Lng32 index)
{
return NULL;
}
//
// methods for tracing
//
const NAString
StmtDDLCreateSequence::displayLabel1() const
{
return NAString("Sequence name: ") + seqQualName_.getQualifiedNameAsAnsiString();
}
NATraceList
StmtDDLCreateSequence::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
//
// table name
//
detailTextList.append(displayLabel1());
return detailTextList;
}
const NAString
StmtDDLCreateSequence::getText() const
{
return "StmtDDLCreateSequence";
}
// method for collecting information
void StmtDDLCreateSequence::synthesize()
{
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateTable
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateTable::StmtDDLCreateTable(const QualifiedName & aTableQualName,
ElemDDLNode * pTableDefBody,
ElemDDLNode * pCreateTableAttrList,
ElemDDLNode * pInsertColumnsList,
RelExpr * queryExpression,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_TABLE),
origTableQualName_(heap),
tableQualName_(aTableQualName, heap),
isLocationClauseSpec_(FALSE),
locationName_(heap),
locationNameType_(ElemDDLLocation::LOCATION_DEFAULT_NAME_TYPE),
partitionName_(heap),
isLikeClauseSpec_(FALSE),
likeSourceTableCorrName_("", heap),
guardianLocation_(heap),
isPrimaryKeyClauseSpec_(FALSE),
pAddConstraintPK_(NULL),
isAttributeClauseSpec_(FALSE),
isMVFileAttributeClauseSpec_(FALSE),
isDivisionByClauseSpec_(FALSE),
pDivisionByClauseParseNode_(NULL),
isHbaseOptionsSpec_(FALSE),
pHbaseOptionsParseNode_(NULL),
pSaltOptions_(NULL),
isStoreByClauseSpec_(FALSE),
isUniqueStoreByKeylist_(FALSE),
isUniqueStoreByPrimaryKey_(FALSE),
storeOption_(COM_UNKNOWN_STORE_OPTION),
isRoundRobinPartitioningSpecified_(FALSE),
isHashV1PartitionSpec_(FALSE),
isHashV2PartitionSpec_(FALSE),
isPartitionClauseSpec_(FALSE),
isPartitionByClauseSpec_(FALSE),
pPrimaryPartition_(NULL),
columnDefArray_(heap),
primaryKeyColRefArray_(heap),
partitionArray_(heap),
partitionKeyColRefArray_(heap),
keyColRefArray_(heap),
addConstraintCheckArray_(heap),
addConstraintRIArray_(heap),
addConstraintUniqueArray_(heap),
addConstraintArray_(heap),
tableType_(ExtendedQualName::NORMAL_TABLE), //++ MV
isSpecialTypeSpecified_(FALSE), //++ MV
isPOSNumPartnsSpecified_(FALSE),
isPOSInitialTableSizeSpecified_(FALSE),
isPOSMaxTableSizeSpecified_(FALSE),
isPOSDiskPoolSpecified_(FALSE),
isPOSIgnoreSpecified_(FALSE),
isNumRowsSpecified_(FALSE),
isIndexLevelsSpecified_(FALSE),
isPartnEOFSpecified_(FALSE),
posNumPartns_(-1),
posInitialTableSize_(-1),
posMaxTableSize_(-1),
posDiskPool_(0),
posNumDiskPools_(0),
posIgnore_(FALSE),
numRows_(-1),
indexLevels_(-1),
partnEOF_(-1),
eInsertMode_(COM_REGULAR_TABLE_INSERT_MODE),
pInsertColumnsList_(pInsertColumnsList),
pQueryExpression_(queryExpression),
startOfCreateTableQuery_(0),
startOfCreateTableAsAttrList_(0),
ctaColumnsAreRenamed_(FALSE),
loadIfExists_(FALSE),
noLoad_(FALSE),
deleteData_(FALSE),
isTableFeatureSpecified_(FALSE),
isDroppable_(TRUE),
isInsertOnly_(FALSE),
pSGOptions_(NULL),
createIfNotExists_(FALSE),
mapToHbaseTable_(FALSE),
hbaseDataFormat_(FALSE)
{
setChild(INDEX_TABLE_DEFINITION, pTableDefBody);
setChild(INDEX_ATTRIBUTE_LIST, pCreateTableAttrList);
}
//
// virtual destructor
//
StmtDDLCreateTable::~StmtDDLCreateTable()
{
// Delete the Primary Partition parse node. This parse node
// is not part of the parse tree. The former was created
// during the construction of the Create Table parse node
// (this object).
delete pPrimaryPartition_;
// Delete the kludge parse nodes derived from class
// StmtDDLAddConstraint. For more information, please read
// the contents of the header file StmtDDLCreateTable.h.
StmtDDLAddConstraint * pAddConstraint;
while (addConstraintArray_.getFirst(pAddConstraint))
{
delete pAddConstraint;
}
// Delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
}
//
// cast virtual function
//
StmtDDLCreateTable *
StmtDDLCreateTable::castToStmtDDLCreateTable()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateTable::getArity() const
{
return MAX_STMT_DDL_CREATE_TABLE_ARITY;
}
ExprNode *
StmtDDLCreateTable::getChild(Lng32 index)
{
ComASSERT(index >= 0 AND index < getArity());
return children_[index];
}
ComPartitioningScheme
StmtDDLCreateTable::getPartitioningScheme() const
{
if (getIsHashV1PartitionSpecified()) // HASH PARTITION clause specified
return COM_HASH_V1_PARTITIONING;
if (getIsHashV2PartitionSpecified()) // HASH2 PARTITION clause specified
return COM_HASH_V2_PARTITIONING;
ComASSERT(pPrimaryPartition_ NEQ NULL);
switch (pPrimaryPartition_->getOperatorType())
{
case ELM_PARTITION_SINGLE_ELEM :
//
// Note that COM_NO_PARTITIONING and
// COM_SINGLE_PARTITIONING defined in
// ComSmallDefs.h have the same meaning.
//
return COM_SINGLE_PARTITIONING;
case ELM_PARTITION_RANGE_ELEM :
return COM_RANGE_PARTITIONING;
case ELM_PARTITION_SYSTEM_ELEM :
return COM_SYSTEM_PARTITIONING;
default :
ABORT("internal logic error");
return COM_UNKNOWN_PARTITIONING; // any dummy value would do
}
}
//
// mutators
//
//
// Computes the default primary partitioning scheme and then
// creates the Primary Partition parse node.
//
void
StmtDDLCreateTable::computeDefaultPrimaryPartition()
{
//
// This method should not be called unless
// the Partition clause does not appear.
//
//
// Computes the default partitioning scheme.
// There are four (4) possibilities:
//
// 1a. If the STORE BY NONDROPPABLE PRIMARY KEY clause appears, or
// 1b. if the STORE BY clause does not appear and the PRIMARY KEY
// clause with the NONDROPPABLE option is specified, then
// uses the range partitioning scheme.
//
if (/*1a*/ (isStoreBySpecified() AND
getStoreOption() EQU COM_NONDROPPABLE_PK_STORE_OPTION) OR
/*1b*/ (NOT isStoreBySpecified() AND
getIsConstraintPKSpecified() AND
NOT getAddConstraintPK()->isDroppable()))
{
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionRange();
pPrimaryPartition_->setTheSpecialCase1aOr1bFlag(TRUE);
}
//
// 2. If the STORE BY clause does not appear and the PRIMARY KEY
// clause with the NONDROPPABLE option is not specified, then
// we can not partition the table at all (forever)! There can
// only exist one single partition, the primary partition.
//
else if (NOT isStoreBySpecified() AND
(NOT getIsConstraintPKSpecified() OR
getAddConstraintPK()->isDroppable()))
{
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionSingle();
}
//
// 3. If the STORE BY <key-column-list> clause appears (whether
// the PRIMARY KEY appears or not), uses the range partitioning
// scheme.
//
else if (isStoreBySpecified() AND
getStoreOption() EQU COM_KEY_COLUMN_LIST_STORE_OPTION)
{
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionRange();
}
//
// 4. If the STORE BY ENTRY ORDER clause appears, uses the
// system partitioning scheme.
//
else if (isStoreBySpecified() AND
getStoreOption() EQU COM_ENTRY_ORDER_STORE_OPTION)
{
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionSystem();
}
//
// I intentionally structured the nested IF code to reflect the
// descriptions on pages 103 and 104 of the version 2.0 of the
// "SQL/Ark DDL Language" external specification, dated 15
// November 1995. The code could have been simplified, but I
// decided that it would be easier to maintain the code if I
// structured the code this way.
//
// I was not sure whether I should have issued error messages
// for the cases not covered in the external specification or
// not. For now I decided to use the system partitioning scheme
// for these cases.
// Kenneth Luu 2/1/96
//
else
{
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionSystem();
}
partitionArray_.insert(pPrimaryPartition_);
}
void
StmtDDLCreateTable::setChild(Lng32 index, ExprNode * pChildNode)
{
ComASSERT(index >= 0 AND index < getArity());
if (pChildNode EQU NULL)
{
children_[index] = NULL;
}
else
{
children_[index] = pChildNode->castToElemDDLNode();
}
}
void
StmtDDLCreateTable::setConstraint(ElemDDLNode * pElement)
{
switch (pElement->getOperatorType())
{
case ELM_CONSTRAINT_CHECK_ELEM :
{
ComASSERT(pElement->castToElemDDLConstraintCheck() NEQ NULL);
// Create a kludge parse node. For more information, please
// read the contents of the head file StmtDDLCreateTable.h
StmtDDLAddConstraintCheck * pAddConstraintCheck =
new(PARSERHEAP())
StmtDDLAddConstraintCheck(getTableNameAsQualifiedName(), pElement);
pAddConstraintCheck->setIsParseSubTreeDestroyedByDestructor(FALSE);
addConstraintArray_.insert(pAddConstraintCheck);
addConstraintCheckArray_.insert(pAddConstraintCheck);
}
break;
case ELM_CONSTRAINT_PRIMARY_KEY_ELEM :
case ELM_CONSTRAINT_PRIMARY_KEY_COLUMN_ELEM :
{
ComASSERT(pElement->castToElemDDLConstraintPK() NEQ NULL);
if (isPrimaryKeyClauseSpec_)
{
// Duplicate PRIMARY KEY clauses.
*SqlParser_Diags << DgSqlCode(-3106);
}
isPrimaryKeyClauseSpec_ = TRUE;
ElemDDLNode * pColRefList = pElement->castToElemDDLConstraintPK()
->getColumnRefList();
ComASSERT(pColRefList NEQ NULL);
for (CollIndex index = 0; index < pColRefList->entries(); index++)
{
primaryKeyColRefArray_.insert(
(*pColRefList)[index]->castToElemDDLColRef());
}
// Create a kludge parse node. For more information, please
// read the contents of the head file StmtDDLCreateTable.h
pAddConstraintPK_ = new(PARSERHEAP())
StmtDDLAddConstraintPK(getTableNameAsQualifiedName(), pElement);
pAddConstraintPK_->setIsParseSubTreeDestroyedByDestructor(FALSE);
addConstraintArray_.insert(pAddConstraintPK_);
}
break;
case ELM_CONSTRAINT_REFERENTIAL_INTEGRITY_ELEM :
{
ComASSERT(pElement->castToElemDDLConstraintRI() NEQ NULL);
// Create a kludge parse node. For more information, please
// read the contents of the head file StmtDDLCreateTable.h
StmtDDLAddConstraintRI * pAddConstraintRI = new(PARSERHEAP())
StmtDDLAddConstraintRI(getTableNameAsQualifiedName(), pElement);
pAddConstraintRI->setIsParseSubTreeDestroyedByDestructor(FALSE);
addConstraintArray_.insert(pAddConstraintRI);
addConstraintRIArray_.insert(pAddConstraintRI);
}
break;
case ELM_CONSTRAINT_UNIQUE_ELEM :
{
ComASSERT(pElement->castToElemDDLConstraintUnique() NEQ NULL);
// Create a kludge parse node. For more information, please
// read the contents of the head file StmtDDLCreateTable.h
StmtDDLAddConstraintUnique * pAddConstraintUnique =
new(PARSERHEAP())
StmtDDLAddConstraintUnique(getTableNameAsQualifiedName(),
pElement);
pAddConstraintUnique->setIsParseSubTreeDestroyedByDestructor(FALSE);
addConstraintArray_.insert(pAddConstraintUnique);
addConstraintUniqueArray_.insert(pAddConstraintUnique);
}
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
}
} // StmtDDLCreateTable::setConstraint()
void
StmtDDLCreateTable_visitTableDefElement(ElemDDLNode * pCreateTableNode,
CollIndex /* index */,
ElemDDLNode * pElement);
//
// collects information in the parse sub-tree and copy/move them
// to the current parse node.
//
void
StmtDDLCreateTable::synthesize()
{
ElemDDLNode *pTableDefBody = NULL;
if (! pQueryExpression_)
{
ComASSERT(getChild(INDEX_TABLE_DEFINITION) NEQ NULL);
}
if (getChild(INDEX_TABLE_DEFINITION) NEQ NULL)
{
pTableDefBody =
getChild(INDEX_TABLE_DEFINITION)->castToElemDDLNode();
ComASSERT(pTableDefBody NEQ NULL);
}
ElemDDLNode *pCreateTableAttrList = NULL;
if (getChild(INDEX_ATTRIBUTE_LIST) NEQ NULL)
{
pCreateTableAttrList =
getChild(INDEX_ATTRIBUTE_LIST)->castToElemDDLNode();
ComASSERT(pCreateTableAttrList NEQ NULL);
}
ElemDDLStoreOptKeyColumnList * sbkcl = NULL; //store by keycolumnlist
ElemDDLStoreOptNondroppablePK * sbpk = NULL; //store by primary key
ElemDDLPartitionClause * pbc = NULL; //partition by clause
NABoolean isDuplicateDivisionByClauseErrorMsgAlreadyIssued = FALSE;
if (pCreateTableAttrList NEQ NULL)
{
if (pCreateTableAttrList->castToElemDDLOptionList() NEQ NULL)
{
for (CollIndex i = 0; i < pCreateTableAttrList->entries(); i++)
{
ElemDDLNode * pTableOption = (*pCreateTableAttrList)[i];
if (pTableOption->castToElemDDLStoreOptKeyColumnList()
NEQ NULL)
{
sbkcl =
pTableOption->castToElemDDLStoreOptKeyColumnList();
}
if (pTableOption->castToElemDDLStoreOptNondroppablePK()
NEQ NULL)
{
sbpk =
pTableOption->castToElemDDLStoreOptNondroppablePK();
}
if (pTableOption->castToElemDDLPartitionClause()
NEQ NULL)
{
pbc =
pTableOption->castToElemDDLPartitionClause();
}
else if (pTableOption->castToElemDDLDivisionClause()
NEQ NULL) // The user specified the DIVISION BY clause
{
if (isDivisionByClauseSpec_ AND NOT isDuplicateDivisionByClauseErrorMsgAlreadyIssued)
{
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("DIVISION BY");
isDuplicateDivisionByClauseErrorMsgAlreadyIssued = TRUE;
}
pDivisionByClauseParseNode_ =
pTableOption->castToElemDDLDivisionClause();
isDivisionByClauseSpec_ = TRUE;
}
else if (pTableOption->castToElemDDLHbaseOptions() NEQ NULL)
{
if (isHbaseOptionsSpecified())
{
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("HBASE_OPTIONS");
}
pHbaseOptionsParseNode_ =
pTableOption->castToElemDDLHbaseOptions();
isHbaseOptionsSpec_ = TRUE;
}
}
}
else
{
if (pCreateTableAttrList->castToElemDDLStoreOptKeyColumnList()
NEQ NULL)
sbkcl =
pCreateTableAttrList->castToElemDDLStoreOptKeyColumnList();
if (pCreateTableAttrList->castToElemDDLStoreOptNondroppablePK()
NEQ NULL)
sbpk =
pCreateTableAttrList->castToElemDDLStoreOptNondroppablePK();
if (pCreateTableAttrList->castToElemDDLPartitionClause()
NEQ NULL)
pbc =
pCreateTableAttrList->castToElemDDLPartitionClause();
else if (pCreateTableAttrList->castToElemDDLDivisionClause()
NEQ NULL) // The user specified the DIVISION BY clause
{
pDivisionByClauseParseNode_ =
pCreateTableAttrList->castToElemDDLDivisionClause();
isDivisionByClauseSpec_ = TRUE;
}
else if (pCreateTableAttrList->castToElemDDLHbaseOptions() NEQ NULL)
{
pHbaseOptionsParseNode_ =
pCreateTableAttrList->castToElemDDLHbaseOptions();
isHbaseOptionsSpec_ = TRUE;
}
}
} // some table attr specified
isUniqueStoreByKeylist_ = FALSE; // default
isUniqueStoreByPrimaryKey_ = FALSE; // default
NABoolean isPkeyStoreByKeylist = FALSE;
// if the user specified UNIQUE PRIMARY KEY set the flag.
if ( (sbpk != NULL) &&
(sbpk->isUniqueStoreByPrimaryKey()))
{
isUniqueStoreByPrimaryKey_ = TRUE;
}
// if the user specified STORE BY UNIQUE (col-list) then set flag.
if ( (sbkcl != NULL) &&
(sbkcl->getKeyColumnList()->entries() > 0))
{
// User specified a STORE BY (col-list) clause; did they specify
// the UNIQUE keyword too?
isUniqueStoreByKeylist_ = sbkcl->isUniqueStoreByKeylist();
// did they specify a primary key clause with column list
isPkeyStoreByKeylist = sbkcl->isPkeyStoreByKeylist();
}
NABoolean userSpecifiedPKey = FALSE;
if ((CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON) ||
(isVolatile()) ||
((isPkeyStoreByKeylist) && pTableDefBody && (pTableDefBody->castToElemDDLLikeCreateTable() == NULL)))
{
NABoolean addPrimaryKeyClause = FALSE;
ElemDDLNode * keyColsList = NULL;
ElemDDLColDef * col = NULL;
ElemDDLColDef * volTabSbyCol = NULL;
Lng32 volTabSbyColPos = -1;
ElemDDLNode * currListElem = pTableDefBody;
ElemDDLNode * currElem = NULL;
while (currListElem)
{
if (currListElem->getOperatorType() EQU ELM_ELEM_LIST)
{
currElem = (ElemDDLNode*)currListElem->getChild(1);
currListElem = (ElemDDLNode*)currListElem->getChild(0);
}
else
{
currElem = currListElem;
currListElem = NULL;
}
if (currElem->getOperatorType() EQU ELM_COL_DEF_ELEM)
{
col = (ElemDDLColDef *)currElem;
if (col->getConstraintPK())
userSpecifiedPKey = TRUE;
// Hierarchy of the datatypes that will be used to determine
// the keys of a volatile table. Hierarchy is low to high
// (first entry is the lowest)
static const Lng32 volTabSbyHier[] =
{
REC_BYTE_V_ASCII,
REC_INT_SECOND,
REC_INT_MINUTE_SECOND,
REC_INT_MINUTE,
REC_INT_HOUR_SECOND,
REC_INT_DAY_SECOND,
REC_INT_DAY,
REC_INT_HOUR,
REC_INT_DAY_HOUR,
REC_INT_HOUR_MINUTE,
REC_INT_DAY_MINUTE,
REC_INT_YEAR,
REC_INT_MONTH,
REC_INT_YEAR_MONTH,
REC_DATETIME,
REC_BYTE_F_ASCII,
REC_NUM_BIG_SIGNED,
REC_NUM_BIG_UNSIGNED,
REC_DECIMAL_LSE,
REC_DECIMAL_UNSIGNED,
REC_BIN16_SIGNED,
REC_BIN16_UNSIGNED,
REC_BIN32_SIGNED,
REC_BIN32_UNSIGNED,
REC_BIN64_UNSIGNED,
REC_BIN64_SIGNED
};
// find the column on which to store/hash based on the
// hierarchy specified in the volTabSbyHier array.
// Do this only if there are no user specified pkey, store by,
// or partition by clauses.
// Within that hierarchy, non-nullable values have preference
// over nullable values.
// If a column is found, then it will be used later in this
// method to create a storeBy clause of the volatile table
// so that the table created as partitioned table.
// If no usable columns are found,
// then the table will be created as non-partitioned.
if ((CmpCommon::getDefault(VOLATILE_TABLE_FIND_SUITABLE_KEY) != DF_OFF) &&
(NOT userSpecifiedPKey) &&
((sbkcl == NULL) && (sbpk == NULL) && (pbc == NULL)))
{
NABoolean found = FALSE;
Lng32 j = 0;
Lng32 maxSize = sizeof(volTabSbyHier) / sizeof(Lng32);
for (j = 0; ((NOT found) && (j < maxSize)); j++)
{
if (col->getColumnDataType() &&
col->getColumnDataType()->getFSDatatype() ==
volTabSbyHier[j])
found = TRUE;
}
if (found)
{
if (volTabSbyCol == NULL)
{
volTabSbyColPos = j;
volTabSbyCol = col;
}
else
{
// choose the current col if it has a higher
// hierarchy than the saved column.
// If they have the same hierarchy then pick the
// non-nullable column.
// If they have the same hierarchy and same
// nullability, then pick the current col.
if ((j > volTabSbyColPos) ||
((j == volTabSbyColPos) &&
((col->isNotNullConstraintSpecified() ==
volTabSbyCol->isNotNullConstraintSpecified()) ||
(col->isNotNullConstraintSpecified()))))
{
volTabSbyColPos = j;
volTabSbyCol = col;
}
}
}
}
}
else
{
if (currElem->getOperatorType() EQU
ELM_CONSTRAINT_PRIMARY_KEY_ELEM)
{
userSpecifiedPKey = TRUE;
keyColsList =
currElem->castToElemDDLConstraintPK()->getColumnRefList();
}
}
} // while
if (userSpecifiedPKey)
{
volTabSbyCol = NULL;
if (isPkeyStoreByKeylist)
{
// cannot specify 'primary key' as a column AND a table attr.
// Return error.
*SqlParser_Diags << DgSqlCode(-3106);
return;
}
}
// if no user specified pkey or store by clause has been specified
// for a volatile table, then make the first column the pkey.
if ((isVolatile()) &&
(sbkcl == NULL) &&
(NOT userSpecifiedPKey) &&
(col != NULL) &&
(CmpCommon::getDefault(VOLATILE_TABLE_FIND_SUITABLE_KEY) == DF_OFF))
{
// make the storeby list the primary key
ElemDDLConstraintPKColumn * pk =
new (PARSERHEAP()) ElemDDLConstraintPKColumn();
pk->setConstraintAttributes(NULL);
col->setColumnAttribute(pk);
ElemDDLNode * pColAttrList = NULL;
if (col->getChild(ElemDDLColDef::INDEX_ELEM_DDL_COL_ATTR_LIST))
pColAttrList =
col->getChild(ElemDDLColDef::INDEX_ELEM_DDL_COL_ATTR_LIST)->castToElemDDLNode();
ElemDDLNode * newColAttrList = NULL;
if (pColAttrList)
newColAttrList =
new (PARSERHEAP()) ElemDDLList(pColAttrList, pk);
else
newColAttrList = pk;
col->setChild(ElemDDLColDef::INDEX_ELEM_DDL_COL_ATTR_LIST,
newColAttrList);
userSpecifiedPKey = TRUE;
}
if ((sbkcl) &&
(pTableDefBody) &&
(NOT userSpecifiedPKey) &&
(sbkcl->getKeyColumnList()->entries() > 0))
{
keyColsList = sbkcl->getKeyColumnList();
if (sbkcl->isUniqueStoreBy())
{
// make the storeby list the primary key
ElemDDLConstraintPK * pk =
new (PARSERHEAP()) ElemDDLConstraintPK
(NULL, sbkcl->getSerializedOption());
pk->setColumnRefList(keyColsList);
pk->setConstraintKind(ElemDDLConstraint::TABLE_CONSTRAINT_DEF);
pk->setConstraintAttributes(NULL);
pTableDefBody = new (PARSERHEAP())
ElemDDLList(pTableDefBody, pk);
}
}
// if no user specified pkey or store by clause or partition by clause
// has been specified for a volatile table, and the CQD is OFF,
// then pick the first column based on the hierarchy specified
// in array volTabSbyType, and add the following clause:
//
// store by (<first-col>)
//
if ((isVolatile()) &&
(sbkcl == NULL) &&
(NOT userSpecifiedPKey) &&
(volTabSbyCol != NULL) &&
(pbc == NULL) &&
(CmpCommon::getDefault(VOLATILE_TABLE_FIND_SUITABLE_KEY) != DF_OFF))
{
sbkcl = new (PARSERHEAP())
ElemDDLStoreOptKeyColumnList(
new (PARSERHEAP())
ElemDDLColRef(volTabSbyCol->getColumnName(),
COM_UNKNOWN_ORDER, PARSERHEAP()));
if (pCreateTableAttrList)
{
pCreateTableAttrList = new (PARSERHEAP())
ElemDDLOptionList(pCreateTableAttrList, sbkcl);
}
else
pCreateTableAttrList = sbkcl;
setChild(INDEX_ATTRIBUTE_LIST, pCreateTableAttrList);
userSpecifiedPKey = TRUE;
}
// loop over all cols and make nullable columns which are part
// of pkey specification, not-null-non-droppable.
// Do this only if cqd VOLATILE_TABLE_FIND_SUITABLE_KEY is
// set to OFF.
if (CmpCommon::getDefault(VOLATILE_TABLE_FIND_SUITABLE_KEY) == DF_OFF)
{
currListElem = pTableDefBody;
while (currListElem)
{
if (currListElem->getOperatorType() EQU ELM_ELEM_LIST)
{
currElem = (ElemDDLNode*)currListElem->getChild(1);
currListElem = (ElemDDLNode*)currListElem->getChild(0);
}
else
{
currElem = currListElem;
currListElem = NULL;
}
if (currElem->getOperatorType() EQU ELM_COL_DEF_ELEM)
{
col = (ElemDDLColDef *)currElem;
}
else
{
continue;
}
// if 'col' is nullable and part of keyColsList, make
// 'col' not nullable.
if (NOT col->isNotNullConstraintSpecified())
{
NABoolean makeThisColNNND = FALSE;
if (col->isPrimaryKeyConstraintSpecified())
makeThisColNNND = TRUE;
else if (keyColsList NEQ NULL)
{
// See if this col is in pkey or store by clause.
for (CollIndex index = 0; index < keyColsList->entries();
index++)
{
ComASSERT((*keyColsList)[index]->castToElemDDLColRef() NEQ NULL);
ElemDDLColRef * kCol =
(*keyColsList)[index]->castToElemDDLColRef();
if (col->getColumnName() == kCol->getColumnName())
{
// make col non-nullable
makeThisColNNND = TRUE;
}
} // for
} // else
// soln 10-090312-9983. If dataType is NULL then create table AS will set it later.
if (makeThisColNNND && col->getColumnDataType())
{
ElemDDLConstraintNotNull * nn =
new (PARSERHEAP()) ElemDDLConstraintNotNull(PARSERHEAP());
ElemDDLConstraintAttrDroppable * nd =
new (PARSERHEAP())
ElemDDLConstraintAttrDroppable(FALSE);
nn->setConstraintAttributes(nd);
col->setColumnAttribute(nn);
}
} // col is nullable
} // while
}
} //
// ---------------------------------------------------------------------
// traverse the Table Definition parse sub-tree
// ---------------------------------------------------------------------
// If pTableDefBody points to a parse node representing LIKE clause
// (instead of a list of column and table constraint definitions),
// gather the LIKE options specified in the LIKE clause and store
// them in data member likeOptions_. Also save the source table
// name in data member likeSourceTableCorrName_.
if (pTableDefBody)
{
if (pTableDefBody->castToElemDDLLikeCreateTable() NEQ NULL)
{
if (isLikeClauseSpec_)
{
// Duplicate LIKE clauses.
*SqlParser_Diags << DgSqlCode(-3107);
}
isLikeClauseSpec_ = TRUE;
likeSourceTableCorrName_ = pTableDefBody->castToElemDDLLikeCreateTable()
->getDDLLikeNameAsCorrName();
likeOptions_ = pTableDefBody->castToElemDDLLikeCreateTable()
->getLikeOptions();
if ((NOT isExternal()) &&
(pTableDefBody->castToElemDDLLikeCreateTable()->forExtTable()))
{
*SqlParser_Diags << DgSqlCode(-3242)
<< DgString0("'for' clause can only be specified when creating an 'external' table.");
return;
}
else if ((isExternal()) &&
(NOT pTableDefBody->castToElemDDLLikeCreateTable()->forExtTable()))
{
*SqlParser_Diags << DgSqlCode(-3242)
<< DgString0("'like' clause cannot be specified when creating an external table.");
return;
}
}
else
{
// pTableDefBody points to a (left linear tree) list of
// column and/or table constraint definitions
// Traverse the parse sub-tree containing the list of column
// and table constraint definitions.
//
// Update the data member columnDefArray_ to contain pointers
// pointing to Column Definition parse nodes. Storing the
// pointers in columnDefArray_ allows the user to access to
// Column Definition parse nodes more efficiently. The friend
// function StmtDDLCreateTable_visitTableDefElement does the
// insertion.
//
// For each column and table constraint definition (except for
// Not Null constraint), add them to the corresponding contraint
// list. For more information, please read the contents of the
// header file StmtDDLCreateTable.h.
pTableDefBody->traverseList(
this,
StmtDDLCreateTable_visitTableDefElement);
}
}
// ---------------------------------------------------------------------
// traverse the Create Table Attribute List sub-tree
// ---------------------------------------------------------------------
// Traverse the Create Table Attribute List sub-tree to extract the
// information about the specified file attributes. Store this
// information in data member fileAttributes_.
if (pCreateTableAttrList NEQ NULL)
{
if (pCreateTableAttrList->castToElemDDLOptionList() NEQ NULL)
{
for (CollIndex i = 0; i < pCreateTableAttrList->entries(); i++)
{
setTableOption((*pCreateTableAttrList)[i]);
}
}
else
{
//
// pCreateTableAttrList points to a single Create Table
// option (e.g., a partition clause, a file attributes
// clause, a location clause, etc.
//
setTableOption(pCreateTableAttrList);
}
} // if (pCreateTableAttrList NEQ NULL)
// Don't allow volatile tables to be created as not droppable
if (isVolatile() && !isDroppable())
*SqlParser_Diags << DgSqlCode(-1286); // volatile table must be droppable
// ---------------------------------------------------------------------
// Updates information about file attributes if necessary
// ---------------------------------------------------------------------
//
// If Buffered phrase does not appeared, sets its default value
// depending on whether the table is audited or not.
//
getFileAttributes().setDefaultValueForBuffered();
// if default column family is not specified, then set it to traf default
getFileAttributes().setDefaultValueForColFam();
// ---------------------------------------------------------------------
// Creates or updates parse node representing primary partition
// ---------------------------------------------------------------------
//
// If partition clause does not appear, the partitionArray_
// is still empty; constructs the primary partition node and
// then inserts its pointer to the array.
//
if (partitionArray_.entries() EQU 0)
{
//
// The following method should only be invoked after all
// information in the parse has been collected and copied
// to the Create Table (root) parse node.
//
computeDefaultPrimaryPartition();
}
ComASSERT(pPrimaryPartition_ NEQ NULL);
// ---------------------------------------------------------------------
// Temporary code--Currently we do not allow multiple partitions
// for entry-sequenced user tables.
// ---------------------------------------------------------------------
if (getStoreOption() EQU COM_ENTRY_ORDER_STORE_OPTION AND
isPartitionSpecified())
{
// *** ERROR[3121] Partitioned entry-sequenced tables
// currently not allowed.
// I (Huy) will need to change this to an error instead.
// Otherwise execution will keep go, and executor spit
// out weird error message. Remove the minus in front of
// the 3121 to get a warning , and remove the whole line
// to support the entry-sequence partition table.
*SqlParser_Diags << DgSqlCode(-3121);
}
// I (Huy) added the code to check if the table is
// Key-Sequence is specified,
// Then first key is not allowed.
/**********
if ( getIsStoreBySpecified() && getIsLikeOptionSpecified())
{
*SqlParser_Diags << DgSqlCode(-3156);
return;
}
**********/
if (getStoreOption() NEQ COM_ENTRY_ORDER_STORE_OPTION AND
getStoreOption() NEQ COM_RELATIVE_ORDER_STORE_OPTION)
{
// is key-sequenced by default it is a key-sequence table.
// unless the store by option is specified.
/*****************
if ((Get_SqlParser_Flags(ALLOW_FUNNY_TABLE_CREATE)) ||
(getIsLikeOptionSpecified())
)
{
for (CollIndex i = 0; i < getPartitionArray().entries(); i++)
if (getPartitionArray()[i]->castToElemDDLPartitionRange() NEQ NULL)
{
// this is the case that the table is key-sequence and
// the partition scheme is vertical, then the first key is
// not allowed.
*SqlParser_Diags << DgSqlCode(-3146);
break;
}
}
else
{
*****************/
if (partitionArray_.entries() > 1) // PARTITION clause specified
{
for (CollIndex i = 0; i < getPartitionArray().entries(); i++)
{
if (getPartitionArray()[i]->castToElemDDLPartitionRange() EQU NULL)
{ // Neither FIRST KEY phrase nor HASH specified in PARTITION clause
if (getIsHashV1PartitionSpecified() EQU FALSE &&
getIsHashV2PartitionSpecified() EQU FALSE)
{
*SqlParser_Diags << DgSqlCode(-3138);
break;
}
}
else // FIRST KEY WAS SPECIFIED--cannot specify HASH
{
if (getIsHashV1PartitionSpecified() ||
getIsHashV2PartitionSpecified())
{
*SqlParser_Diags << DgSqlCode(-3153);
break;
}
}
}
}
//} // else
} // if is key-sequenced
// The information specified in the location clause and
// load option clauses (e.g., dslack and islack) is for
// the primary partition, copies it to the primary partition
// node.
//
//
// Note that class ElemDDLPartitionSystem is the base class
// for both derived classes ElemDDLPartitionSingle and
// ElemDDLPartitionRange.
//
ElemDDLPartitionSystem * pSysPart =
pPrimaryPartition_->castToElemDDLPartitionSystem();
if (pSysPart EQU NULL)
{
ABORT("internal logic error");
}
else
{
//
// location
//
if (isLocationSpecified())
{
pSysPart->setLocationName(getLocationName());
pSysPart->setLocationNameType(getLocationNameType());
pSysPart->setPartitionName(getPartitionName());
}
//
// file attributes
//
const ParDDLFileAttrsCreateIndex & fileAttrs = getFileAttributes();
if (fileAttrs.isMaxSizeSpecified())
{
pSysPart->setIsMaxSizeSpecified(fileAttrs.isMaxSizeSpecified());
pSysPart->setIsMaxSizeUnbounded(fileAttrs.isMaxSizeUnbounded());
pSysPart->setMaxSize (fileAttrs.getMaxSize());
pSysPart->setMaxSizeUnit (fileAttrs.getMaxSizeUnit());
}
if (fileAttrs.isExtentSpecified())
{
pSysPart->setIsExtentSpecified(fileAttrs.isExtentSpecified());
pSysPart->setPriExt (fileAttrs.getPriExt());
pSysPart->setSecExt (fileAttrs.getSecExt());
}
if (fileAttrs.isMaxExtentSpecified())
{
pSysPart->setIsMaxExtentSpecified(fileAttrs.isMaxExtentSpecified());
pSysPart->setMaxExt (fileAttrs.getMaxExt());
}
} // else (pSysPart NEQ NULL)
if (isStoreBySpecified() AND
getStoreOption() EQU COM_NONDROPPABLE_PK_STORE_OPTION)
{
if (getIsConstraintPKSpecified())
{
if (isUniqueStoreByPrimaryKey_)
{
// STORE BY UNIQUE PRIMARY KEY clause appears in the CREATE TABLE
// definition. Do not give error 3065 because of UNIQUE.
}
else
if (getAddConstraintPK()->isDroppableSpecifiedExplicitly())
{
// The primary key constraint cannot be droppable when the STORE BY
// PRIMARY KEY clause appears in the CREATE TABLE definition. Please
// change the definition of the primary key constraint to make it
// NOT DROPPABLE.
*SqlParser_Diags << DgSqlCode(-3065);
}
else
{
// Forces the primary key constraint to be non-droppable
getAddConstraintPK()->setDroppableFlag(FALSE);
}
}
else
// "store by primary key" specified, but no primary key exists
// Error 3188 unless MODE_SPECIAL_1.
if (!getIsLikeOptionSpecified())
if (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_OFF)
{
*SqlParser_Diags << DgSqlCode(-3188);
return;
}
}
// check and RI constraints are not allowed on volatile tables
if ((isVolatile()) &&
((getAddConstraintCheckArray().entries() > 0) || // no check constraint
(getAddConstraintRIArray().entries() > 0))) // no RI (FK) constraint
{
*SqlParser_Diags << DgSqlCode(-1283);
}
// if volatile table and pos extensions are not specified in
// the ddl, then get number of partitions info from CQD and set it.
// The default is 4 local partitions. The default is 100 Mb per partition.
// Also set the max table size from temp table CQD, if that cqd exists.
if ((isVolatile()) &&
(CmpCommon::getDefault(POS) != DF_OFF))
{
// num partitions is not explicitly specified, get it from defaults.
if (NOT isPOSNumPartnsSpecified())
{
if (CmpCommon::getDefault(POS_NUM_OF_TEMP_TABLE_PARTNS, 0) == DF_SYSTEM)
// set to 4 local partitions.
posNumPartns_ = -4; // the default, 4 local partitions
else
{
posNumPartns_ = ActiveSchemaDB()->getDefaults().
getAsLong(POS_NUM_OF_TEMP_TABLE_PARTNS);
if (posNumPartns_ == 1)
posNumPartns_ = 0;
// negative number from this cqd indicates all(local + remote)
// segment partitions.
// positive number indicates local partitions.
// Negate it so +ve number can indicate all partitions and
// -ve number can indicate local partitions.
posNumPartns_ = - posNumPartns_;
}
isPOSNumPartnsSpecified_ = TRUE;
}
// if max table size if not explicitly specified, get it from defaults.
if (NOT isPOSMaxTableSizeSpecified())
{
NAString str;
char tempStr[1000];
char *value;
const char *sep = " ,";
CmpCommon::getDefault(POS_TEMP_TABLE_SIZE, str, 0);
strcpy(tempStr, str.data());
value = strtok(tempStr, sep);
if (value != NULL)
{
double tableSize = 0;
sscanf(value, "%lf", &tableSize);
posMaxTableSize_ = (Lng32)tableSize;
isPOSMaxTableSizeSpecified_ = TRUE;
}
}
}
if (isPOSDiskPoolSpecified_)
{
if (posNumDiskPools_ != 0 )
{
if (posDiskPool_)
{
if ((posDiskPool_ != MAX_COMSINT32) &&
(posDiskPool_ > posNumDiskPools_))
{
*SqlParser_Diags << DgSqlCode(-3417)
<< DgInt0(posDiskPool_)
<< DgInt1(posNumDiskPools_);
}
}
else
{
if (ActiveSchemaDB()->getDefaults().getAsLong(POS_DISK_POOL) >
posNumDiskPools_)
{
*SqlParser_Diags << DgSqlCode(-3417)
<< DgInt0(ActiveSchemaDB()->getDefaults()
.getAsLong(POS_DISK_POOL))
<< DgInt1(posNumDiskPools_);
}
}
}
else if ((ActiveSchemaDB()->getDefaults().getAsLong(POS_NUM_DISK_POOLS) > 0) &&
((posDiskPool_ != MAX_COMSINT32) &&
(posDiskPool_ > ActiveSchemaDB()->
getDefaults().getAsLong(POS_NUM_DISK_POOLS))))
{
*SqlParser_Diags << DgSqlCode(-3417)
<< DgInt0(posDiskPool_)
<< DgInt1(ActiveSchemaDB()->
getDefaults().getAsLong(POS_NUM_DISK_POOLS));
}
}
if (isPOSDiskPoolSpecified_ &&
isPOSNumPartnsSpecified_ &&
posNumPartns_ < 0)
{
*SqlParser_Diags << DgSqlCode(-3418);
}
/*
if ((isPOSDiskPoolSpecified_ ||
(CmpCommon::getDefault(POS) == DF_DISK_POOL)) &&
((isPOSNumPartnsSpecified_ &&
posNumPartns_ > 0) ||
((CmpCommon::getDefault(POS_NUM_OF_PARTNS, 0) != DF_SYSTEM) &&
(ActiveSchemaDB()->getDefaults().getAsULong(POS_NUM_OF_PARTNS) >0))) &&
((posNumDiskPools_ > 1) ||
(ActiveSchemaDB()->getDefaults().getAsULong(POS_NUM_DISK_POOLS) > 1)))
{
*SqlParser_Diags << DgSqlCode(-3417);
}
*/
} // StmtDDLCreateTable::synthesize()
// Parameter pCreateTableNode points to the Create Table
// parse node.
// Parameter pElement points to either a column or table
// constraint definition parse node in the left linear
// tree list. This tree is a sub-tree in the Create
// Table parse node.
// Parameter index contains the index of the parse node
// pointed by pElement in the (left linear tree) list.
//
void
StmtDDLCreateTable_visitTableDefElement(ElemDDLNode * pCreateTableNode,
CollIndex /* index */,
ElemDDLNode * pElement)
{
ComASSERT(pCreateTableNode NEQ NULL AND
pCreateTableNode->castToStmtDDLCreateTable() NEQ NULL AND
pElement NEQ NULL);
StmtDDLCreateTable * pCreateTable =
pCreateTableNode->castToStmtDDLCreateTable();
if (pElement->castToElemDDLLikeCreateTable() NEQ NULL)
{
pCreateTable->likeSourceTableCorrName_ =
pElement->castToElemDDLLikeCreateTable()
->getDDLLikeNameAsCorrName();
pCreateTable->likeOptions_ =
pElement->castToElemDDLLikeCreateTable()
->getLikeOptions();
if ((NOT pCreateTable->isExternal()) &&
(pElement->castToElemDDLLikeCreateTable()->forExtTable()))
{
*SqlParser_Diags << DgSqlCode(-3242)
<< DgString0("'for' clause can only be specified when creating an 'external' table.");
return;
}
else if ((pCreateTable->isExternal()) &&
(NOT pElement->castToElemDDLLikeCreateTable()->forExtTable()))
{
*SqlParser_Diags << DgSqlCode(-3242)
<< DgString0("'like' clause cannot be specified when creating an external table.");
return;
}
}
else if (pElement->castToElemDDLConstraint() NEQ NULL)
{
//
// table constraint definition
//
pCreateTable->setConstraint(pElement);
}
else if (pElement->castToElemDDLColDef() NEQ NULL)
{
ElemDDLColDef * pColDef = pElement->castToElemDDLColDef();
if (pColDef->getColumnDataType() == NULL)
{
// if ((CmpCommon::getDefault(COMP_BOOL_207) == DF_OFF) ||
if (pCreateTable->getQueryExpression() == NULL)
{
*SqlParser_Diags << DgSqlCode(-1174)
<< DgString0(pColDef->getColumnName());
return;
}
else
{
pCreateTable->setCTAcolumnsAreRenamed(TRUE);
}
}
pCreateTable->getColDefArray().insert(pColDef);
if (pColDef->getIsConstraintPKSpecified())
{
pCreateTable->setConstraint(pColDef->getConstraintPK());
}
//
// For each column constraint definition (except for
// not null and primary key constraints), creates
// a corresponding table constraint definition and
// then insert the newly create parse node to the
// appropriate table constraint array. This arrangement
// helps the processing of constraint definitions in
// create table statement.
//
for (CollIndex i = 0; i < pColDef->getConstraintArray().entries(); i++)
{
pCreateTable->setConstraint(pColDef->getConstraintArray()[i]);
}
}
else
{
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
}
} // StmtDDLCreateTable_visitTableDefElement()
//
// Copies the information in the specified secondary partition
// (pointed to by pElement) to the Create Table parse node
// pointed to by pCreateTableNode.
//
void
StmtDDLCreateTable_visitPartitionElement(ElemDDLNode * pCreateTableNode,
CollIndex /* index */,
ElemDDLNode * pElement)
{
ComASSERT(pCreateTableNode NEQ NULL AND pElement NEQ NULL);
StmtDDLCreateTable * pCreateTable =
pCreateTableNode->castToStmtDDLCreateTable();
ComASSERT(pCreateTable NEQ NULL);
ElemDDLPartition * pPartition = pElement->castToElemDDLPartition();
ComASSERT(pPartition NEQ NULL);
//
// Inserts the specified secondary partition node to the end
// of the partitionArray_ of the Create Table parse node.
// Note that secondary partitions are defined in the partition
// clause.
//
switch (pPartition->getOperatorType())
{
case ELM_PARTITION_RANGE_ELEM :
case ELM_PARTITION_SYSTEM_ELEM :
//
// Note that class ElemDDLPartitionRange is derived
// from class ElemDDLPartitionSystem, and the latter
// is derived from class ElemDDLPartition.
//
ComASSERT(pPartition->castToElemDDLPartitionSystem() NEQ NULL);
if (pPartition->castToElemDDLPartitionSystem()->getOption()
NEQ ElemDDLPartition::ADD_OPTION)
{
// Only ADD option allowed in PARTITION clause in CREATE TABLE statement.
*SqlParser_Diags << DgSqlCode(-3104);
}
pCreateTable->partitionArray_.insert(pPartition);
break;
//
// Other future partitioning schemes; e.g., hash partitioning
//
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch (pPartition->getOperatorType())
} // StmtDDLCreateTable_visitPartitionElement()
//
// Copies the information in the specified Partition clause
// (pointed to by pPartitionClause) to this object.
//
void
StmtDDLCreateTable::setPartitions(ElemDDLPartitionClause * pPartitionClause)
{
ComASSERT(pPartitionClause NEQ NULL);
if ( (isPartitionSpecified()) ||
((isPOSNumPartnsSpecified()) && (posNumPartns_ == 0)) )
{
// Duplicate PARTITION clauses. It is OK to have a partn spec (e.g.
// "hash2 partitioning") and a partitioning count (e.g.
// "number of partitions 2") But, if "no partitions" is specified
// (number of partitions 0) then we don't allow any other partn spec
*SqlParser_Diags << DgSqlCode(-3103)
<< DgString0("PARTITION");
}
isPartitionClauseSpec_ = TRUE;
//
// Initializes pPartitions to point to the parse node representing
// the definition of a partition (class ElemDDLPartition) or
// a list of partition definitions (class ElemDDLPartitionList).
//
ElemDDLNode * pPartitions = pPartitionClause->getPartitionDefBody();
//
// Copy the partitioning type from the partition clause
//
if (pPartitionClause->getPartitionType() EQU COM_HASH_V1_PARTITIONING)
{
isHashV1PartitionSpec_ = TRUE;
}
else if (pPartitionClause->getPartitionType() EQU COM_HASH_V2_PARTITIONING)
{
isHashV2PartitionSpec_ = TRUE;
}
//
// Constructs the primary partition node and then inserts
// its pointer at the beginning of the partitionArray_.
// Note that the partition clause does not include the
// definition of the primary partition.
//
// The kind of the primary partition node must be the
// same as that of the secondary partition node.
//
if (pPartitions EQU NULL)
setPrimaryPartition(NULL);
else
// (*pPartitions)[0] points to the parse node
// representing the first secondary partition.
setPrimaryPartition((*pPartitions)[0]);
//
// Inserts the secondary partition nodes to the end
// of the partitionArray_. Note that secondary partitions
// are defined in the partition clause.
//
if (pPartitions NEQ NULL)
pPartitions->traverseList(this, StmtDDLCreateTable_visitPartitionElement);
//
// Initializes pPartitionByOption to point to the parse node
// representing the definition of partition by columns (class
// ElemDDLPartitionByOpt).
//
ElemDDLNode *pPartitionByOption = pPartitionClause->getPartitionByOption();
if(pPartitionByOption NEQ NULL)
{
// If the Partition By Option is specified, set the flag and copy
// the pointers to column parse nodes to partitionKeyColRefArray_.
if(pPartitionByOption->castToElemDDLPartitionByOpt() NEQ NULL)
{
isPartitionByClauseSpec_ = TRUE;
switch (pPartitionByOption->getOperatorType())
{
case ELM_PARTITION_BY_COLUMN_LIST_ELEM :
ComASSERT(pPartitionByOption->castToElemDDLPartitionByColumnList()
NEQ NULL);
{
// Once we have other types of partition by
// partitionByOption_ = COM_COLUMN_LIST_PARTITION_BY_OPTION;
//
// Copies array of pointers pointing to Column parse nodes to
// PartitionKeyColRefArray_ so the user of this object can access
// the information easier.
//
ElemDDLNode * pPartitionByCols = pPartitionByOption->
castToElemDDLPartitionByColumnList()->getPartitionKeyColumnList();
NABoolean columnOrderingSpecified = FALSE;
for (CollIndex index = 0; index < pPartitionByCols->entries(); index++)
{
ComASSERT((*pPartitionByCols)[index]->castToElemDDLColRef() NEQ NULL);
// Report error if ordering was specified for any column.
if ((*pPartitionByCols)[index]->castToElemDDLColRef()->isColumnOrderingSpecified())
{
// It is not allowed to specify ordering for columns of a partitioning key clause.
// Report an error only once for the column list - not for each offending column.
if (NOT columnOrderingSpecified)
{
*SqlParser_Diags << DgSqlCode(-3199)
<< DgString0((*pPartitionByCols)[index]->castToElemDDLColRef()->getColumnName());
columnOrderingSpecified = TRUE;
}
}
partitionKeyColRefArray_.insert(
(*pPartitionByCols)[index]->castToElemDDLColRef());
}
}
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
}
} // if(pPartitionByOption NEQ NULL)
} // StmtDDLCreateTable::setPartitions()
//
// Copies the information in the specified file attributes clause
// to the data member fileAttributes_.
//
void
StmtDDLCreateTable::setFileAttributes(ElemDDLFileAttrClause * pFileAttrClause)
{
ComASSERT(pFileAttrClause NEQ NULL);
if (isAttributeClauseSpec_)
{
// Duplicate file ATTRIBUTE(S) clauses.
*SqlParser_Diags << DgSqlCode(-3099);
}
isAttributeClauseSpec_ = TRUE;
ElemDDLNode * pFileAttrs = pFileAttrClause->getFileAttrDefBody();
ComASSERT(pFileAttrs NEQ NULL);
for (CollIndex i = 0; i < pFileAttrs->entries(); i++)
{
getFileAttributes().setFileAttr((*pFileAttrs)[i]->castToElemDDLFileAttr());
}
} // StmtDDLCreateTable::setFileAttributes()
void
StmtDDLCreateTable::setMVFileAttributes(ElemDDLMVFileAttrClause * pMVFileAttrClause)
{
ComASSERT(pMVFileAttrClause NEQ NULL);
if (isMVFileAttributeClauseSpec_)
{
// Duplicate file ATTRIBUTE(S) clauses.
*SqlParser_Diags << DgSqlCode(-3099);
}
isMVFileAttributeClauseSpec_ = TRUE;
ElemDDLNode * pMVFileAttrs = pMVFileAttrClause->getFileAttrDefBody();
ComASSERT(pMVFileAttrs NEQ NULL);
for (CollIndex i = 0; i < pMVFileAttrs->entries(); i++)
{
getFileAttributes().setFileAttr((*pMVFileAttrs)[i]->castToElemDDLFileAttr());
}
} // StmtDDLCreateTable::setFileAttributes()
//
// Constructs the primary partition node and then inserts its pointer
// at the beginning of the partitionArray_. The kind of the primary
// partition must match that of the secondary partition[s].
//
// This method is only invoked when the partition clause appears.
//
void
StmtDDLCreateTable::setPrimaryPartition(ElemDDLNode * pFirstSecondaryPartition)
{
if (pFirstSecondaryPartition EQU NULL) // single partition
{
if (getIsHashV1PartitionSpecified() || getIsHashV2PartitionSpecified())
// The HASH PARTITION or HASH2 PARTITION clause was specified.
pPrimaryPartition_ = new(PARSERHEAP())ElemDDLPartitionSystem();
else
pPrimaryPartition_ = new(PARSERHEAP())ElemDDLPartitionRange();
}
else
switch (pFirstSecondaryPartition->getOperatorType())
{
case ELM_PARTITION_RANGE_ELEM :
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionRange();
break;
case ELM_PARTITION_SYSTEM_ELEM :
// We use ElemDDLPartitionSystem parse node for HASH partitions.
pPrimaryPartition_ = new(PARSERHEAP()) ElemDDLPartitionSystem();
break;
//
// Other future partitioning schemes
//
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
}
partitionArray_.insert(pPrimaryPartition_);
} // StmtDDLCreateTable::setPrimaryPartition()
void
StmtDDLCreateTable::setTableOption(ElemDDLNode * pTableOption)
{
ComASSERT(pTableOption NEQ NULL);
if (pTableOption->castToElemDDLStoreOpt() NEQ NULL)
{
if (isStoreByClauseSpec_)
{
// Duplicate STORE BY clauses.
*SqlParser_Diags << DgSqlCode(-3109);
}
isStoreByClauseSpec_ = TRUE;
switch (pTableOption->getOperatorType())
{
case ELM_STORE_OPT_DEFAULT_ELEM :
ComASSERT(pTableOption->castToElemDDLStoreOptDefault() NEQ NULL);
storeOption_ = COM_UNKNOWN_STORE_OPTION; // for now
break;
case ELM_STORE_OPT_ENTRY_ORDER_ELEM :
ComASSERT(pTableOption->castToElemDDLStoreOptEntryOrder() NEQ NULL);
storeOption_ = COM_ENTRY_ORDER_STORE_OPTION;
break;
case ELM_STORE_OPT_KEY_COLUMN_LIST_ELEM :
ComASSERT(pTableOption->castToElemDDLStoreOptKeyColumnList() NEQ NULL);
storeOption_ = COM_KEY_COLUMN_LIST_STORE_OPTION;
{
//
// Copies array of pointers pointing to Key Column parse nodes
// keyColumnArray_ so the user of this object can access the
// information easier.
//
ElemDDLNode * pKeyCols = pTableOption->
castToElemDDLStoreOptKeyColumnList()->getKeyColumnList();
for (CollIndex index = 0; index < pKeyCols->entries(); index++)
{
ComASSERT((*pKeyCols)[index]->castToElemDDLColRef() NEQ NULL);
keyColRefArray_.insert((*pKeyCols)[index]->castToElemDDLColRef());
}
}
break;
case ELM_STORE_OPT_NONDROPPABLE_PRIMARY_KEY_ELEM :
ComASSERT(pTableOption->castToElemDDLStoreOptNondroppablePK() NEQ NULL);
storeOption_ = COM_NONDROPPABLE_PK_STORE_OPTION;
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
return; // exist this method
} // if (pTableOption->castToElemDDLStoreOpt() NEQ NULL)
switch (pTableOption->getOperatorType())
{
case ELM_FILE_ATTR_CLAUSE_ELEM :
// no needs to check for duplication - the syntax only allows
// a single file ATTRIBUTES clause.
//
setFileAttributes(pTableOption->castToElemDDLFileAttrClause());
break;
// this is a special MV extension to file attributes
case ELM_MV_FILE_ATTR_CLAUSE_ELEM :
setMVFileAttributes(pTableOption->castToElemDDLMVFileAttrClause());
break;
case ELM_TABLE_FEATURE_ELEM :
setTableFeature(pTableOption->castToElemDDLTableFeature());
break;
case ELM_LOCATION_ELEM :
ComASSERT(pTableOption->castToElemDDLLocation() NEQ NULL);
if (isLocationClauseSpec_)
{
// Duplicate LOCATION clauses.
*SqlParser_Diags << DgSqlCode(-3098);
}
isLocationClauseSpec_ = TRUE;
{
ElemDDLLocation * pLocation = pTableOption->castToElemDDLLocation();
locationName_ = pLocation->getLocationName();
locationNameType_ = pLocation->getLocationNameType();
partitionName_ = pLocation->getPartitionName();
}
break;
case ELM_PARTITION_CLAUSE_ELEM :
// no needs to check for duplication - the syntax only allows
// a single PARTITION clause.
//
setPartitions(pTableOption->castToElemDDLPartitionClause());
break;
case ELM_FILE_ATTR_POS_NUM_PARTNS_ELEM:
if (isPOSNumPartnsSpecified_)
{
// Duplicate phrases.
if ((posNumPartns_ == 0) &&
(pTableOption->castToElemDDLFileAttrPOSNumPartns()
->getPOSNumPartns() == 0))
{
*SqlParser_Diags << DgSqlCode(-3421);
}
else
{
*SqlParser_Diags << DgSqlCode(-3423);
}
}
posNumPartns_ = pTableOption->castToElemDDLFileAttrPOSNumPartns()
->getPOSNumPartns();
if ( (isPartitionSpecified()) && (posNumPartns_ == 0) )
{
// Conflicting PARTITION clauses. It is OK to have a partn spec (e.g.
// "hash2 partitioning") and a partitioning count (e.g.
// "number of partitions 2") But, if "no partitions" is specified
// (number of partitions 0) then we don't allow any other partn spec
*SqlParser_Diags << DgSqlCode(-3103)
<< DgString0("PARTITION");
}
isPOSNumPartnsSpecified_ = TRUE;
break;
case ELM_FILE_ATTR_POS_DISK_POOL_ELEM:
{
if (isPOSDiskPoolSpecified_)
*SqlParser_Diags << DgSqlCode(-3422);
posDiskPool_ = pTableOption->castToElemDDLFileAttrPOSDiskPool()
->getPOSDiskPool();
posNumDiskPools_ = pTableOption->castToElemDDLFileAttrPOSDiskPool()
->getPOSNumDiskPools();
isPOSDiskPoolSpecified_ = TRUE;
}
break;
case ELM_FILE_ATTR_POS_TABLE_SIZE_ELEM:
{
if (pTableOption->castToElemDDLFileAttrPOSTableSize()
->getPOSInitialTableSize() != -1)
{
if (isPOSInitialTableSizeSpecified_)
{
// Duplicate TABLE SIZE phrases.
*SqlParser_Diags << DgSqlCode(-3407);
}
posInitialTableSize_ =
pTableOption->castToElemDDLFileAttrPOSTableSize()
->getPOSInitialTableSize();
isPOSInitialTableSizeSpecified_ = TRUE;
}
if (pTableOption->castToElemDDLFileAttrPOSTableSize()
->getPOSMaxTableSize() != -1)
{
if (isPOSMaxTableSizeSpecified_)
{
// Duplicate TABLE SIZE phrases.
*SqlParser_Diags << DgSqlCode(-3407);
}
posMaxTableSize_ =
pTableOption->castToElemDDLFileAttrPOSTableSize()
->getPOSMaxTableSize();
isPOSMaxTableSizeSpecified_ = TRUE;
}
if (pTableOption->castToElemDDLFileAttrPOSTableSize()->getNumRows() != -1)
{
if (isNumRowsSpecified_)
{
// Duplicate phrases.
*SqlParser_Diags << DgSqlCode(-3407);
}
numRows_ =
pTableOption->castToElemDDLFileAttrPOSTableSize()->getNumRows();
isNumRowsSpecified_ = TRUE;
}
if (pTableOption->castToElemDDLFileAttrPOSTableSize()->getIndexLevels() != -1)
{
// only allowed with InMem table definitions
if (NOT isInMemoryObjectDefn())
{
*SqlParser_Diags << DgSqlCode(-15001);
return;
}
if (isIndexLevelsSpecified_)
{
// Duplicate phrases.
*SqlParser_Diags << DgSqlCode(-3407);
}
indexLevels_ =
pTableOption->castToElemDDLFileAttrPOSTableSize()->getIndexLevels();
isIndexLevelsSpecified_ = TRUE;
}
if (pTableOption->castToElemDDLFileAttrPOSTableSize()->getPartnEOF() != -1)
{
// only allowed with InMem table definitions
if (NOT isInMemoryObjectDefn())
{
*SqlParser_Diags << DgSqlCode(-15001);
return;
}
if (isPartnEOFSpecified_)
{
// Duplicate phrases.
*SqlParser_Diags << DgSqlCode(-3407);
}
partnEOF_ =
pTableOption->castToElemDDLFileAttrPOSTableSize()->getPartnEOF();
isPartnEOFSpecified_ = TRUE;
}
}
break;
case ELM_FILE_ATTR_POS_IGNORE_ELEM:
{
if (isPOSIgnoreSpecified_)
*SqlParser_Diags << DgSqlCode(-3090);
posIgnore_ =
pTableOption->castToElemDDLFileAttrPOSIgnore()->getIgnorePOS();
isPOSIgnoreSpecified_ = TRUE;
}
break;
case ELM_DIVISION_CLAUSE_ELEM:
case ELM_HBASE_OPTIONS_ELEM:
// Do nothing here.
// We already performed the initialization in StmtDDLCreateTable::synthesize().
break;
case ELM_SALT_OPTIONS_ELEM:
{
if (pSaltOptions_)
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183) << DgString0("SALT");
else
pSaltOptions_ = pTableOption->castToElemDDLSaltOptionsClause();
}
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
} // StmtDDLCreateTable::setTableOption()
//
// methods for tracing
//
const NAString
StmtDDLCreateTable::displayLabel1() const
{
return NAString("Table name: ") + getTableName();
}
NATraceList
StmtDDLCreateTable::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
//
// table name
//
detailTextList.append(displayLabel1());
//
// Like clause
//
if (getIsLikeOptionSpecified())
{
//
// ParDDLLikeOptsCreateTable from getLikeOptions()
//
detailTextList.append("LIKE option specified.");
//
// Does nothing for now because Like clause is not
// support in the first release. Exits this method.
//
return detailTextList;
}
//
// Display information about column definitions
//
const ElemDDLColDefArray & colsList = getColDefArray();
CollIndex i, nbrCols = colsList.entries();
if (nbrCols EQU 0)
{
//
// list of column definitions is required
// unless Like clause appears.
//
detailTextList.append("No columns.");
}
else
{
detailText = "Column list [";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " column(s)]:";
detailTextList.append(detailText);
ElemDDLColDef * col;
for (i = 0; i < nbrCols; i++)
{
col = colsList[i];
detailText = "[column ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", col->getDetailInfo());
}
} // else (nbrCols NEQ 0) of column definitions
//
// check constraints
//
const StmtDDLAddConstraintCheckArray & checkConstraintList
= getAddConstraintCheckArray();
CollIndex nbrConstraints = checkConstraintList.entries();
if (nbrConstraints EQU 0)
{
detailTextList.append("No check constraints.");
}
else
{
detailText = "Check constraint list [";
detailText += LongToNAString((Lng32)nbrConstraints);
detailText += " element(s)]:";
detailTextList.append(detailText);
StmtDDLAddConstraintCheck * checkConstraint;
for (i = 0; i < nbrConstraints; i++)
{
checkConstraint = checkConstraintList[i];
detailText = "[check constraint ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", checkConstraint->getDetailInfo());
}
} // else (nbrConstraints NEQ 0) of check constraints
//
// primary key (column or table) constraint
//
detailText = "is primary key constraint specified? ";
detailText += YesNo(getIsConstraintPKSpecified());
detailTextList.append(detailText);
if (getIsConstraintPKSpecified())
{
const ElemDDLColRefArray & keysList = getPrimaryKeyColRefArray();
nbrCols = keysList.entries();
if (nbrCols EQU 0)
{
detailTextList.append("No primary key list.");
}
else
{
detailText = "Primary key column list [";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " element(s)]:";
detailTextList.append(detailText);
ElemDDLColRef * keyCol;
for (i = 0; i < nbrCols; i++)
{
keyCol = keysList[i];
detailText = "[primary key column ";
detailText += LongToNAString((Lng32)i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", keyCol->getDetailInfo());
} // for (i = 0; i < nbrCols; i++)
} // else ((nbrCols EQU 0)
} // if (getIsConstraintPKSpecified())
//
// referential integrity constraints
//
const StmtDDLAddConstraintRIArray & rIConstraintList
= getAddConstraintRIArray();
nbrConstraints = rIConstraintList.entries();
if (nbrConstraints EQU 0)
{
detailTextList.append("No referential integrity constraints.");
}
else
{
detailText = "Referential integrity constraint list [";
detailText += LongToNAString((Lng32)nbrConstraints);
detailText += " element(s)]:";
detailTextList.append(detailText);
StmtDDLAddConstraintRI * rIConstraint;
for (i = 0; i < nbrConstraints; i++)
{
rIConstraint = rIConstraintList[i];
detailText = "[referential integrity constraint ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", rIConstraint->getDetailInfo());
}
} // else (nbrConstraints NEQ 0) of referential integrity constraints
//
// unique constraints
//
const StmtDDLAddConstraintUniqueArray & uniqueConstraintList
= getAddConstraintUniqueArray();
nbrConstraints = uniqueConstraintList.entries();
if (nbrConstraints EQU 0)
{
detailTextList.append("No unique constraints.");
}
else
{
detailText = "Unique constraint list [";
detailText += LongToNAString((Lng32)nbrConstraints);
detailText += " element(s)]:";
detailTextList.append(detailText);
StmtDDLAddConstraintUnique * uniqueConstraint;
for (i = 0; i < nbrConstraints; i++)
{
uniqueConstraint = uniqueConstraintList[i];
detailText = "[unique constraint ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", uniqueConstraint->getDetailInfo());
}
} // else (nbrConstraints NEQ 0) of unique constraints
//
// Store By clause
//
if (isStoreBySpecified())
{
switch (getStoreOption())
{
case COM_ENTRY_ORDER_STORE_OPTION :
detailTextList.append("Entry Order store option specified");
break;
case COM_KEY_COLUMN_LIST_STORE_OPTION :
detailTextList.append("Key Column List store option specified");
{
const ElemDDLColRefArray & keyCols = getKeyColumnArray();
nbrCols = keyCols.entries();
ComASSERT(nbrCols NEQ 0);
detailText = "key column list in Store By clause[";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " element(s)]:";
detailTextList.append(detailText);
ElemDDLColRef * keyCol;
for (i = 0; i < nbrCols; i++)
{
keyCol = keyCols[i];
detailText = "[key column ";
detailText += LongToNAString((Lng32)i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", keyCol->getDetailInfo());
} // for (i = 0; i < nbrCols; i++)
}
break;
case COM_NONDROPPABLE_PK_STORE_OPTION :
detailTextList.append("Nondroppable Primary Key store option specified");
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
} // if (isStoreBySpecified())
else
{
detailTextList.append("Store By clause not specified.");
} // else (NOT isStoreBySpecified())
//
// file attributes
//
detailTextList.append("File attributes: ");
ParDDLFileAttrsCreateTable fileAttribs = getFileAttributes();
detailTextList.append(" ", fileAttribs.getDetailInfo());
//
// partitions
//
CollIndex nbrParts;
const ElemDDLPartitionArray & partsList = getPartitionArray();
ElemDDLPartitionSystem * part;
nbrParts = partsList.entries();
if (nbrParts EQU 0)
{
detailTextList.append("No partitions.");
}
else
{
detailText = "Partition list [";
detailText += LongToNAString((Lng32)nbrParts);
detailText += " element(s)]: ";
detailTextList.append(detailText);
for (i = 0; i < nbrParts; i++)
{
part = partsList[i]->castToElemDDLPartitionSystem();
if (part EQU NULL)
{
//
// Note that class ElemDDLPartitionRange is
// derived from class ElemDDLPartitionSystem
//
// Only support range and system partitioning.
*SqlParser_Diags << DgSqlCode(-3105);
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
}
detailText = "[partition ";
detailText += LongToNAString((Lng32)i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", part->getDetailInfo());
} //for (j = 0; j < nbrParts; j++)
} // else (nbrParts NEQ 0)
return detailTextList;
} // StmtDDLCreateTable::getDetailInfo()
const NAString
StmtDDLCreateTable::getText() const
{
return "StmtDDLCreateTable";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateTableArray
// -----------------------------------------------------------------------
// virtual destructor
StmtDDLCreateTableArray::~StmtDDLCreateTableArray()
{
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateHbaseTable
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateHbaseTable::StmtDDLCreateHbaseTable(const QualifiedName & aTableQualName,
ConstStringList * csl,
ElemDDLHbaseOptions * hbaseOptions,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_HBASE_TABLE),
origTableQualName_(heap),
tableQualName_(aTableQualName, heap),
csl_(csl),
pHbaseOptionsParseNode_(hbaseOptions)
{
}
StmtDDLCreateHbaseTable::~StmtDDLCreateHbaseTable()
{
}
//
// cast virtual function
//
StmtDDLCreateHbaseTable *
StmtDDLCreateHbaseTable::castToStmtDDLCreateHbaseTable()
{
return this;
}
const NAString
StmtDDLCreateHbaseTable::displayLabel1() const
{
return NAString("Table name: ") + getTableName();
}
NATraceList
StmtDDLCreateHbaseTable::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
//
// table name
//
detailTextList.append(displayLabel1());
return detailTextList;
} // StmtDDLCreateHbaseTable::getDetailInfo()
const NAString
StmtDDLCreateHbaseTable::getText() const
{
return "StmtDDLCreateHbaseTable";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateMV
// -----------------------------------------------------------------------
//
// Internal helper routine
//
//
// constructor
//
StmtDDLCreateMV::StmtDDLCreateMV( const QualifiedName &MVQualName,
const ParNameLocList &nameLocList,
ElemDDLNode *optionalMVColumnList,
ComMVRefreshType refreshType,
ElemDDLNode *pAttributeTableLists,
//ComMVStatus mvStatus,
MvInitializationType mvInitType,
ComBoolean isRewriteEnabled,
ElemDDLNode *optionalFileOptionsClause,
RelExpr *queryExpression,
ElemDDLNode *pOptionalOwner,
CollHeap *heap)
: MVQualName_(MVQualName, heap),
refreshType_(refreshType),
columnDefArray_(heap),
nameLocList_(nameLocList, heap),
startPos_(nameLocList.getTextStartPosition()),
endPos_(0), // set later by ParSetTextEndPos()
theMVInfo_(NULL),
viewUsages_(heap),
isAttrClauseSpecified_(FALSE),
isLocationClauseSpecified_(FALSE),
isPartitionDefinitionSpecified_(FALSE),
isPartitionByClauseSpecified_(FALSE),
isDivisionByClauseSpecified_(FALSE),
pDivisionByClauseParseNode_(NULL),
isStoreByClauseSpecified_(FALSE),
isMVAttributeClauseSpecified_(FALSE),
mvAuditType_(COM_MV_AUDIT),
commitEachNRows_(0),
pMVColumnList_(optionalMVColumnList),
pFileOptions_(optionalFileOptionsClause),
pStoreByOption_(NULL),
pQueryExpression_(queryExpression),
pAttributeTableLists_(pAttributeTableLists),
pIgnoreChangesList_(0),
StmtDDLNode(DDL_CREATE_MV),
partitionKeyColRefArray_(heap),
udfList_(heap)
{
// MV file options are a subset of Table's file options.
// Since we use the same parsing rule as a Table's, we need to check that all file
// options are allowed.
ensureCorrectMVFileOptions();
extractMvAttributesFromFileOptions();
ComMVStatus mvStatus = COM_MVSTATUS_UNKNOWN;
switch (mvInitType)
{
case MVINIT_ON_CREATE:
mvStatus = COM_MVSTATUS_INITIALIZED;
break;
case MVINIT_ON_REFRESH:
mvStatus = COM_MVSTATUS_NOT_INITIALIZED;
break;
case MVINIT_NO_INIT:
case MVINIT_BY_USER:
mvStatus = COM_MVSTATUS_NO_INITIALIZATION;
break;
}
theMVInfo_ = new(heap)
MVInfoForDDL(MVQualName_.getQualifiedNameAsAnsiString(),
refreshType,
isRewriteEnabled,
mvStatus,
nameLocList.getInputStringPtr(),
nameLocList.getInputStringCharSet(),
pStoreByOption_,
heap );
// set up owner info
if (pOptionalOwner)
{
ElemDDLNode *pTemp = pOptionalOwner;
ComASSERT(pTemp NEQ NULL);
pOwner_ = pTemp->castToElemDDLGrantee();
ComASSERT(pOwner_ NEQ NULL);
}
}
//
// virtual destructor
//
StmtDDLCreateMV::~StmtDDLCreateMV()
{
// delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
}
//
// cast
//
StmtDDLCreateMV *
StmtDDLCreateMV::castToStmtDDLCreateMV()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateMV::getArity() const
{
return MAX_STMT_DDL_CREATE_MV_ARITY;
}
ExprNode *
StmtDDLCreateMV::getChild(Lng32 index)
{
switch (index)
{
case INDEX_MV_COLUMN_LIST :
return pMVColumnList_;
case INDEX_FILE_OPTIONS_CLAUSE :
return pFileOptions_;
case INDEX_QUERY_EXPRESSION :
return pQueryExpression_;
default :
ABORT("internal logic error");
return 0;
}
}
//
// mutators
//
void
StmtDDLCreateMV::incrCurViewColNum()
{
if (isProcessingViewColList())
{
setCurViewColNum(getCurViewColNum()+(CollIndex)1);
}
else
{
setCurViewColNum((CollIndex)0);
}
}
void
StmtDDLCreateMV::setChild(Lng32 index, ExprNode * pChildNode)
{
switch (index)
{
case INDEX_MV_COLUMN_LIST :
if (pChildNode NEQ NULL)
{
pMVColumnList_ = pChildNode->castToElemDDLNode();
ComASSERT(pMVColumnList_ NEQ NULL);
}
else
{
pMVColumnList_ = NULL;
}
break;
case INDEX_FILE_OPTIONS_CLAUSE :
if (pChildNode NEQ NULL)
{
pFileOptions_ = pChildNode->castToElemDDLNode();
ComASSERT(pFileOptions_ NEQ NULL);
}
else
{
pFileOptions_ = NULL;
}
break;
case INDEX_QUERY_EXPRESSION :
if (pChildNode NEQ NULL)
{
pQueryExpression_ = pChildNode->castToRelExpr();
ComASSERT(pQueryExpression_ NEQ NULL);
}
else
{
pQueryExpression_ = NULL;
}
break;
default :
ABORT("internal logic error");
}
}
void
StmtDDLCreateMV::synthesize()
{
//
// Collects pointers to column name parser nodes for easier access
//
if (pMVColumnList_ NEQ NULL)
{
for (Int32 i = 0; i < (Int32)pMVColumnList_->entries(); i++)
{
ComASSERT((*pMVColumnList_)[i] NEQ NULL);
columnDefArray_.insert((*pMVColumnList_)[i]->
castToElemDDLColViewDef());
}
}
processAttributeTableLists();
} // StmtDDLCreateMV::synthesize()
NABoolean
StmtDDLCreateMV::statementHasAttributeTableLists()
{
return (NULL != pAttributeTableLists_);
}
void
StmtDDLCreateMV::processAttributeTableLists()
{
if(!statementHasAttributeTableLists())
{
return;
}
if (COM_ON_REQUEST != refreshType_)
{
// no changes clause for recompute mvs
*SqlParser_Diags << DgSqlCode(-12043);
}
NABoolean ignoreChangesListSpecified = FALSE;
for ( CollIndex i = 0 ; i < pAttributeTableLists_->entries() ; i++)
{
ElemDDLCreateMVOneAttributeTableList * pAttributeList =
(*pAttributeTableLists_)[i]->
castToElemDDLCreateMVOneAttributeTableList();
ComASSERT(NULL NEQ pAttributeList);
if (COM_IGNORE_CHANGES == pAttributeList->getType())
{
if (ignoreChangesListSpecified)
{
// Duplicate IGNORE CHANGES clause.
*SqlParser_Diags << DgSqlCode(-12044);
}
else
{
ignoreChangesListSpecified = TRUE;
}
pIgnoreChangesList_ = pAttributeList;
}
else
{
// Fatal Error in attribute table lists - list type unknown.
*SqlParser_Diags << DgSqlCode(-12046);
}
}
}
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::ensureCorrectMVFileOptions()
{
if (getChild(INDEX_FILE_OPTIONS_CLAUSE) NEQ NULL)
{
ElemDDLNode *pCreateTableAttrList =
getChild(INDEX_FILE_OPTIONS_CLAUSE)->castToElemDDLNode();
ComASSERT(pCreateTableAttrList NEQ NULL);
if (pCreateTableAttrList->castToElemDDLOptionList() NEQ NULL)
{
for (CollIndex i = 0; i < pCreateTableAttrList->entries(); i++)
{
checkFileOption((*pCreateTableAttrList)[i]);
}
}
else
{
// pCreateTableAttrList points to a single Create Table
// option (e.g., a partition clause, a file attributes
// clause, a location clause, etc.
checkFileOption(pCreateTableAttrList);
}
} // if (pCreateTableAttrList NEQ NULL)
return;
}
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkFileOption(ElemDDLNode * pTableOption)
{
ComASSERT(pTableOption NEQ NULL);
// STORE BY
if (pTableOption->castToElemDDLStoreOpt() NEQ NULL)
{
checkStoreByClause(pTableOption->castToElemDDLStoreOpt());
pStoreByOption_ = pTableOption->castToElemDDLStoreOpt()
->castToElemDDLStoreOptKeyColumnList();
}
//ATTRIBUTES
else if (pTableOption->castToElemDDLFileAttrClause() NEQ NULL)
{
checkFileAttributeClause(pTableOption->castToElemDDLFileAttrClause());
}
// LOCATION
else if (pTableOption->castToElemDDLLocation() NEQ NULL)
{
checkLocationClause(pTableOption->castToElemDDLLocation());
}
// DIVISION BY
else if (pTableOption->castToElemDDLDivisionClause() NEQ NULL)
{
checkDivisionByClause(pTableOption->castToElemDDLDivisionClause());
}
// PARTITION
else if (pTableOption->castToElemDDLPartitionClause() NEQ NULL)
{
checkPartitionDefinitionclause(
pTableOption->castToElemDDLPartitionClause());
}
// MVATTRIBUTES
else if (pTableOption->castToElemDDLMVFileAttrClause() NEQ NULL)
{
checkMVFileAttributeClause(pTableOption->castToElemDDLMVFileAttrClause());
}
else // error
{
switch (pTableOption->getOperatorType())
{
case ELM_FILE_ATTR_POS_NUM_PARTNS_ELEM:
case ELM_FILE_ATTR_POS_TABLE_SIZE_ELEM:
case ELM_FILE_ATTR_POS_DISK_POOL_ELEM:
{
*SqlParser_Diags << DgSqlCode (-3424);
break;
}
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
}
}
} // checkFileOption
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkStoreByClause(ElemDDLStoreOpt *pTableOption)
{
if (isStoreByClauseSpecified_)
{
// Duplicate STORE BY clauses.
*SqlParser_Diags << DgSqlCode(-3109);
}
isStoreByClauseSpecified_ = TRUE;
switch (pTableOption->getOperatorType())
{
// ALLOWED
case ELM_STORE_OPT_KEY_COLUMN_LIST_ELEM :
ComASSERT(pTableOption->castToElemDDLStoreOptKeyColumnList() NEQ NULL);
break;
// NOT ALLOWED
case ELM_STORE_OPT_DEFAULT_ELEM :
*SqlParser_Diags << DgSqlCode(-12040);
break;
case ELM_STORE_OPT_ENTRY_ORDER_ELEM:
*SqlParser_Diags << DgSqlCode(-12041);
break;
case ELM_STORE_OPT_NONDROPPABLE_PRIMARY_KEY_ELEM:
*SqlParser_Diags << DgSqlCode(-12042);
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
return; // exist this method
} // checkStoreByClause
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkFileAttributeClause(ElemDDLFileAttrClause *pTableOption)
{
if (isAttrClauseSpecified_)
{
// Duplicate file ATTRIBUTE(S) clauses.
*SqlParser_Diags << DgSqlCode(-3099);
}
isAttrClauseSpecified_ = TRUE;
ElemDDLNode * pFileAttrs = pTableOption->getFileAttrDefBody();
ComASSERT(pFileAttrs NEQ NULL);
for (CollIndex i = 0; i < pFileAttrs->entries(); i++)
{
checkFileAttribute((*pFileAttrs)[i]->castToElemDDLFileAttr());
}
}
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkFileAttribute(ElemDDLFileAttr * pFileAttr)
{
switch (pFileAttr->getOperatorType())
{
// ALLOWED
case ELM_FILE_ATTR_AUDIT_COMPRESS_ELEM :
case ELM_FILE_ATTR_BLOCK_SIZE_ELEM :
case ELM_FILE_ATTR_BUFFERED_ELEM :
case ELM_FILE_ATTR_CLEAR_ON_PURGE_ELEM :
case ELM_FILE_ATTR_COMPRESSION_ELEM :
case ELM_FILE_ATTR_D_COMPRESS_ELEM :
case ELM_FILE_ATTR_I_COMPRESS_ELEM :
case ELM_FILE_ATTR_MAX_SIZE_ELEM :
case ELM_FILE_ATTR_LOCK_ON_REFRESH_ELEM :
case ELM_FILE_ATTR_MVS_ALLOWED_ELEM :
case ELM_FILE_ATTR_EXTENT_ELEM :
case ELM_FILE_ATTR_MAXEXTENTS_ELEM :
case ELM_FILE_ATTR_ROW_FORMAT_ELEM :
case ELM_FILE_ATTR_OWNER_ELEM :
break;
// NOT ALLOWED
case ELM_FILE_ATTR_ALLOCATE_ELEM :
*SqlParser_Diags << DgSqlCode(-12047);
break;
case ELM_FILE_ATTR_AUDIT_ELEM :
*SqlParser_Diags << DgSqlCode(-12050);
break;
case ELM_FILE_ATTR_DEALLOCATE_ELEM :
*SqlParser_Diags << DgSqlCode(-12051);
break;
case ELM_FILE_ATTR_RANGE_LOG_ELEM:
*SqlParser_Diags << DgSqlCode(-12062);
break;
case ELM_FILE_ATTR_INSERT_LOG_ELEM:
*SqlParser_Diags << DgSqlCode(-12063);
break;
case ELM_FILE_ATTR_MV_COMMIT_EACH_ELEM: // cannot be
case ELM_FILE_ATTR_MVAUDIT_ELEM: // cannot be
default :
NAAbort("StmtDDLCreate.CPP", __LINE__, "internal logic error");
break;
}
}
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkLocationClause(ElemDDLLocation *pTableOption)
{
if (isLocationClauseSpecified_)
{
// Duplicate LOCATION clauses.
*SqlParser_Diags << DgSqlCode(-3098);
}
isLocationClauseSpecified_ = TRUE;
if (NOT pTableOption->getPartitionName().isNull())
*SqlParser_Diags << DgSqlCode(-3405);
}
//----------------------------------------------------------------------------
void StmtDDLCreateMV::checkDivisionByClause(ElemDDLDivisionClause *pDivisionByParseNode)
{
if (isDivisionByClauseSpecified_)
{
// Error 3183 - Duplicate $0~string0 clauses were specified.
*SqlParser_Diags << DgSqlCode(-3183)
<< DgString0("DIVISION BY");
}
pDivisionByClauseParseNode_ = pDivisionByParseNode;
isDivisionByClauseSpecified_ = TRUE;
}
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkPartitionDefinitionclause(
ElemDDLPartitionClause *pTableOption)
{
if (isPartitionDefinitionSpecified_ || isPartitionByClauseSpecified_)
{
// Duplicate PARTITION clauses.
*SqlParser_Diags << DgSqlCode(-3103)
<< DgString0("PARTITION");
}
isPartitionDefinitionSpecified_ = TRUE;
//
// Initializes pPartitionByOption to point to the parse node
// representing the definition of partition by columns (class
// ElemDDLPartitionByOpt).
//
ElemDDLNode *pPartitionByOption = pTableOption->getPartitionByOption();
if(pPartitionByOption NEQ NULL)
{
// If the Partition By Option is specified, set the flag and copy
// the pointers to column parse nodes to partitionKeyColRefArray_.
if(pPartitionByOption->castToElemDDLPartitionByOpt() NEQ NULL)
{
isPartitionByClauseSpecified_ = TRUE;
switch (pPartitionByOption->getOperatorType())
{
case ELM_PARTITION_BY_COLUMN_LIST_ELEM :
ComASSERT(pPartitionByOption->castToElemDDLPartitionByColumnList()
NEQ NULL);
{
//
// Copies array of pointers pointing to Column parse nodes to
// PartitionKeyColRefArray_ so the user of this object can access
// the information easier.
//
ElemDDLNode * pPartitionByCols = pPartitionByOption->
castToElemDDLPartitionByColumnList()->getPartitionKeyColumnList();
NABoolean columnOrderingSpecified = FALSE;
for (CollIndex index = 0; index < pPartitionByCols->entries(); index++)
{
ComASSERT((*pPartitionByCols)[index]->castToElemDDLColRef() NEQ NULL);
// Report error if ordering was specified for any column.
if ((*pPartitionByCols)[index]->castToElemDDLColRef()->isColumnOrderingSpecified())
{
// It is not allowed to specify ordering for columns of a partitioning key clause.
// Report an error only once for the column list - not for each offending column.
if (NOT columnOrderingSpecified)
{
*SqlParser_Diags << DgSqlCode(-3199)
<< DgString0((*pPartitionByCols)[index]->castToElemDDLColRef()->getColumnName());
columnOrderingSpecified = TRUE;
}
}
partitionKeyColRefArray_.insert(
(*pPartitionByCols)[index]->castToElemDDLColRef());
}
}
break;
default :
NAAbort("StmtDDLCreate.C", __LINE__, "internal logic error");
break;
} // switch
}
} // if(pPartitionByOption NEQ NULL)
}
//----------------------------------------------------------------------------
void
StmtDDLCreateMV::checkMVFileAttributeClause(
ElemDDLMVFileAttrClause *pTableOption)
{
if(TRUE == isMVAttributeClauseSpecified_)
{
// Duplicate MVATTRIBUTES clauses.
*SqlParser_Diags << DgSqlCode(-12060);
}
isMVAttributeClauseSpecified_ = TRUE;
}
//----------------------------------------------------------------------------
void StmtDDLCreateMV::extractMvAttributesFromFileOptions()
{
if(FALSE == isMVAttributeClauseSpecified_ ||
NULL == getChild(INDEX_FILE_OPTIONS_CLAUSE) )
{
return;
}
ElemDDLNode *pCreateTableAttrList =
getChild(INDEX_FILE_OPTIONS_CLAUSE)->castToElemDDLNode();
ComASSERT(pCreateTableAttrList NEQ NULL);
ElemDDLMVFileAttrClause* pAttribs = NULL;
if (pCreateTableAttrList->castToElemDDLOptionList() NEQ NULL)
{
for (CollIndex i = 0; i < pCreateTableAttrList->entries(); i++)
{
if (NULL !=
((*pCreateTableAttrList)[i])->castToElemDDLMVFileAttrClause())
{
pAttribs = ((*pCreateTableAttrList)[i])->
castToElemDDLMVFileAttrClause();
}
}
}
else
{
// pCreateTableAttrList points to a single Create Table
// option. this has to be the MVATTRIBUTE CLAUSE.
pAttribs = pCreateTableAttrList->castToElemDDLMVFileAttrClause();
ComASSERT(NULL != pAttribs);
}
ComASSERT(NULL != pAttribs);
ElemDDLNode * pFileAttrs = pAttribs ->getFileAttrDefBody();
ComASSERT(pFileAttrs NEQ NULL);
NABoolean mvAuditSpecified(FALSE);
NABoolean commitEachSpecified(FALSE);
for (CollIndex j = 0; j < pFileAttrs->entries(); j++)
{
ElemDDLFileAttr* pAttr =
(*pFileAttrs)[j]->castToElemDDLFileAttr();
switch (pAttr->getOperatorType())
{
case ELM_FILE_ATTR_MVAUDIT_ELEM:
if(TRUE == mvAuditSpecified)
{
*SqlParser_Diags << DgSqlCode(-12061);
}
mvAuditType_ =
(pAttr->castToElemDDLFileAttrMvAudit())
->getMvAuditType();
mvAuditSpecified = TRUE;
break;
case ELM_FILE_ATTR_MV_COMMIT_EACH_ELEM:
if(TRUE == commitEachSpecified)
{
*SqlParser_Diags << DgSqlCode(-12059);
}
commitEachNRows_ =
(pAttr->castToElemDDLFileAttrMVCommitEach())
->getNRows();
commitEachSpecified = TRUE;
break;
}
}
return;
} // StmtDDLCreateMV::extractMvAttributesFromFileOptions
//
// methods for tracing
//
const NAString
StmtDDLCreateMV::displayLabel1() const
{
return NAString("MV name: ") + getMVName();
}
NATraceList
StmtDDLCreateMV::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
detailTextList.append(displayLabel1()); // display name of defined view
//
// displays list of column names
//
CollIndex i, nbrCols;
const ElemDDLColViewDefArray & colsList = getMVColDefArray();
ElemDDLColViewDef * col;
nbrCols = colsList.entries();
if (nbrCols EQU 0)
{
detailTextList.append("No columns.");
}
else
{
detailText = "Column list [";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " column(s)]:";
detailTextList.append(detailText);
for (i = 0; i < nbrCols; i++)
{
col = colsList[i];
detailText = "[column ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", col->getDetailInfo());
}
} // else (nbrCols EQU 0) of column references
return detailTextList;
}
const NAString
StmtDDLCreateMV::getText() const
{
return "StmtDDLCreateMV";
}
// -----------------------------------------------------------------------
// methods for class StmtDDLCreateView
// -----------------------------------------------------------------------
//
// constructor
//
StmtDDLCreateView::StmtDDLCreateView(const QualifiedName & viewQualName,
const ParNameLocList & nameLocList,
ElemDDLNode * optionalViewColumnList,
ElemDDLNode * optionalLocationClause,
RelExpr * queryExpression,
ElemDDLNode * optionalWithCheckOption,
ComCreateViewBehavior createViewBehavior,
ElemDDLNode *pOwner,
CollHeap * heap)
: StmtDDLNode(DDL_CREATE_VIEW),
viewQualName_(viewQualName, heap),
isUpdatable_(FALSE),
isInsertable_(FALSE),
nameLocList_(nameLocList, heap),
startPos_(nameLocList.getTextStartPosition()),
endPos_(0), // will be set later by function ParSetTextEndPos()
isLocationClauseSpec_(FALSE),
locationName_(heap),
locationNameType_(ElemDDLLocation::LOCATION_DEFAULT_NAME_TYPE),
createViewBehavior_(createViewBehavior),
checkOptionLevel_(COM_UNKNOWN_LEVEL),
pViewColumnList_(optionalViewColumnList),
pLocationClause_(optionalLocationClause),
pQueryExpression_(queryExpression),
pWithCheckOption_(optionalWithCheckOption),
columnDefArray_(heap),
viewUsages_(heap),
udfList_(heap)
{
setChild(INDEX_VIEW_OWNER, pOwner);
}
//
// virtual destructor
//
StmtDDLCreateView::~StmtDDLCreateView()
{
// delete all children
for (Int32 i = 0; i < getArity(); i++)
{
delete getChild(i);
}
}
//
// cast
//
StmtDDLCreateView *
StmtDDLCreateView::castToStmtDDLCreateView()
{
return this;
}
//
// accessors
//
Int32
StmtDDLCreateView::getArity() const
{
return MAX_STMT_DDL_CREATE_VIEW_ARITY;
}
ExprNode *
StmtDDLCreateView::getChild(Lng32 index)
{
switch (index)
{
case INDEX_VIEW_COLUMN_LIST :
return pViewColumnList_;
case INDEX_LOCATION_CLAUSE :
return pLocationClause_;
case INDEX_QUERY_EXPRESSION :
return pQueryExpression_;
case INDEX_WITH_CHECK_OPTION :
return pWithCheckOption_;
case INDEX_VIEW_OWNER :
return pOwner_;
default :
ABORT("internal logic error");
return 0;
}
}
//
// mutators
//
void
StmtDDLCreateView::incrCurViewColNum()
{
if (isProcessingViewColList())
{
setCurViewColNum(getCurViewColNum()+(CollIndex)1);
}
else
{
setCurViewColNum((CollIndex)0);
}
}
void
StmtDDLCreateView::setChild(Lng32 index, ExprNode * pChildNode)
{
switch (index)
{
case INDEX_VIEW_COLUMN_LIST :
if (pChildNode NEQ NULL)
{
pViewColumnList_ = pChildNode->castToElemDDLNode();
ComASSERT(pViewColumnList_ NEQ NULL);
}
else
{
pViewColumnList_ = NULL;
}
break;
case INDEX_LOCATION_CLAUSE :
if (pChildNode NEQ NULL)
{
pLocationClause_ = pChildNode->castToElemDDLNode();
ComASSERT(pLocationClause_ NEQ NULL);
}
else
{
pLocationClause_ = NULL;
}
break;
case INDEX_QUERY_EXPRESSION :
if (pChildNode NEQ NULL)
{
pQueryExpression_ = pChildNode->castToRelExpr();
ComASSERT(pQueryExpression_ NEQ NULL);
}
else
{
pQueryExpression_ = NULL;
}
break;
case INDEX_WITH_CHECK_OPTION :
if (pChildNode NEQ NULL)
{
pWithCheckOption_ = pChildNode->castToElemDDLNode();
ComASSERT(pWithCheckOption_ NEQ NULL);
}
else
{
pWithCheckOption_ = NULL;
}
break;
case INDEX_VIEW_OWNER :
if (pChildNode NEQ NULL)
{
ElemDDLNode *pTemp = pChildNode->castToElemDDLNode();
ComASSERT(pTemp NEQ NULL);
pOwner_ = pTemp->castToElemDDLGrantee();
ComASSERT(pOwner_ NEQ NULL);
}
else
{
pOwner_ = NULL;
}
break;
default :
ABORT("internal logic error");
}
}
void
StmtDDLCreateView::synthesize()
{
//
// Collects pointers to column name parser nodes for easier access
//
if (pViewColumnList_ NEQ NULL)
{
for (Int32 i = 0; i < (Int32)pViewColumnList_->entries(); i++)
{
ComASSERT((*pViewColumnList_)[i] NEQ NULL);
columnDefArray_.insert((*pViewColumnList_)[i]->
castToElemDDLColViewDef());
}
}
//
// Collects information from the Location clause if it appears
//
if (pLocationClause_ NEQ NULL)
{
isLocationClauseSpec_ = TRUE;
ElemDDLLocation * pLoc = pLocationClause_->castToElemDDLLocation();
ComASSERT(pLoc NEQ NULL);
if (NOT pLoc->getPartitionName().isNull())
*SqlParser_Diags << DgSqlCode(-3405);
locationName_ = pLoc->getLocationName();
locationNameType_ = pLoc->getLocationNameType();
}
//
// Collects information from With Check Option parser node if it exists
//
if (pWithCheckOption_ NEQ NULL)
{
ElemDDLWithCheckOption * pWCkOpt = pWithCheckOption_->
castToElemDDLWithCheckOption();
ComASSERT(pWCkOpt NEQ NULL);
checkOptionLevel_ = pWCkOpt->getLevel();
}
} // StmtDDLCreateView::synthesize()
//
// methods for tracing
//
const NAString
StmtDDLCreateView::displayLabel1() const
{
return NAString("View name: ") + getViewName();
}
const NAString
StmtDDLCreateView::displayLabel2() const
{
return NAString("is With Ck Opt spec? ") +
YesNo(isWithCheckOptionSpecified());
}
const NAString
StmtDDLCreateView::displayLabel3() const
{
if (isWithCheckOptionSpecified())
{
ElemDDLWithCheckOption * pWCkOpt = pWithCheckOption_->
castToElemDDLWithCheckOption();
ComASSERT(pWCkOpt NEQ NULL);
return NAString("check option level: ") + pWCkOpt->getLevelAsNAString();
}
else
{
return NAString();
}
}
NATraceList
StmtDDLCreateView::getDetailInfo() const
{
NAString detailText;
NATraceList detailTextList;
detailTextList.append(displayLabel1()); // display name of defined view
detailTextList.append(displayLabel2()); // is With Check Option specified?
if (NOT displayLabel3().isNull())
{
detailTextList.append(displayLabel3()); // display Check Option level
}
//
// displays list of column names
//
CollIndex i, nbrCols;
const ElemDDLColViewDefArray & colsList = getViewColDefArray();
ElemDDLColViewDef * col;
nbrCols = colsList.entries();
if (nbrCols EQU 0)
{
detailTextList.append("No columns.");
}
else
{
detailText = "Column list [";
detailText += LongToNAString((Lng32)nbrCols);
detailText += " column(s)]:";
detailTextList.append(detailText);
for (i = 0; i < nbrCols; i++)
{
col = colsList[i];
detailText = "[column ";
detailText += LongToNAString((Lng32) i);
detailText += "]";
detailTextList.append(detailText);
detailTextList.append(" ", col->getDetailInfo());
}
} // else (nbrCols EQU 0) of column references
return detailTextList;
}
const NAString
StmtDDLCreateView::getText() const
{
return "StmtDDLCreateView";
}
/*****************************************************
// -----------------------------------------------------------------------
// non-inline methods for class ViewUsages
// -----------------------------------------------------------------------
//
// virtual destructor
//
ViewUsages::~ViewUsages()
{
}
//
// accessors
//
const QualifiedName *
ViewUsages::getUsedTableNamePtr(const QualifiedName &tableName) const
{
for (CollIndex i = 0; i < usedTableNameList_.entries(); i++)
{
if (usedTableNameList_[i] EQU tableName)
{
return &usedTableNameList_[i];
}
}
return NULL;
}
//
// mutators
//
void
ViewUsages::insertUsedTableName(const QualifiedName &tableName)
{
const QualifiedName *pTableName = getUsedTableNamePtr(tableName);
if (pTableName EQU NULL) // not found
{
// ok to insert
usedTableNameList_.insert(tableName);
}
}
*****************************************************/
// -----------------------------------------------------------------------
// Methods for class StmtDDLCommentOn
// -----------------------------------------------------------------------
//
// Constructor
//
StmtDDLCommentOn::StmtDDLCommentOn(COMMENT_ON_TYPES objType, const QualifiedName & objName, const NAString & commentStr, CollHeap * heap)
: StmtDDLNode(DDL_COMMENT_ON),
type_(objType),
objectName_(objName, heap),
comment_(commentStr),
colRef_(NULL),
isViewCol_(FALSE),
colNum_(0)
{
}
StmtDDLCommentOn::StmtDDLCommentOn(COMMENT_ON_TYPES objType, const QualifiedName & objName, const NAString & commentStr, ColReference * colRef, CollHeap * heap)
: StmtDDLNode(DDL_COMMENT_ON),
type_(objType),
objectName_(objName, heap),
colRef_(colRef),
comment_(commentStr),
isViewCol_(FALSE),
colNum_(0)
{
}
StmtDDLCommentOn::~StmtDDLCommentOn()
{
}
StmtDDLCommentOn * StmtDDLCommentOn::castToStmtDDLCommentOn()
{
return this;
}
/* add escape quote for single quote */
NAString StmtDDLCommentOn::getCommentEscaped()
{
NAString ret(comment_);
int idx = ret.length() - 1;
for (; idx >= 0; idx--)
{
if (ret[idx] == '\'')
ret.insert(idx, "'");
}
return ret;
}
//
// End of File
//