blob: 18aa81b72ce408930004d44acef8de37620e521b [file] [log] [blame]
/**********************************************************************
// @@@ 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: StmtNode.C
* Description: Stmt nodes
* Created: 3/6/95
* Language: C++
*
*
*
*
******************************************************************************
*/
#include "charinfo.h"
#include "ComOptIncludes.h"
#include "SchemaDB.h"
#include "StmtNode.h"
void action::setActionLabel(MBD_ACTION newAction, const NAString &newLabel)
{
theAction = newAction;
theLabel = newLabel;
}
// -----------------------------------------------------------------------
// methods for class StmtNode
// -----------------------------------------------------------------------
Int32 StmtNode::getArity() const { return 0; }
StmtNode * StmtNode::castToStatementExpr()
{
return this;
}
const StmtNode * StmtNode::castToStatementExpr() const
{
return this;
}
RelExpr * StmtNode::getQueryExpression() const { return NULL; }
ExprNode * StmtNode::getChild(Lng32 /* index */)
{
assert(0 == 1);
return NULL;
} // StmtNode::getChild()
void StmtNode::setChild(Lng32 /* index */, ExprNode * /* newChild */)
{
assert(0 == 1);
} // StmtNode::setChild()
// -----------------------------------------------------------------------
// methods for class StmtQuery
// -----------------------------------------------------------------------
Int32 StmtQuery::getArity() const { return 1; }
RelExpr * StmtQuery::getQueryExpression() const { return queryExpr_; }
ExprNode * StmtQuery::getChild(Lng32 index)
{
assert(index == 0);
return getQueryExpression();
} // StmtNode::getChild()
void StmtQuery::setChild(Lng32 index, ExprNode * newChild)
{
assert(index == 0);
assert(newChild->castToRelExpr());
queryExpr_ = newChild->castToRelExpr();
} // StmtQuery::setChild()
const NAString StmtQuery::getText() const
{
return "StmtQuery";
} // StmtQuery::getText()
void StmtQuery::print(FILE * f,
const char * prefix,
const char *) const
{
// print operator text
fprintf(f,"%sExprNode(%s)\n", prefix, (const char *) getText());
}
// -----------------------------------------------------------------------
// methods for class StmtModule
// -----------------------------------------------------------------------
// Apply defaults to self, and then (ANSI 12.1 SR 3) apply self to SchemaDB.
NABoolean StmtModule::applyDefaults(NABoolean wantR18behavior)
{
NABoolean err = FALSE;
if (charSet().isNull())
charSet() = CharInfo::getCharSetName(CharInfo::DefaultCharSet);
if (CharInfo::isCharSetSupported(charSet())) {
// Get charset name in canonical format (the name of the enum of the name).
charSet() = CharInfo::getCharSetName(CharInfo::getCharSetEnum(charSet()));
}
else {
*CmpCommon::diags() << DgSqlCode(-3010) << DgString0(charSet());
err = TRUE;
}
if (!CharInfo::isModuleCharSetSupported(CharInfo::getCharSetEnum(charSet())))
{
*CmpCommon::diags() << DgSqlCode(-3404) << DgString0(charSet());
err = TRUE;
}
// Here we're using internal-format names
if (name().getCatalogName().isNull()) {
// Must be an Ansi name, not an MPLOC.
const SchemaName& defcs =
ActiveSchemaDB()->getDefaultSchema(
SchemaDB::REFRESH_CACHE | SchemaDB::FORCE_ANSI_NAMETYPE);
if (name().getSchemaName().isNull()) {
if (name().getObjectName().isNull()) {
name().setObjectName("SQLMX_DEFAULT_MODULE_");
}
name().setSchemaName(defcs.getSchemaName());
}
name().setCatalogName(defcs.getCatalogName());
}
if (wantR18behavior) {
// And now we use external-format names, for the ANSI 12.1 SR 3 stuff.
NAString catName(name().getCatalogNameAsAnsiString());
if (!ActiveSchemaDB()->getDefaults().setCatalog(catName))
err = TRUE;
NAString schName(name().getUnqualifiedSchemaNameAsAnsiString());
if (!ActiveSchemaDB()->getDefaults().setSchema(schName))
err = TRUE;
}
else { // want R2 (correct) behavior
// We used to take the catalog & schema of the module directive and apply
// them above as the default catalog & schema. This was a misguided
// attempt to "use external-format names, for the ANSI 12.1 SR 3 stuff"
// in the SQL92 std.
//
// In SQL99, this has been clarified in section 13.1 of ISO/IEC FDIS
// 9075-2:1999 (aka the 1999 Foundation doc) where syntax rules 3 & 4
// specify that:
//
// "If the explicit or implicit <schema name> does not specify a <catalog
// name>, then an implementation-defined <catalog name> is implicit."
//
// "The implicit or explicit <catalog name> is the implicit <catalog name>
// for all unqualified <schema name>s in the <SQL-client module
// definition>."
//
// Three observations may be worth pointing out here:
// 1) SQL/MX client modules do not have a <module authorization clause> as
// specified by the SQL99 std.
// 2) Even if (in the future) SQL/MX tries to conform to the SQL99 std for
// client module definition(s), the SQL99 std itself (syntax rule 3)
// allows us to use "an implementation-defined <catalog name>" to
// implicitly qualify unqualified <schema name>s.
// 3) This current "implementation is a deviation from ANSI in
// that the module name is a 3-part name. This deviation and the use of
// cat/sch name to qualify unqualified SQL objects in the module are
// also 'valid' implementation of the 2 syntax rules 13.1, rules 3 & 4
// of ANSI."
// Similar logic can be applied to using an implementation-defined
// <schema name> to implicitly qualify unqualified table names, etc.
//
// In other words, our technique of using CQD default CATALOG & SCHEMA
// settings to qualify unqualified table names, view names, etc is allowed
// for by the SQL99 std.
//
// Deleting the old code that was here is part of the fix to genesis
// cases 10-030725-8215, 10-030730-8326, 10-030826-0792.
}
return err;
}
NABoolean StmtModule::unparse(NAString &result, NABoolean wantR18behavior)
{
NABoolean err = applyDefaults(wantR18behavior);
result += NAString("MODULE ") +
name().getQualifiedNameAsAnsiNTFilenameString() +
" NAMES ARE " + charSet() + ";";
return err;
}
NABoolean StmtModule::unparseSimple(NAString &result,
NABoolean wantR18behavior)
{
NABoolean err = applyDefaults(wantR18behavior);
// assume caller will handle err
result += NAString("MODULE ") +
name().getQualifiedNameAsAnsiString() +
" NAMES ARE " + charSet() + ";";
return err;
}
void StmtModule::applyModuleCatalogSchema(const NAString& cat,
const NAString& sch)
{
// apply moduleCatalog if necessary
if (name().getCatalogName().isNull()) {
if (!cat.isNull())
name().setCatalogName(cat);
}
// apply moduleSchema if necessary
if (name().getSchemaName().isNull()) {
if (!sch.isNull())
name().setSchemaName(sch);
}
// module catalog & schema must be non-null now. Otherwise, a fatal
// exception can occur in mxsqlc/mxsqlco in
// mod_def::setModule() --> mod_def::outputModule()
// --> StmtModule::unparseSimple() -->
// QualifiedName::getQualifiedNameAsAnsiString() -->
// QualifiedName::getQualifiedNameAsString() -->
// CMPASSERT(NOT getSchemaName().isNull());
// as reported in genesis case 10-030708-8735.
if (name().getCatalogName().isNull() || name().getSchemaName().isNull()) {
const SchemaName& defcs =
ActiveSchemaDB()->getDefaultSchema(
SchemaDB::REFRESH_CACHE | SchemaDB::FORCE_ANSI_NAMETYPE);
if (name().getCatalogName().isNull())
name().setCatalogName(defcs.getCatalogName());
if (name().getSchemaName().isNull())
name().setSchemaName(defcs.getSchemaName());
}
}
// -----------------------------------------------------------------------
// methods for ...
// -----------------------------------------------------------------------
/* The constructor for StmtAllocStaticDesc */
/* just takes its arguments and initializes the */
/* private data members from them. Rather straightforward. */
StmtAllocStaticDesc::StmtAllocStaticDesc( NamePlusDesc* namePlusDescPtr,
StmtOrCursEnum theTag,
NAString* theName) : StmtNode(STM_ALLOC_STATIC_DESC),
mainDescriptor(namePlusDescPtr),
entityTag(theTag),
entityName( theTag == NAME_ABSENT ? NULL : theName)
{ }
NamePlusDesc::NamePlusDesc(NAString* descName,
NABoolean isInputFlag,
DescTypeList* theArray) :
descriptorName(descName), isInput(isInputFlag), descriptorArray(theArray)
{ }
StmtDeclStatCurs::StmtDeclStatCurs(NAString* new_curs_name,
RelExpr* new_curs_spec,
NABoolean holdable // QSTUFF
) :
StmtNode(STM_DECL_STATCURS, holdable),
cursorName(new_curs_name),
cursorSpec(new_curs_spec)
{ }
StmtDeclDynCurs::StmtDeclDynCurs(NAString* new_curs_name,
NAString* new_stmt_name,
NABoolean holdable // QSTUFF
) :
StmtNode(STM_DECL_DYNCURS, holdable),
cursorName(new_curs_name),
stmtName(new_stmt_name)
{ }
designation::designation(designator_tag newTag)
{
assert(newTag != DT_DESCRIPTOR);
theTag = newTag;
descName = NULL;
}
designation::designation()
{
descName = NULL;
theTag = DT_NULL;
}
designation::designation(NAString* newDescName)
{
if (newDescName == NULL)
{
descName = NULL;
theTag = DT_DESC_VIA_HV;
}
else
{
descName = newDescName;
theTag = DT_DESCRIPTOR;
}
}
StaticDescItem::StaticDescItem(ConstValue* newLiteral)
{
assert(newLiteral != NULL);
literalPointer = newLiteral;
dataTypePointer = NULL;
}
StaticDescItem::StaticDescItem(HostVarExprType *dataPtr)
{
assert(dataPtr!=NULL);
literalPointer = NULL;
dataTypePointer = dataPtr;
}
StaticDescItem::~StaticDescItem()
{
delete literalPointer;
delete dataTypePointer;
}
NABoolean StaticDescItem::isDataTypePointer () const
{
return (dataTypePointer!=NULL);
}
NABoolean StaticDescItem::isLiteralPointer () const
{
return (literalPointer != NULL);
}
ConstValue *StaticDescItem::getConstValuePtr ()
{
ConstValue *returnValue = literalPointer;
assert(returnValue!=NULL);
literalPointer = NULL;
return returnValue;
}
HostVarExprType *StaticDescItem::getDataTypePtr ()
{
HostVarExprType *returnValue = dataTypePointer;
assert(returnValue != NULL);
dataTypePointer = NULL;
return returnValue;
}
StmtDescBase::~StmtDescBase()
{
delete descriptorName;
}