blob: 2a73a489a3d0f9bfdcefa76c9f919d3086430168 [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 @@@
**********************************************************************/
#include "string.h"
#include "CompException.h"
#include "NAInternalError.h"
#include "CmpEHCallBack.h"
BaseException::BaseException(const char *fileName, UInt32 lineNum)
: lineNum_(lineNum)
{
if(fileName) {
strncpy(fileName_, fileName, sizeof(fileName_));
fileName_[sizeof(fileName_)-1] = 0;
}
else {
fileName_[0] = 0;
}
}
BaseException::BaseException() : lineNum_(0)
{ fileName_[0] = 0; }
UInt32 BaseException::getLineNum()
{ return lineNum_; }
const char * BaseException::getFileName()
{ return fileName_; }
// Optinally hook the Debugger when something is wrong.
void BaseException::doFFDCDebugger(char * msg)
{
makeTFDSCall(msg, fileName_, lineNum_);
hookDebugger();
}
void BaseException::hookDebugger()
{
static NABoolean firstTime = TRUE;
static NABoolean invokeDebugger = FALSE;
if(invokeDebugger)
hookDebuggerHelper();
}
void BaseException::hookDebuggerHelper()
{
MessageBox( NULL,
"An Internal Error Found, Attach Debugger Now",
"NonStop SQL/MX",
MB_OK|MB_ICONINFORMATION );
// DebugBreak() stop the MSDEV when the user is in the MSDEV debugger
// DebugBreak() terminates MXCMP when the user is not in the MSDEV debugger
// and the standard breakpoint exception handler is in place.
DebugBreak();
}
// UserException Implementation
UserException::UserException(const char *fileName, UInt32 lineNum)
: BaseException(fileName, lineNum)
{
}
void UserException::throwException()
{
throw *this;
}
DDLException::DDLException(Int32 sqlcode, const char *fileName, UInt32 lineNum)
: BaseException(fileName, lineNum),
sqlcode_ (sqlcode)
{
}
void DDLException::throwException()
{
throw *this;
}
// FatalException Implementation
FatalException::FatalException(const char *msg,
const char *fileName,
UInt32 lineNum,
const char *stackTrace)
: BaseException(fileName, lineNum)
{
int len = 0;
if(msg && (len = strlen(msg))) {
len = MINOF(len,EXCEPTION_MSG_SIZE);
strncpy(msg_, msg, len);
msg_[len] = 0;
}
else {
msg_[0] = 0;
}
if(stackTrace && (len = strlen(stackTrace))) {
len = MINOF(len, STACK_TRACE_SIZE);
strncpy(stackTrace_, stackTrace, len);
stackTrace_[len] = 0;
}
else {
stackTrace_[0] = 0;
}
}
const char * FatalException::getMsg()
{ return msg_; }
const char * FatalException::getStackTrace()
{ return stackTrace_; }
void FatalException::throwException()
{
doFFDCDebugger(msg_);
throw *this;
}
// CmpInternalException Implementation
CmpInternalException::CmpInternalException(const char *msg,
const char *fileName,
UInt32 lineNum)
: BaseException(fileName, lineNum)
{
if(msg) {
strncpy(msg_, msg, EXCEPTION_MSG_SIZE);
msg_[EXCEPTION_MSG_SIZE-1] = 0;
}
else {
msg_[0] = 0;
}
}
const char * CmpInternalException::getMsg()
{ return msg_; }
void CmpInternalException::throwException()
{
doFFDCDebugger(msg_);
throw *this;
}
// AssertException Implementation
AssertException::AssertException(const char *condition,
const char *fileName,
UInt32 lineNum,
const char *stackTrace)
: BaseException(fileName, lineNum)
{
int len = 0;
if(condition && (len = strlen(condition))) {
len = MINOF(len ,EXCEPTION_CONDITION_SIZE);
strncpy(condition_, condition, len);
condition_[len] = 0;
}
else {
condition_[0] = 0;
}
if(stackTrace && (len = strlen(stackTrace))) {
len = MINOF(len, STACK_TRACE_SIZE);
strncpy(stackTrace_, stackTrace, len );
stackTrace_[len] = 0;
}
else {
stackTrace_[0] = 0;
}
}
AssertException::AssertException(AssertException & e) :
BaseException(e.getFileName(), e.getLineNum())
{
int len = 0;
const char *condition = e.getCondition();
if(condition && (len = strlen(condition))) {
len = MINOF(len , EXCEPTION_CONDITION_SIZE);
strncpy(condition_, condition, len);
condition_[len] = 0;
}
else {
condition_[0] = 0;
}
const char *stackTrace = e.getStackTrace();
if(stackTrace && (len = strlen(stackTrace))) {
len = MINOF(len, STACK_TRACE_SIZE);
strncpy(stackTrace_, stackTrace, len);
stackTrace_[len] = 0;
}
else {
stackTrace_[0] = 0;
}
}
const char * AssertException::getCondition()
{ return condition_; }
const char * AssertException::getStackTrace()
{ return stackTrace_; }
void AssertException::throwException()
{
doFFDCDebugger(condition_);
throw *this;
}
OsimLogException::OsimLogException(const char * errMsg,
const char * srcFileName,
UInt32 srcLineNum)
: BaseException (srcFileName, srcLineNum)
{
errMsg_[0] = 0;
if(errMsg){
strcpy(errMsg_,errMsg);
}
}
void OsimLogException::throwException()
{
throw *this;
}
// PassOneAssertFatalException Implementation
PassOneAssertFatalException::PassOneAssertFatalException(const char *condition,
const char *fileName,
UInt32 lineNum)
: FatalException("Assertion occurred in optimizer pass one",
fileName,
lineNum)
{
if(condition) {
strncpy(condition_, condition, EXCEPTION_CONDITION_SIZE);
condition_[EXCEPTION_CONDITION_SIZE-1] = 0;
}
else {
condition_[0] = 0;
}
}
void PassOneAssertFatalException::throwException()
{
doFFDCDebugger(condition_);
throw *this;
}
// PassOneNoPlanFatalException Implementation
PassOneNoPlanFatalException::PassOneNoPlanFatalException(const char *fileName,
UInt32 lineNum)
: FatalException("Cannot produce a plan in optimizer pass one",
fileName,
lineNum) {}
void PassOneNoPlanFatalException::throwException()
{
doFFDCDebugger((char *)getMsg());
throw *this;
}
// PassOneSkippedPassTwoNoPlanFatalException
PassOneSkippedPassTwoNoPlanFatalException::
PassOneSkippedPassTwoNoPlanFatalException(const char *fileName,
UInt32 lineNum) :
FatalException("Pass one skipped, but cannot produce a plan in pass two",
fileName,
lineNum) {}
void PassOneSkippedPassTwoNoPlanFatalException::throwException()
{
doFFDCDebugger((char *)getMsg());
throw *this;
}
// OptAssertException Implementation
OptAssertException::OptAssertException(AssertException & e, Lng32 taskCount) :
AssertException(e),
taskCount_(taskCount) {}
void OptAssertException::throwException()
{
doFFDCDebugger((char *)getCondition());
throw *this;
}
// CmpExceptionCallBack Implementation
void CmpExceptionCallBack::throwFatalException(const char *msg,
const char *file,
UInt32 line,
const char *stackTrace)
{ FatalException(msg, file, line, stackTrace).throwException(); }
void CmpExceptionCallBack::throwAssertException(const char *cond,
const char *file,
UInt32 line,
const char *stackTrace)
{ AssertException(cond, file, line, stackTrace).throwException(); }
CmpExceptionCallBack CmpExceptionEnv::eCallBack_;
void CmpExceptionEnv::registerCallBack()
{ NAInternalError::registerExceptionCallBack(&eCallBack_); }
void CmpExceptionEnv::unRegisterCallBack()
{ NAInternalError::unRegisterExceptionCallBack(); }