blob: 5be9ef4c425a5811a9373abba146cb88f36b9297 [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: arkcmp.cpp
* Description: This is the main program for arkcmp process. The tasks for
* this process is to :
* . dynamic compile - process requests from executor
* . static compile - invoked from c89, compile Module definition
* file into module file.
* . interface to SQLCAT - DDL.
*
* Created: 06/20/96
* Language: C++
*
*
*
*****************************************************************************
*/
#include "Platform.h"
#include "NewDel.h"
#include <fstream>
#include <string.h>
#include "seabed/ms.h"
#include "seabed/fs.h"
extern void my_mpi_fclose();
#include "SCMVersHelp.h"
DEFINE_DOVERS(tdm_arkcmp)
#include "CmpMessage.h"
#include "CmpConnection.h"
#include "CmpContext.h"
#include "CmpCommon.h"
#include "CmpStoredProc.h"
#include "CmpErrLog.h"
#include "CompException.h"
#include "cmpargs.h"
#include "logmxevent.h"
#include "QCache.h"
#include "QueryCacheSt.h"
#include "NATableSt.h"
#include "ComCextdecs.h"
#define CLI_DLL
#include "SQLCLIdev.h"
#undef CLI_DLL
#include "EHException.h"
#include "CmpEHCallBack.h"
#include "Globals.h"
#include "ObjectNames.h"
#include "CmpISPInterface.h"
#include "QRLogger.h"
THREAD_P jmp_buf ExportJmpBuf;
ostream &operator<<(ostream &dest, const ComDiagsArea& da);
extern CmpISPInterface cmpISPInterface;
// The following global is defined in CmpConnection.cpp
extern THREAD_P NABoolean CmpMainISPConnection;
// mainNewHandler_CharSave and mainNewHandler are used in the error
// handling when running out of virtual memory for the main program.
//
// Save 4K bytes of memory for the error handling when running out of VM.
static char* mainNewHandler_CharSave = new char[4096];
static Int32 mainNewHandler(size_t s)
{
if (mainNewHandler_CharSave)
{
delete[] mainNewHandler_CharSave;
mainNewHandler_CharSave = NULL;
CmpErrLog((char *)"Memory allocation failure");
ArkcmpFatalError(ARKCMP_ERROR_PREFIX "Out of virtual memory.", NOMEM_SEV);
}
return 0;
}
static void longJumpHandler()
{
// check if we have emergency memory for reporting error.
if (mainNewHandler_CharSave == 0)
exit(1);
delete [] mainNewHandler_CharSave;
mainNewHandler_CharSave = 0;
ArkcmpFatalError(ARKCMP_ERROR_PREFIX "Assertion failed (thrown by longjmp).");
}
// this copy is used by remote tdm_arkcmp process
static jmp_buf CmpInternalErrorJmpBuf;
static void initializeArkcmp(Int32 argc, char** argv)
{
if (setjmp(ExportJmpBuf))
longJumpHandler();
ExportJmpBufPtr = &ExportJmpBuf;
if (setjmp(CmpInternalErrorJmpBuf))
longJumpHandler();
CmpInternalErrorJmpBufPtr = &CmpInternalErrorJmpBuf;
}
// Please do not remove this function. Otherwise a linkage
// error will occur.
void deinitializeArkcmp()
{
}
static ofstream* initializeArkcmpCoutCerr()
{
// Initialize cout and cerr.
ofstream* outstream = 0;
char* streamName;
char* NULLSTREAM = (char *)"/dev/null";
streamName = NULLSTREAM;
outstream = new ofstream(streamName, ios::app);
cout.rdbuf(outstream->rdbuf());
cin.rdbuf(outstream->rdbuf());
return outstream;
}
//extern void bloom_filter_test();
//extern void hdfs_list_test(int argc, char **argv);
// argv[1] : <n> as in CHAR(<n>)
// argv[2]: input file name, in which each line is a string
// at least <n> bytes long
Int32 main(Int32 argc, char **argv)
{
dovers(argc, argv);
try
{
file_init_attach(&argc, &argv, TRUE, (char *)"");
file_mon_process_startup(true);
msg_debug_hook("arkcmp", "ark.hook");
atexit(my_mpi_fclose);
}
catch (...)
{
cerr << "Error while initializing messaging system. Exiting..." << endl;
exit(1);
}
IdentifyMyself::SetMyName(I_AM_SQL_COMPILER);
// Instantiate CliGlobals
CliGlobals *cliGlobals = CliGlobals::createCliGlobals(FALSE);
if (getenv("SQL_CMP_MSGBOX_PROCESS") != NULL )
MessageBox(NULL, "Server: Process Launched", "tdm_arkcmp",
MB_OK|MB_ICONINFORMATION);
// The following call causes output messages to be displayed in the
// same order on NSK and Windows.
cout.sync_with_stdio();
initializeArkcmp(argc, argv);
QRLogger::initLog4cxx(QRLogger::QRL_MXCMP);
cmpISPInterface.InitISPFuncs();
// we wish stmt heap could be passed to this constructor,
// but stmt heap is not yet created at this point in time.
Cmdline_Args cmdlineArgs;
cmdlineArgs.processArgs(argc, argv);
try
{
{ // a local ctor scope, within a try block
CmpIpcEnvironment ipcEnv;
ExCmpMessage exCmpMessage(&ipcEnv);
ipcEnv.initControl(cmdlineArgs.allocMethod(),
cmdlineArgs.socketArg(),
cmdlineArgs.portArg());
exCmpMessage.addRecipient
(ipcEnv.getControlConnection()->getConnection());
CmpMessageConnectionType connectionType;
// to receive the Connection Type information
exCmpMessage.clearAllObjects();
exCmpMessage.receive();
// Set up the context info for the connection, it contains the variables
// persistent through each statement loops.
// Check for env var that indicates this is a secondary mxcmp process.
// Keep this value in CmpContext so that secondary mxcmp on NSK
// will allow MP DDL issued from a parent mxcmp process.
NABoolean IsSecondaryMxcmp = FALSE;
/*if (getenv("SECONDARY_MXCMP") != NULL)
IsSecondaryMxcmp = TRUE;
else
// Any downstream process will be a "SECONDARY_MXCMP".
putenv("SECONDARY_MXCMP=1");*/
CmpContext *context=NULL;
NAHeap *parentHeap = GetCliGlobals()->getCurrContextHeap();
NAHeap *cmpContextHeap = new (parentHeap)
NAHeap((char *)"Cmp Context Heap",
parentHeap,
(Lng32)524288);
try
{
context= new (cmpContextHeap) CmpContext
(CmpContext::IS_DYNAMIC_SQL |
(IsSecondaryMxcmp ? CmpContext::IS_SECONDARY_MXCMP : 0) |
(CmpMainISPConnection ? CmpContext::IS_ISP : 0) |
(CmpContext::IS_MXCMP),
cmpContextHeap);
}
catch (...)
{
ArkcmpErrorMessageBox
(ARKCMP_ERROR_PREFIX "- Cannot initialize Compiler global data.",
ERROR_SEV, FALSE, FALSE, TRUE);
exit(1);
}
// moved down the IdentifyMyself so that it can be determined that the
// context has not yet been set up
//IdentifyMyself::SetMyName(I_AM_SQL_COMPILER);
context->initContextGlobals();
context->envs()->cleanup();
// ## This dump-diags only goes to arkcmp console --
// ## we really need to reply to sqlci (or whoever is requester)
// ## with these diags! (Work to be done in Ipc and CmpConnection...)
NADumpDiags(cerr, CmpCommon::diags(), TRUE/*newline*/);
assert(cmpCurrentContext == context);
exCmpMessage.setCmpContext(context);
while (!exCmpMessage.end())
{
// Clear the SQL text buffer in the event logging area.
cmpCurrentContext->resetLogmxEventSqlText();
exCmpMessage.clearAllObjects();
exCmpMessage.receive();
}
// in most (probably all?) cases, an mxci-spawned mxcmp calls NAExit
// in CmpConnection.cpp. So, everything below this line is probably
// dead code.
CURRENTQCACHE->finalize((char *)"Dynamic (non-NAExit case) ");
}
}
catch(BaseException& bE)
{
char msg[500];
sprintf(msg, "%s BaseException: %s %d", ARKCMP_ERROR_PREFIX,
bE.getFileName(), bE.getLineNum());
ArkcmpFatalError(msg);
}
catch(...)
{
ArkcmpFatalError(ARKCMP_ERROR_PREFIX "Fatal exception.");
}
ENDTRANSACTION();
return 0;
}
// stubs
Int32 arkcmp_main_entry()
{ // return 1 for embedded cmpiler not created
return 1;
}
// no-op
void arkcmp_main_exit() {}