blob: ef5f3a9e73f5bbdf2a0091d6cc329abd17a0afc2 [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: SchemaDB.C
* Description: Schema Information
* Created: 4/27/94
* Language: C++
* Status: Experimental
*
*
*************************************************************************
*/
#define SQLPARSERGLOBALS_NADEFAULTS
#include <stdlib.h>
#include <string.h>
#include "ComAnsiNamePart.h"
#include "ComMPLoc.h"
#include "CmpContext.h"
#include "DefaultValidator.h"
#include "Sqlcomp.h"
#include "StmtCompilationMode.h"
#include "NAClusterInfo.h"
#include "CmpStatement.h"
// triggers -- eliezer
#include "TriggerDB.h"
#include "logmxevent.h"
#include <ComCextdecs.h>
#include "SQLCLIdev.h"
#include "ComUnits.h"
#include "CmpSeabaseDDL.h"
#include "ExpHbaseInterface.h"
#include "SqlParserGlobals.h" // must be last #include
#include "OptimizerSimulator.h"
#include "seabed/ms.h"
// -----------------------------------------------------------------------
// global functions
// -----------------------------------------------------------------------
void InitSchemaDB()
{
CmpCommon::context()->initSchemaDB();
}
// ***********************************************************************
// Implementation for functions
// ***********************************************************************
// Note: The SchemaDB object is created during arkcmp initialization, and
// persists until arkcmp dies. Thus, its data members cannot be put
// anywhere but on the context heap. If you tried to put them on the
// statement heap, they'd end up on the global system heap, because there
// is no statement heap at the time that they're created -- and even if
// there were a statement heap, as soon as it was "wiped away" these data
// members would be time bombs, since their internal heap pointers would be
// invalid.
SchemaDB::SchemaDB()
: tableDB_(
new CTXTHEAP NAHeap("NATable Heap", (NAHeap *)CTXTHEAP,
16 * 1024,
0)),
routineDB_(CmpCommon::contextHeap()),
actionRoutineDB_(CmpCommon::contextHeap()),
valueDArray_(),
domainDList_(CmpCommon::contextHeap()),
defaults_(CmpCommon::contextHeap()),
defaultSchema_(CmpCommon::contextHeap()),
// triggers -- eliezer
// created only on demand
triggerDB_(NULL),
currentDiskPool_(-1),
hbaseBlockCacheFrac_(-1.0)
{
// error during nadefault creation. Cannot proceed. Return.
if (! defaults_.getSqlParser_NADefaults_Ptr())
return;
initPerStatement();
routineDB_.setMetadata("NEO.UDF.ROUTINES");
actionRoutineDB_.setMetadata("NEO.UDF.UUDR_ROUTINES");
}
void SchemaDB::initPerStatement(NABoolean lightweight)
{
if (!lightweight) {
//CMPASSERT(domainDList_.entries() == 0);
//CMPASSERT(valueDArray_.entries() == 1);
//CMPASSERT(tableDB_.entries() == 0);
// WE CANNOT DO THIS HERE:
// TransMode::IsolationLevel il;
// if (getDefaults().getIsolationLevel(il))
// CmpCommon::transMode()->isolationLevel() = il;
// BECAUSE THEN WE'D BE RESETTING DURING A TXN UNDER THE AEGIS OF
// A "SET TRANSACTION" STMT, WHICH WOULD BE WRONG...
// Instead, a] CmpCommon::transMode() init's itself once,
// and b] NADefaults::validateAndInsert() updates CmpCommon::transMode glob
// when necessary...
}
// The defaults table contains EXTERNAL names (and has validated them).
// The SchemaName object we fill in here has to be INTERNAL format.
// First, ensure the NADefaults and the SqlParser_NADefaults globals
// have been initialized.
//
NAString cat, sch;
getDefaults().getCatalogAndSchema(cat, sch);
// NB: These two ToInternalIdentifier() calls are essential to making
// delimited identifiers work properly. Is it not useless emitting their
// return codes into cerr? Would it not be better to CMPASSERT them instead?
Lng32 err1, err2;
err1 = ToInternalIdentifier(cat);
err2 = ToInternalIdentifier(sch);
if (err1 || err2)
cerr << err1 << ' ' << cat << '\t'
<< err2 << ' ' << sch << endl;
defaultSchema_.setCatalogName(cat);
defaultSchema_.setSchemaName (sch);
}
// By default, this returns the ANSI default schema.
const SchemaName &SchemaDB::getDefaultSchema(UInt32 flags)
{
if (flags & REFRESH_CACHE)
initPerStatement();
return defaultSchema_;
}
SchemaDB::~SchemaDB()
{
cleanupPerStatement();
}
void SchemaDB::cleanupPerStatement()
{
domainDList_.clear();
valueDArray_.clear();
// Create a NULL entry (valueId = 0). This
// is done so that an uninitialized value id (= 0) could
// be detected as an invalid entry.
valueDArray_.insertAt(0,NULL);
// NATables are now on the statement heap, so there've already been
// destroyed at this point.
// Reset metadata (i.e. NATable & histogram) caches after statement
tableDB_.resetAfterStatement();
routineDB_.resetAfterStatement();
actionRoutineDB_.resetAfterStatement();
CURRCONTEXT_HISTCACHE->resetAfterStatement();
CURRCONTEXT_HISTCACHE->traceTablesFinalize();
CURRCONTEXT_HISTCACHE->monitor();
// applies when allocating the TriggerDB from the ContextHeap:
if (Trigger::Heap() == CmpCommon::contextHeap()) {
NABoolean deallocationNeeded = triggerDB_->cleanupPerStatement();
if (deallocationNeeded) {
delete triggerDB_;
triggerDB_ = NULL;
}
}
else { // the TriggerDB_ memory was be deallocated with the StatementHeap
triggerDB_= NULL;
}
// EJF 8/14/01 - gpClusterInfo is NULL in NT for NSK preprocessors.
if (gpClusterInfo)
gpClusterInfo->cleanupPerStatement();
// Reset static members (quasi-globals) of other classes
ItemExpr::cleanupPerStatement();
}
void SchemaDB::dropStmtTables()
{
// Now a noop:
//domainDList_.clear();
}
void SchemaDB::createStmtTables()
{
// Now a noop:
//dropStmtTables(); // (used to have to) cleanup from last stmt
}
NABoolean SchemaDB::endTransaction()
{
return TRUE;
}
float SchemaDB::getHbaseBlockCacheFrac()
{
if (hbaseBlockCacheFrac_ < 0) // access JNI layer first time to set value
{
CmpSeabaseDDL cmpSBD(STMTHEAP);
ExpHbaseInterface* ehi = cmpSBD.allocEHI();
if (!ehi)
hbaseBlockCacheFrac_ = 0.4 ; // hbase default default
else {
float frac;
Lng32 retcode;
retcode = ehi->getBlockCacheFraction(frac);
if (retcode < 0)
hbaseBlockCacheFrac_ = 0.4 ; // hbase default default
else
hbaseBlockCacheFrac_ = frac;
cmpSBD.deallocEHI(ehi);
}
}
return hbaseBlockCacheFrac_ ;
}
//****************************************************************************
// CollationDB stuff that can't be compiled if in ../common/CharInfo.cpp
//****************************************************************************
Lng32 CollationDB::nextUserCo_(CharInfo::FIRST_USER_DEFINED_COLLATION);
CharInfo::Collation CollationDB::insert(QualifiedName &qn,
const SchemaName *defaultSchema,
CollationInfo::CollationFlags flags)
{
Int32 defaultMatchCount = 0;
if (defaultSchema)
defaultMatchCount = qn.applyDefaults(*defaultSchema);
CMPASSERT(!qn.getCatalogName().isNull()); // fully qualified w/ all defaults
size_t siz[CollationInfo::SIZEARRAY_SIZE];
NAString nam(qn.getQualifiedNameAsAnsiString(siz));
CMPASSERT(siz[0] == 3); // fully qualified w/ all defaults
return insert(nam, siz, flags, defaultMatchCount);
}
CharInfo::Collation CollationDB::insert(ComMPLoc &loc,
const ComMPLoc *defaultMPLoc,
CollationInfo::CollationFlags flags)
{
Int32 defaultMatchCount = 0;
if (defaultMPLoc)
defaultMatchCount = loc.applyDefaults(*defaultMPLoc);
CMPASSERT(loc.isValid(ComMPLoc::FILE));
size_t siz[CollationInfo::SIZEARRAY_SIZE];
NAString nam(loc.getMPName(siz));
CMPASSERT(siz[0] == 3 || siz[0] == 4); // was defaulted out to $vol or \sys
return insert(nam, siz, flags, defaultMatchCount);
}
CharInfo::Collation CollationDB::insert(const char *nam,
size_t *siz,
CollationInfo::CollationFlags flags,
Int32 defaultMatchCount)
{
CMPASSERT(defaultMatchCount >= 0);
size_t mat = (size_t)defaultMatchCount;
CMPASSERT(siz[0] > mat); // up to n-1 name parts can match
siz[0] = mat; // no longer cnt of total nameparts,
// now it is cnt of MATCHING parts
// Well before getting to overflow, wrap around to begin again
// with automatically generated numbers for non-builtin collations.
if (nextUserCo_ > 2147000000) // well shy of INT_MAX
nextUserCo_ = CharInfo::FIRST_USER_DEFINED_COLLATION;
CharInfo::Collation co = (CharInfo::Collation)nextUserCo_++;
CollationInfo *collInfo = new (heap_)
CollationInfo(heap_, co, nam, flags, siz);
CollationDBSupertype::insert(collInfo);
refreshNeeded() = FALSE;
return co;
}
// triggers -- eliezer
//
// -- SchemaDB::getTriggerDB
//
// The TriggerDB is constructed only if needed.
//
TriggerDB * SchemaDB::getTriggerDB() {
if (!triggerDB_)
triggerDB_ = new (Trigger::Heap()) TriggerDB(Trigger::Heap());
return triggerDB_;
}