blob: 36af463078c3e00c9ec84f32a53a7f7fe6ec1ad3 [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 @@@
**********************************************************************/
#ifndef COM_TRANS_INFO_H
#define COM_TRANS_INFO_H
/* -*-C++-*-
*****************************************************************************
*
* File: ComTransInfo.h
* Description:
*
* Created: 7/10/95
* Language: C++
*
*
*
*****************************************************************************
*/
#include "Platform.h"
#include "NABoolean.h"
#include "NABoolean.h"
#include "NAVersionedObject.h"
enum TransStmtType
{
BEGIN_, COMMIT_, COMMIT_WAITED_, ROLLBACK_, ROLLBACK_WAITED_,
SET_TRANSACTION_
};
// PROTECTED_ mode allows read operation against the table but prevents
// writes to it. Currently used with lock table operation only.
enum LockMode
{
SHARE_, EXCLUSIVE_, PROTECTED_, LOCK_MODE_NOT_SPECIFIED_
};
// Define a type to be used inside an unnamed Union
typedef
struct
{
unsigned short consistencyLevel_;
unsigned char lockSize_:1;
unsigned char lockState_:2;
unsigned char bounceLockFlag_:1;
unsigned char noLockEscalation_:1;
unsigned char updateOrDeleteFlag_:1;
unsigned char updateIndex_:1;
unsigned char backoutAccess_:1;
// BertBert VV
unsigned char invisible_:1;
unsigned char skipLockedRows_:1;
unsigned char unLockRowFlag_:1;
unsigned char selfReferencingUpdate_:1;
unsigned char eidCleanup_:1;
unsigned char bitFiller_:3;
// BertBert ^^
// unsigned char bitFiller_; // originally...now changed to
// accomodate new flags
} LockFlagsType ;
///////////////////////////////////////////////////////////////////////
// This class defines the lock and consistency flags that are
// passed to DP2. Do not add or change any private members to this class
// as the value passed to DP2 is a long (INT(32)) and the bit position
// of each field must be as it is laid out in this class.
////////////////////////////////////////////////////////////////////////
class DP2LockFlags
{
public:
enum BounceLock {
WAIT_LOCK = 0,
BOUNCE_LOCK = 1
};
enum ConsistencyLevel {
READ_UNCOMMITTED, // browse access
READ_COMMITTED, // clean access
STABLE, // stable access
SERIALIZABLE, // repeatable access
// QSTUFF
SKIP_CONFLICT // skip conflict access,
// skips tuples with conflicting lock mode
//QSTUFF
};
enum LockSize {
ROW_LOCK = 0,
GROSS_FILE_LOCK = 1
};
enum LockState {
LOCK_CURSOR = 0,
LOCK_SHARED = 1,
LOCK_EXCLUSIVE = 2,
LOCK_SELECT = 3
};
DP2LockFlags() : value_(0) { }
void setBounceLock(BounceLock bl)
{ flags_.bounceLockFlag_ = (unsigned char ) bl; }
short getBounceLock() const { return flags_.bounceLockFlag_; }
void setConsistencyLevel(ConsistencyLevel cl)
{ flags_.consistencyLevel_ = (unsigned short) cl; }
short getConsistencyLevel() const {return (short)flags_.consistencyLevel_;}
void setLockSize(LockSize ls) { flags_.lockSize_ = (unsigned char) ls; }
short getLockSize() const { return flags_.lockSize_; }
void setLockState(LockState ls) { flags_.lockState_ = (unsigned char) ls; }
short getLockState() const { return flags_.lockState_; }
void setNoLockEscalation(unsigned char v) { flags_.noLockEscalation_ = v; }
short getNoLockEscalation() const { return flags_.noLockEscalation_; }
Lng32 getValue() const { return value_; }
// BertBert VV
void setBounceLockFlag(){flags_.bounceLockFlag_ = 1;};
void resetBounceLockFlag(){flags_.bounceLockFlag_ = 0;};
short getBounceLockFlag(){return flags_.bounceLockFlag_;};
void setSkipLockedRows(){flags_.skipLockedRows_ = 1;};
void resetSkipLockedRows(){flags_.skipLockedRows_ = 0;};
short getSkipLockedRows(){return flags_.skipLockedRows_;};
void setUpdateOrDeleteFlag(){flags_.updateOrDeleteFlag_ = 1;};
void resetUpdateOrDeleteFlag(){flags_.updateOrDeleteFlag_ = 0;};
short getUpdateOrDeleteFlag(){return flags_.updateOrDeleteFlag_;};
void setUnLockRowFlag(){flags_.unLockRowFlag_ = 1;};
void resetUnLockRowFlag(){flags_.unLockRowFlag_ = 0;};
// BertBert ^^
void setSelfReferencingUpdate(unsigned char v)
{ flags_.selfReferencingUpdate_ = v; }
short getSelfReferencingUpdate() const
{ return flags_.selfReferencingUpdate_; }
void setEidCleanup(unsigned char v) { flags_.eidCleanup_ = v; }
short getEidCleanup() const { return flags_.eidCleanup_; }
DP2LockFlags operator=(DP2LockFlags src)
{
value_ = src.getValue();
return *this;
}
// returns -1, if a transaction is needed for these lock flags.
short transactionNeeded();
private:
union
{
Lng32 value_;
LockFlagsType flags_ ;
};
};
class TransMode : public NAVersionedObject
{
public:
enum AccessType
{
READ_UNCOMMITTED_ACCESS_ = 00,
SKIP_CONFLICT_ACCESS_ = 05,
READ_COMMITTED_ACCESS_ = 10,
REPEATABLE_READ_ACCESS_ = 20,
SERIALIZABLE_ACCESS_ = 30,
ACCESS_TYPE_NOT_SPECIFIED_ = -1
};
// These values get stored in generated code, so MUST NOT BE CHANGED.
// The values must form a logical sequence -- see the xxCompatible()
// code below, and StmtLevelAccessOptions::updateAccessOptions.
//
// Enum TransMode::IsolationLevel maps to enum AccessType.
// The static funcs that follow do this mapping, in both directions.
//
enum IsolationLevel
{
READ_UNCOMMITTED_ = READ_UNCOMMITTED_ACCESS_,
READ_COMMITTED_ = READ_COMMITTED_ACCESS_,
REPEATABLE_READ_ = REPEATABLE_READ_ACCESS_,
SERIALIZABLE_ = SERIALIZABLE_ACCESS_,
IL_NOT_SPECIFIED_ = ACCESS_TYPE_NOT_SPECIFIED_
};
static AccessType ILtoAT(IsolationLevel il)
{ return (il == SERIALIZABLE_) ? REPEATABLE_READ_ACCESS_ : (AccessType)il; }
static IsolationLevel ATtoIL(AccessType at)
{ return (IsolationLevel)at; }
enum AccessMode
{
READ_ONLY_, READ_WRITE_, AM_NOT_SPECIFIED_, READ_ONLY_SPECIFIED_BY_USER_
};
enum AutoCommit
{
ON_, OFF_, AC_NOT_SPECIFIED_
};
enum MultiCommit
{
MC_NOT_SPECIFIED_, MC_ON_, MC_OFF_
};
// whether to rollback waited or nowaited. Default is waited.
enum RollbackMode
{
ROLLBACK_MODE_WAITED_, ROLLBACK_MODE_NOWAITED_, ROLLBACK_MODE_NOT_SPECIFIED_,
NO_ROLLBACK_, NO_ROLLBACK_IN_IUD_STATEMENT_
};
enum Flags
{
STMTLEVELACCESSOPTIONS_ = 0x2,
AUTO_BEGIN_ON_ = 0x4,
AUTO_BEGIN_OFF_ = 0x8,
USER_TRANS_MODE_ = 0x10
};
TransMode(IsolationLevel il = IL_NOT_SPECIFIED_,
AccessMode am = AM_NOT_SPECIFIED_,
AutoCommit ac = AC_NOT_SPECIFIED_,
RollbackMode rm = ROLLBACK_MODE_NOT_SPECIFIED_,
Lng32 das = -1,
Lng32 aiVal = -1,
MultiCommit mc = MC_NOT_SPECIFIED_,
ULng32 mcs = 0)
: il_(il), am_((short) am), autoCommit_((short) ac), diagAreaSize_(das),
flags_(0), rm_((short) rm), autoAbortInterval_(aiVal),
multiCommit_((short) mc), multiCommitSize_(mcs), NAVersionedObject(-1)
{}
virtual unsigned char getClassVersionID() { return 1; }
virtual void populateImageVersionIDArray()
{ setImageVersionID(0,getClassVersionID()); }
virtual short getClassSize() { return (short)sizeof(TransMode); }
/*IsolationLevel&*/ Int16& isolationLevel() { return il_; }
/*IsolationLevel */ Int16 isolationLevel() const { return il_; }
/*AccessMode&*/ Int16& accessMode() { return am_; }
/*AccessMode */ Int16 accessMode() const { return am_; }
/*AutoCommit&*/ Int16& autoCommit() { return autoCommit_; }
/*RollbackMode&*/ Int16& rollbackMode() { return rm_; }
/*MultiCommit&*/ Int16& multiCommit() { return multiCommit_; }
Int32& diagAreaSize() { return diagAreaSize_; }
Int32& autoAbortIntervalInSeconds() { return autoAbortInterval_; }
UInt32& multiCommitSize() { return multiCommitSize_; }
IsolationLevel getIsolationLevel(){ return (IsolationLevel)il_;}
AccessMode getAccessMode() { return (AccessMode)am_; }
AutoCommit getAutoCommit() { return (AutoCommit)autoCommit_; }
RollbackMode getRollbackMode() { return (RollbackMode)rm_;}
NABoolean anyNoRollback() { return
(rm_ == NO_ROLLBACK_ ||
rm_ == NO_ROLLBACK_IN_IUD_STATEMENT_); }
Lng32 getDiagAreaSize() { return diagAreaSize_; }
Int16 getFlags() const { return flags_; }
Int16& setFlags() { return flags_; }
Int32 getAutoAbortIntervalInSeconds() const { return autoAbortInterval_; }
MultiCommit getMultiCommit() { return (MultiCommit)multiCommit_; }
UInt32 getMultiCommitSize() const { return multiCommitSize_; }
NABoolean stmtLevelAccessOptions() const
{ return flags_ & STMTLEVELACCESSOPTIONS_; }
void setStmtLevelAccessOptions(Int32 v=1)
{ if (v) flags_ |= STMTLEVELACCESSOPTIONS_;
else flags_ &= ~STMTLEVELACCESSOPTIONS_; }
void setAutoBeginOn(NABoolean vi)
{
if (vi == TRUE)
flags_ |= AUTO_BEGIN_ON_;
else
flags_ &= ~AUTO_BEGIN_ON_;
}
NABoolean getAutoBeginOn()
{
if (flags_ & AUTO_BEGIN_ON_)
return TRUE;
else
return FALSE;
}
void setAutoBeginOff(NABoolean vi)
{
if (vi == TRUE)
flags_ |= AUTO_BEGIN_OFF_;
else
flags_ &= ~AUTO_BEGIN_OFF_;
}
NABoolean getAutoBeginOff()
{
if (flags_ & AUTO_BEGIN_OFF_)
return TRUE;
else
return FALSE;
}
NABoolean userTransMode() const
{ return (flags_ & USER_TRANS_MODE_) != 0; }
void setUserTransMode(NABoolean v)
{ if (v) flags_ |= USER_TRANS_MODE_;
else flags_ &= ~USER_TRANS_MODE_; }
NABoolean isolationLevelCompatible(const TransMode &o) const
{ return il_ <= o.il_; }
NABoolean accessModeCompatible(const TransMode &o) const
{ if (o.am_ == READ_ONLY_SPECIFIED_BY_USER_)
return am_ <= READ_ONLY_;
else
return am_ <= o.am_;
}
NABoolean operator==(const TransMode &o) const;
void updateTransMode(TransMode * trans_mode);
ULng32 getByteSize() const { return sizeof(*this); }
static IsolationLevel getIsolationLevel(const char *value);
// Update per Ansi 14.1 SR 4.
// Should ONLY be used when an access mode was not explicitly specified
// in the SET TRANSACTION stmt.
void updateAccessModeFromIsolationLevel(IsolationLevel il,
NABoolean affectIL = TRUE)
{
Int16 tempIL = il_;
if (il != IL_NOT_SPECIFIED_)
tempIL = (Int16) il;
if (am_ != READ_ONLY_SPECIFIED_BY_USER_)
am_ = (Int16) ((tempIL == READ_UNCOMMITTED_) ? READ_ONLY_ : READ_WRITE_);
if (affectIL)
il_ = tempIL;
}
void updateAccessModeAndResetIsolationLevel()
{
il_ = IL_NOT_SPECIFIED_;
updateAccessModeFromIsolationLevel(IL_NOT_SPECIFIED_);
}
NABoolean invalidAccessModeAndIsolationLevel() // ret TRUE if invalid
{ return (il_ == READ_UNCOMMITTED_ && (am_ != READ_ONLY_ || am_ != READ_ONLY_SPECIFIED_BY_USER_)); }
NABoolean invalidMultiCommitCompatibility() // ret TRUE if invalid
{ return (il_ == READ_UNCOMMITTED_ ||
am_ == READ_ONLY_ ||
am_ == READ_ONLY_SPECIFIED_BY_USER_ ||
rm_ == NO_ROLLBACK_ ); }
// multi commit modes are compatible
NABoolean multiCommitCompatible(const TransMode &o) const
{
switch (o.multiCommit_)
{
case MC_OFF_:
case MC_NOT_SPECIFIED_:
return multiCommit_ != MC_ON_;
break;
case MC_ON_:
return multiCommit_ == MC_ON_ ;
break;
default:
return FALSE; // Not compatible
break;
}
}
// based on the current access options or SET TRANSACTION settings,
// return the corresponding DP2LockFlags.
DP2LockFlags getDP2LockFlags();
// Fast encoding for DgInt0 diags display.
// Shift things left (more zeroes in each xx_*10) if want to add more members
Lng32 display() const
{ return multiCommit_*1000000 + il_*10000 + am_*100 + rm_*10 + autoCommit_; }
private:
// see enum IsolationLevel
Int16 il_; // 00-01
// see enum AccessMode
Int16 am_; // 02-03
// if ON_, then implicitly commit each SQL statement (see enum AutoCommit)
Int16 autoCommit_; // 04-05
Int16 flags_; // 06-07
Int32 diagAreaSize_; // 08-11
// see enum RollbackMode
Int16 rm_; // 12-13
Int16 multiCommit_; // 14-15
Int32 autoAbortInterval_; // 16-19
UInt32 multiCommitSize_; // 20-23
};
////////////////////////////////////////////////////////////////
// These are the access options that are specified in a SQL
// statements (FOR BROWSE ACCESS, IN SHARE MODE, etc).
// This is a Tandem extension. Do HELP from sql/mp sqlci or
// look at sql/mp manual or SQL/ARK Language spec
// for details on these options. If these are specified in a
// query, they override any options specified via a SET
// TRANSACTION statement.
////////////////////////////////////////////////////////////////
class StmtLevelAccessOptions
{
public:
StmtLevelAccessOptions(TransMode::AccessType at = TransMode::ACCESS_TYPE_NOT_SPECIFIED_,
LockMode lm = LOCK_MODE_NOT_SPECIFIED_)
: accessType_(at), lockMode_(lm)
,updateOrDelete_ (FALSE)
,scanLockForIM_(FALSE)
{}
NABoolean operator==(const StmtLevelAccessOptions &o) const
{ return accessType_ == o.accessType_ && lockMode_ == o.lockMode_; }
TransMode::AccessType& accessType() { return accessType_; }
TransMode::AccessType accessType() const { return accessType_; }
LockMode& lockMode() { return lockMode_; }
NABoolean userSpecified()
{
return (accessType_ != TransMode::ACCESS_TYPE_NOT_SPECIFIED_ ||
lockMode_ != LOCK_MODE_NOT_SPECIFIED_);
}
void updateAccessOptions(TransMode::AccessType at,
LockMode lm = LOCK_MODE_NOT_SPECIFIED_);
// based on the current access options, return the corresponding DP2LockFlags
DP2LockFlags getDP2LockFlags();
// QSTUFF
void setUpdateOrDelete (NABoolean u) { updateOrDelete_ = u; };
NABoolean isUpdateOrDelete() { return updateOrDelete_; };
// QSTUFF
void setScanLockForIM(NABoolean u) { scanLockForIM_ = u; };
NABoolean scanLockForIM(){ return scanLockForIM_; };
private:
TransMode::AccessType accessType_;
LockMode lockMode_;
NABoolean updateOrDelete_;
//-------------------------------------------------------------------------
// This option attribute is set for all scans that are on the left side of
// an TSJ "for write" when there is an update or delete and Index Maintenance.
// This is needed by the executor to ensure that selected rows are
// appropriately locked, even if scanned from an index, to protect against
// index corruption. The attribute is propagated to ComTdbDp2SubsOper and
// ComTdbDp2UniqueOper and used during execution to ask DP2 for serializable
// locks.
//
// This is to address genesis solution 10-040802-8483, and also addresses
// solution 10-031111-1215. The original fix for 10-040802-8483 caused
// deadlocks in "refresh MVGROUP" to get error 73 when
// MV_REFRESH_MAX_PARALLELISM > 1 (see solution 10-070322-3467), so it has
// been modified to limit the scan nodes that will use serializable locking
// to those nodes on the left side of the TSJforWrite.
//-------------------------------------------------------------------------
NABoolean scanLockForIM_;
};
// verify that statement-level access and session-level setting are OK.
// set errCodeA/errCodeB to 0/0 if all OK, else to -3140/-3141.
void verifyUpdatableTrans(StmtLevelAccessOptions * sAxOpt,
TransMode * tm,
TransMode::IsolationLevel isolationLevelForUpdate,
Lng32 &errCodeA, Lng32 &errCodeB);
// ---------------------------------------------------------------------
// Template instantiation to produce a 64-bit pointer emulator class
// for TransMode
// ---------------------------------------------------------------------
typedef NAVersionedObjectPtrTempl<TransMode> TransModePtr;
const char * getStrOfIsolationLevel(TransMode::IsolationLevel isl, NABoolean doNotReportNotSpecified = TRUE);
const char * getStrOfAccessMode(TransMode::AccessMode am);
const char * getStrOfRollbackMode(TransMode::RollbackMode am);
#endif // COM_TRANS_INFO_H