/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "NdbApiSignal.hpp" #include #include #include #include "NdbUtil.hpp" #include "Interpreter.hpp" #include #ifdef VM_TRACE #include #define INT_DEBUG(x) \ { const char* tmp = NdbEnv_GetEnv("INT_DEBUG", (char*)0, 0); \ if (tmp != 0 && strlen(tmp) != 0) { ndbout << "INT:"; ndbout_c x; } } #else #define INT_DEBUG(x) #endif void NdbOperation::initInterpreter(){ theFirstLabel = NULL; theLastLabel = NULL; theFirstBranch = NULL; theLastBranch = NULL; theFirstCall = NULL; theLastCall = NULL; theFirstSubroutine = NULL; theLastSubroutine = NULL; theNoOfLabels = 0; theNoOfSubroutines = 0; theSubroutineSize = 0; theInitialReadSize = 0; theInterpretedSize = 0; theFinalUpdateSize = 0; theFinalReadSize = 0; theInterpretIndicator = 1; theTotalCurrAI_Len = 5; } int NdbOperation::incCheck(const NdbColumnImpl* tNdbColumnImpl) { if ((theInterpretIndicator == 1)) { if ((tNdbColumnImpl == NULL) || (theOperationType == OpenScanRequest || theOperationType == OpenRangeScanRequest)) goto inc_check_error1; if ((tNdbColumnImpl->getInterpretableType() != true) || (tNdbColumnImpl->m_pk != false) || (tNdbColumnImpl->m_nullable)) goto inc_check_error2; if (theStatus == ExecInterpretedValue) { ; // Simply continue with interpretation } else if (theStatus == GetValue) { theInitialReadSize = theTotalCurrAI_Len - 5; theStatus = ExecInterpretedValue; } else if (theStatus == SubroutineExec) { ; // Simply continue with interpretation } else { setErrorCodeAbort(4231); return -1; } m_no_disk_flag &= (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK ? 0:1); return tNdbColumnImpl->m_attrId; } else { if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; inc_check_error1: if (theOperationType == OpenScanRequest || theOperationType == OpenRangeScanRequest) { setErrorCodeAbort(4228); return -1; } setErrorCodeAbort(4004); return -1; inc_check_error2: if (tNdbColumnImpl->m_pk){ setErrorCodeAbort(4202); return -1; }//if if (!tNdbColumnImpl->getInterpretableType()){ setErrorCodeAbort(4217); return -1; }//if if (tNdbColumnImpl->m_nullable){ setErrorCodeAbort(4218); return -1; }//if setErrorCodeAbort(4219); return -1; } int NdbOperation::write_attrCheck(const NdbColumnImpl* tNdbColumnImpl) { if ((theInterpretIndicator == 1)) { if ((tNdbColumnImpl == NULL) || (theOperationType == OpenScanRequest || theOperationType == OpenRangeScanRequest)) goto write_attr_check_error1; if ((tNdbColumnImpl->getInterpretableType() == false) || (tNdbColumnImpl->m_pk)) goto write_attr_check_error2; if (theStatus == ExecInterpretedValue) { ; // Simply continue with interpretation } else if (theStatus == SubroutineExec) { ; // Simply continue with interpretation } else { setErrorCodeAbort(4231); return -1; } m_no_disk_flag &= (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK ? 0:1); return tNdbColumnImpl->m_attrId; } else { if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; write_attr_check_error1: if (theOperationType == OpenScanRequest || theOperationType == OpenRangeScanRequest) { setErrorCodeAbort(4228); return -1; } setErrorCodeAbort(4004); return -1; write_attr_check_error2: if (tNdbColumnImpl->m_pk) { setErrorCodeAbort(4202); return -1; }//if if (tNdbColumnImpl->getInterpretableType() == false){ setErrorCodeAbort(4217); return -1; }//if setErrorCodeAbort(4219); return -1; } int NdbOperation::read_attrCheck(const NdbColumnImpl* tNdbColumnImpl) { if ((theInterpretIndicator == 1)) { if (tNdbColumnImpl == NULL) goto read_attr_check_error1; if (tNdbColumnImpl->getInterpretableType() == false) goto read_attr_check_error2; if (theStatus == ExecInterpretedValue) { ; // Simply continue with interpretation } else if (theStatus == GetValue) { theInitialReadSize = theTotalCurrAI_Len - 5; theStatus = ExecInterpretedValue; } else if (theStatus == SubroutineExec) { ; // Simply continue with interpretation } else { setErrorCodeAbort(4231); return -1; } m_no_disk_flag &= (tNdbColumnImpl->m_storageType == NDB_STORAGETYPE_DISK ? 0:1); return tNdbColumnImpl->m_attrId; } else { if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; read_attr_check_error1: setErrorCodeAbort(4004); return -1; read_attr_check_error2: if (tNdbColumnImpl->getInterpretableType() == false) setErrorCodeAbort(4217); else setErrorCodeAbort(4219); return -1; } int NdbOperation::initial_interpreterCheck() { if ((theInterpretIndicator == 1)) { if (theStatus == ExecInterpretedValue) { return 0; // Simply continue with interpretation } else if (theStatus == GetValue) { theInitialReadSize = theTotalCurrAI_Len - 5; theStatus = ExecInterpretedValue; return 0; } else if (theStatus == SubroutineExec) { return 0; // Simply continue with interpretation } else { setErrorCodeAbort(4231); return -1; } return 0; } else { if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; } int NdbOperation::labelCheck() { if ((theInterpretIndicator == 1)) { if (theStatus == ExecInterpretedValue) { return 0; // Simply continue with interpretation } else if (theStatus == GetValue) { theInitialReadSize = theTotalCurrAI_Len - 5; theStatus = ExecInterpretedValue; return 0; } else if (theStatus == SubroutineExec) { return 0; // Simply continue with interpretation } else if (theStatus == SubroutineEnd) { theStatus = SubroutineExec; } else { setErrorCodeAbort(4231); return -1; } return 0; } else { if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; } int NdbOperation::intermediate_interpreterCheck() { if ((theInterpretIndicator == 1)) { if (theStatus == ExecInterpretedValue) { return 0; // Simply continue with interpretation } else if (theStatus == SubroutineExec) { return 0; // Simply continue with interpretation } else { setErrorCodeAbort(4231); return -1; } return 0; } else { if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; } /***************************************************************************** * int incValue(const char* anAttrName, char* aValue, Uint32 aValue) * * Return Value: Return 0 : incValue was succesful. * Return -1: In all other case. * Parameters: anAttrName : Attribute name where the attribute value * will be save. * aValue : The constant to increment the attribute value with. *****************************************************************************/ int NdbOperation::incValue(const NdbColumnImpl* tNdbColumnImpl, Uint32 aValue) { INT_DEBUG(("incValue32 %d %u", tNdbColumnImpl->m_attrId, aValue)); int tAttrId; tAttrId = incCheck(tNdbColumnImpl); if (tAttrId == -1) goto incValue_error1; // Load Attribute into register 6 if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1) goto incValue_error1; // Load aValue into register 7 if (aValue < 65536) { if (insertATTRINFO(Interpreter::LoadConst16(7, aValue)) == -1) goto incValue_error1; } else { if (insertATTRINFO(Interpreter::LoadConst32(7)) == -1) goto incValue_error1; if (insertATTRINFO(aValue) == -1) goto incValue_error1; } // Add register 6 and 7 and put result in register 7 if (insertATTRINFO( Interpreter::Add(7, 6, 7)) == -1) goto incValue_error1; if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1) goto incValue_error1; theErrorLine++; return 0; incValue_error1: return -1; } /***************************************************************************** * int subValue(const char* anAttrName, char* aValue, Uint32 aValue) * * Return Value: Return 0 : incValue was succesful. * Return -1: In all other case. * Parameters: anAttrName : Attribute name where the attribute value * will be save. * aValue : The constant to increment the attribute value with. ******************************************************************************/ int NdbOperation::subValue(const NdbColumnImpl* tNdbColumnImpl, Uint32 aValue) { INT_DEBUG(("subValue32 %d %u", tNdbColumnImpl->m_attrId, aValue)); int tAttrId; tAttrId = incCheck(tNdbColumnImpl); if (tAttrId == -1) goto subValue_error1; // Load Attribute into register 6 if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1) goto subValue_error1; // Load aValue into register 7 if (aValue < 65536) { if (insertATTRINFO( Interpreter::LoadConst16(7, aValue)) == -1) goto subValue_error1; } else { if (insertATTRINFO( Interpreter::LoadConst32(7)) == -1) goto subValue_error1; if (insertATTRINFO(aValue) == -1) goto subValue_error1; } // Subtract register 6 and 7 and put result in register 7 if (insertATTRINFO( Interpreter::Sub(7, 6, 7)) == -1) goto subValue_error1; if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1) goto subValue_error1; theErrorLine++; return 0; subValue_error1: return -1; } /****************************************************************************** * int incValue(const char* anAttrName, char* aValue, Uint64 aValue) * * Return Value: Return 0 : incValue was succesful. * Return -1: In all other case. * Parameters: anAttrName : Attribute name where the attribute value will * be save. * aValue : The constant to increment the attribute value with. *****************************************************************************/ int NdbOperation::incValue(const NdbColumnImpl* tNdbColumnImpl, Uint64 aValue) { INT_DEBUG(("incValue64 %d %llu", tNdbColumnImpl->m_attrId, aValue)); int tAttrId; tAttrId = incCheck(tNdbColumnImpl); if (tAttrId == -1) goto incValue_error1; // Load Attribute into register 6 if (insertATTRINFO( Interpreter::Read(tAttrId, 6)) == -1) goto incValue_error1; // Load aValue into register 7 if (insertATTRINFO( Interpreter::LoadConst64(7)) == -1) goto incValue_error1; if (insertATTRINFOloop((Uint32*)&aValue, 2) == -1) goto incValue_error1; // Add register 6 and 7 and put result in register 7 if (insertATTRINFO( Interpreter::Add(7, 6, 7)) == -1) goto incValue_error1; if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1) goto incValue_error1; theErrorLine++; return 0; incValue_error1: return -1; } /***************************************************************************** * int subValue(const char* anAttrName, char* aValue, Uint64 aValue) * * Return Value: Return 0 : incValue was succesful. * Return -1: In all other case. * Parameters: anAttrName : Attribute name where the attribute value will * be save. * aValue : The constant to increment the attribute value with. ******************************************************************************/ int NdbOperation::subValue(const NdbColumnImpl* tNdbColumnImpl, Uint64 aValue) { INT_DEBUG(("subValue64 %d %llu", tNdbColumnImpl->m_attrId, aValue)); int tAttrId; tAttrId = incCheck(tNdbColumnImpl); if (tAttrId == -1) goto subValue_error1; // Load Attribute into register 6 if (insertATTRINFO( Interpreter::Read(6, tAttrId)) == -1) goto subValue_error1; // Load aValue into register 7 if (insertATTRINFO( Interpreter::LoadConst64(7)) == -1) goto subValue_error1; if (insertATTRINFOloop((Uint32*)&aValue, 2) == -1) goto subValue_error1; // Subtract register 6 and 7 and put result in register 7 if (insertATTRINFO( Interpreter::Sub(7, 6, 7)) == -1) goto subValue_error1; if (insertATTRINFO( Interpreter::Write(tAttrId, 7)) == -1) goto subValue_error1; theErrorLine++; return 0; subValue_error1: return -1; } /***************************************************************************** * int NdbOperation::def_label() *****************************************************************************/ int NdbOperation::def_label(int tLabelNo) { INT_DEBUG(("def_label %d", tLabelNo)); Uint32 tLabelIndex; if (labelCheck() == -1) return -1; tLabelIndex = theNoOfLabels - ((theNoOfLabels >> 4) << 4); if (tLabelIndex == 0) { NdbLabel* tNdbLabel = theNdb->getNdbLabel(); if (tNdbLabel == NULL) { setErrorCodeAbort(4000); return -1; } if (theFirstLabel == NULL) theFirstLabel = tNdbLabel; else theLastLabel->theNext = tNdbLabel; theLastLabel = tNdbLabel; tNdbLabel->theNext = NULL; } /** * Here we set the address that the label should point to (jump address), * the first 5 words are excluded since they are length specifications and * not part of the data. * We need to add 1 to the current ATTRINFO length since the last inserted * item is not where we want to jump to. * Later on we will update the branch items with this address, this is done in * the NdbOperation::prepareSendInterpreted method. */ theLastLabel->theLabelNo[tLabelIndex] = tLabelNo; theLastLabel->theLabelAddress[tLabelIndex] = (theTotalCurrAI_Len + 1) - (theInitialReadSize + 5); theLastLabel->theSubroutine[tLabelIndex] = theNoOfSubroutines; theNoOfLabels++; theErrorLine++; return (theNoOfLabels - 1); } /************************************************************************************************ int NdbOperation::def_subroutine() ************************************************************************************************/ int NdbOperation::def_subroutine(int tSubNo) { INT_DEBUG(("def_subroutine %d", tSubNo)); Uint32 tSubroutineIndex; if (theInterpretIndicator != 1) { setErrorCodeAbort(4200); return -1; } if (int(theNoOfSubroutines) != tSubNo) { setErrorCodeAbort(4227); return -1; } if (theStatus == FinalGetValue) { theFinalReadSize = theTotalCurrAI_Len - (theInitialReadSize + theInterpretedSize + theFinalUpdateSize + 5); } else if (theStatus == SubroutineEnd) { ; // Correct Status, last call was ret_sub() } else if (theStatus == ExecInterpretedValue) { if (insertATTRINFO(Interpreter::EXIT_OK) == -1) return -1; theInterpretedSize = theTotalCurrAI_Len - (theInitialReadSize + 5); } else if (theStatus == SetValueInterpreted) { theFinalUpdateSize = theTotalCurrAI_Len - (theInitialReadSize + theInterpretedSize + 5); } else if (theStatus == GetValue) { theInitialReadSize = theTotalCurrAI_Len - 5; } else { setErrorCodeAbort(4200); return -1; } theStatus = SubroutineExec; tSubroutineIndex = theNoOfSubroutines - ((theNoOfSubroutines >> 4) << 4); if (tSubroutineIndex == 0) { NdbSubroutine* tNdbSubroutine = theNdb->getNdbSubroutine(); if (tNdbSubroutine == NULL) { setErrorCodeAbort(4000); return -1; } if (theFirstSubroutine == NULL) theFirstSubroutine = tNdbSubroutine; else theLastSubroutine->theNext = tNdbSubroutine; theLastSubroutine = tNdbSubroutine; tNdbSubroutine->theNext = NULL; } theLastSubroutine->theSubroutineAddress[tSubroutineIndex] = theTotalCurrAI_Len - (theInitialReadSize + theInterpretedSize + theFinalUpdateSize + theFinalReadSize); theNoOfSubroutines++; theErrorLine++; return (theNoOfSubroutines - 1); } /************************************************************************************************ int NdbOperation::add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest) ************************************************************************************************/ int NdbOperation::add_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest) { INT_DEBUG(("add_reg %u %u %u", RegSource1, RegSource2, RegDest)); if (intermediate_interpreterCheck() == -1) return -1; if (RegSource1 >= 8) { setErrorCodeAbort(4229); return -1; } if (RegSource2 >= 8) { setErrorCodeAbort(4229); return -1; } if (RegDest >= 8) { setErrorCodeAbort(4229); return -1; } if (insertATTRINFO( Interpreter::Add(RegDest, RegSource1, RegSource2)) == -1) return -1; theErrorLine++; return 0; } /************************************************************************************************ int NdbOperation::sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest) ************************************************************************************************/ int NdbOperation::sub_reg(Uint32 RegSource1, Uint32 RegSource2, Uint32 RegDest) { INT_DEBUG(("sub_reg %u %u %u", RegSource1, RegSource2, RegDest)); if (intermediate_interpreterCheck() == -1) return -1; if (RegSource1 >= 8) { setErrorCodeAbort(4229); return -1; } if (RegSource2 >= 8) { setErrorCodeAbort(4229); return -1; } if (RegDest >= 8) { setErrorCodeAbort(4229); return -1; } if (insertATTRINFO( Interpreter::Sub(RegDest, RegSource1, RegSource2)) == -1) return -1; theErrorLine++; return 0; } /************************************************************************************************ int NdbOperation::load_const_u32(Uint32 RegDest, Uint32 Constant) ************************************************************************************************/ int NdbOperation::load_const_u32(Uint32 RegDest, Uint32 Constant) { INT_DEBUG(("load_const_u32 %u %u", RegDest, Constant)); if (initial_interpreterCheck() == -1) goto l_u32_error1; if (RegDest >= 8) goto l_u32_error2; if (insertATTRINFO( Interpreter::LoadConst32(RegDest)) == -1) goto l_u32_error1; if (insertATTRINFO(Constant) == -1) goto l_u32_error1; theErrorLine++; return 0; l_u32_error1: return -1; l_u32_error2: setErrorCodeAbort(4229); return -1; } /************************************************************************************************ int NdbOperation::load_const_u64(Uint32 RegDest, Uint64 Constant) ************************************************************************************************/ int NdbOperation::load_const_u64(Uint32 RegDest, Uint64 Constant) { INT_DEBUG(("load_const_u64 %u %llu", RegDest, Constant)); if (initial_interpreterCheck() == -1) return -1; if (RegDest >= 8) { setErrorCodeAbort(4229); return -1; } // 64 bit value if (insertATTRINFO( Interpreter::LoadConst64(RegDest)) == -1) return -1; if (insertATTRINFOloop((Uint32*)&Constant, 2) == -1) return -1; theErrorLine++; return 0; } /************************************************************************************************ int NdbOperation::load_const_null(Uint32 RegDest) ************************************************************************************************/ int NdbOperation::load_const_null(Uint32 RegDest) { INT_DEBUG(("load_const_null %u", RegDest)); if (initial_interpreterCheck() == -1) return -1; if (RegDest >= 8) { setErrorCodeAbort(4229); return -1; } if (insertATTRINFO( Interpreter::LOAD_CONST_NULL) == -1) return -1; theErrorLine++; return 0; } /************************************************************************************************ int NdbOperation::read_attr(const char* anAttrName, Uint32 RegDest) ************************************************************************************************/ int NdbOperation::read_attr(const NdbColumnImpl* anAttrObject, Uint32 RegDest) { INT_DEBUG(("read_attr %d %u", anAttrObject->m_attrId, RegDest)); if (initial_interpreterCheck() == -1) return -1; int tAttrId = read_attrCheck(anAttrObject); if (tAttrId == -1) goto read_attr_error1; if (RegDest >= 8) goto read_attr_error2; if (insertATTRINFO( Interpreter::Read(tAttrId, RegDest)) != -1) { return 0; theErrorLine++; }//if return -1; read_attr_error1: return -1; read_attr_error2: setErrorCodeAbort(4229); return -1; } /************************************************************************************************ int NdbOperation::write_attr(const char* anAttrName, Uint32 RegSource) ************************************************************************************************/ int NdbOperation::write_attr(const NdbColumnImpl* anAttrObject, Uint32 RegSource) { INT_DEBUG(("write_attr %d %u", anAttrObject->m_attrId, RegSource)); int tAttrId = write_attrCheck(anAttrObject); if (tAttrId == -1) return -1; if (insertATTRINFO( Interpreter::Write(tAttrId, RegSource)) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::branch_reg_reg(Uint32 type, Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { if (intermediate_interpreterCheck() == -1) return -1; if (insertATTRINFO(Interpreter::Branch(type, RegLvalue, RegRvalue)) == -1) return -1; if (insertBranch(Label) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::branch_ge(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { INT_DEBUG(("branch_ge %u %u %u", RegLvalue, RegRvalue, Label)); return branch_reg_reg(Interpreter::BRANCH_GE_REG_REG, RegLvalue, RegRvalue, Label); } int NdbOperation::branch_gt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { INT_DEBUG(("branch_gt %u %u %u", RegLvalue, RegRvalue, Label)); return branch_reg_reg(Interpreter::BRANCH_GT_REG_REG, RegLvalue, RegRvalue, Label); } int NdbOperation::branch_le(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { INT_DEBUG(("branch_le %u %u %u", RegLvalue, RegRvalue, Label)); return branch_reg_reg(Interpreter::BRANCH_LE_REG_REG, RegLvalue, RegRvalue, Label); } int NdbOperation::branch_lt(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { INT_DEBUG(("branch_lt %u %u %u", RegLvalue, RegRvalue, Label)); return branch_reg_reg(Interpreter::BRANCH_LT_REG_REG, RegLvalue, RegRvalue, Label); } int NdbOperation::branch_eq(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { INT_DEBUG(("branch_eq %u %u %u", RegLvalue, RegRvalue, Label)); return branch_reg_reg(Interpreter::BRANCH_EQ_REG_REG, RegLvalue, RegRvalue, Label); } int NdbOperation::branch_ne(Uint32 RegLvalue, Uint32 RegRvalue, Uint32 Label) { INT_DEBUG(("branch_ne %u %u %u", RegLvalue, RegRvalue, Label)); return branch_reg_reg(Interpreter::BRANCH_NE_REG_REG, RegLvalue, RegRvalue, Label); } int NdbOperation::branch_ne_null(Uint32 RegLvalue, Uint32 Label) { INT_DEBUG(("branch_ne_null %u %u", RegLvalue, Label)); if (intermediate_interpreterCheck() == -1) return -1; if (insertATTRINFO((RegLvalue << 6) + Interpreter::BRANCH_REG_NE_NULL) == -1) return -1; if (insertBranch(Label) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::branch_eq_null(Uint32 RegLvalue, Uint32 Label) { INT_DEBUG(("branch_eq_null %u %u", RegLvalue, Label)); if (intermediate_interpreterCheck() == -1) return -1; if (insertATTRINFO((RegLvalue << 6) + Interpreter::BRANCH_REG_EQ_NULL) == -1) return -1; if (insertBranch(Label) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::branch_label(Uint32 Label) { INT_DEBUG(("branch_label %u", Label)); if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO(Interpreter::BRANCH) == -1) return -1; if (insertBranch(Label) == -1) return -1; theErrorLine++; return 0; } /************************************************************************************************ int NdbOperation::interpret_exit_ok() ************************************************************************************************/ int NdbOperation::interpret_exit_ok() { INT_DEBUG(("interpret_exit_ok")); if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO(Interpreter::EXIT_OK) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::interpret_exit_last_row() { INT_DEBUG(("interpret_exit_last_row")); if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO(Interpreter::EXIT_OK_LAST) == -1) return -1; theErrorLine++; return 0; } /************************************************************************************************ int NdbOperation::interpret_exit_nok(Uint32 ErrorCode) ************************************************************************************************/ int NdbOperation::interpret_exit_nok(Uint32 ErrorCode) { INT_DEBUG(("interpret_exit_nok %u", ErrorCode)); if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO( (ErrorCode << 16) + Interpreter::EXIT_REFUSE) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::interpret_exit_nok() { INT_DEBUG(("interpret_exit_nok")); Uint32 ErrorCode = 899; if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO( (ErrorCode << 16) + Interpreter::EXIT_REFUSE) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::call_sub(Uint32 Subroutine) { INT_DEBUG(("call_sub %u", Subroutine)); if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO( (Subroutine << 16) + Interpreter::CALL) == -1) return -1; if (insertCall(Subroutine) == -1) return -1; theErrorLine++; return 0; } int NdbOperation::ret_sub() { INT_DEBUG(("ret_sub")); if (theInterpretIndicator != 1) { setErrorCodeAbort(4200); return -1; } if (theStatus == SubroutineExec) { ; // Simply continue with interpretation } else { setErrorCodeAbort(4200); return -1; } if (insertATTRINFO(Interpreter::RETURN) == -1) return -1; theStatus = SubroutineEnd; theErrorLine++; return 0; } int NdbOperation::insertBranch(Uint32 aLabel) { Uint32 tAddress; NdbBranch* tBranch = theNdb->getNdbBranch(); if (tBranch == NULL) goto insertBranch_error1; if (theFirstBranch == NULL) theFirstBranch = tBranch; else theLastBranch->theNext = tBranch; theLastBranch = tBranch; if (theNoOfSubroutines == 0) tAddress = theTotalCurrAI_Len - (theInitialReadSize + 5); else tAddress = theTotalCurrAI_Len - (theInitialReadSize + theInterpretedSize + theFinalUpdateSize + theFinalReadSize + 5); tBranch->theBranchAddress = tAddress; tBranch->theSignal = theCurrentATTRINFO; tBranch->theSignalAddress = theAI_LenInCurrAI; // + 1; theAI_LenInCurrAI has already been updated in tBranch->theSubroutine = theNoOfSubroutines; // insertATTRINFO which was done before insertBranch!! tBranch->theBranchLabel = aLabel; return 0; insertBranch_error1: setErrorCodeAbort(4000); return -1; } int NdbOperation::insertCall(Uint32 aCall) { NdbCall* tCall = theNdb->getNdbCall(); if (tCall == NULL) { setErrorCodeAbort(4000); return -1; } if (theFirstCall == NULL) theFirstCall = tCall; else theLastCall->theNext = tCall; theLastCall = tCall; tCall->theSignal = theCurrentATTRINFO; tCall->theSignalAddress = theAI_LenInCurrAI; tCall->theSubroutine = aCall; return 0; } int NdbOperation::branch_col(Uint32 type, Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ DBUG_ENTER("NdbOperation::branch_col"); DBUG_PRINT("enter", ("type: %u col:%u val: 0x%lx len: %u label: %u", type, ColId, (long) val, len, Label)); if (val != NULL) DBUG_DUMP("value", (uchar*)val, len); if (initial_interpreterCheck() == -1) DBUG_RETURN(-1); Interpreter::BinaryCondition c = (Interpreter::BinaryCondition)type; const NdbColumnImpl * col = m_currentTable->getColumn(ColId); if(col == 0){ abort(); } if (val == NULL) len = 0; else { if (! col->getStringType()) { // prevent assert in NdbSqlUtil on length error Uint32 sizeInBytes = col->m_attrSize * col->m_arraySize; if (len != 0 && len != sizeInBytes) { setErrorCodeAbort(4209); DBUG_RETURN(-1); } len = sizeInBytes; } } m_no_disk_flag &= (col->m_storageType == NDB_STORAGETYPE_DISK ? 0:1); Uint32 tempData[2000]; if (((UintPtr)val & 3) != 0) { memcpy(tempData, val, len); val = tempData; } if (insertATTRINFO(Interpreter::BranchCol(c, 0, 0, false)) == -1) DBUG_RETURN(-1); if (insertBranch(Label) == -1) DBUG_RETURN(-1); if (insertATTRINFO(Interpreter::BranchCol_2(col->m_attrId, len))) DBUG_RETURN(-1); Uint32 len2 = Interpreter::mod4(len); if(len2 == len){ insertATTRINFOloop((Uint32*)val, len2 >> 2); } else { len2 -= 4; insertATTRINFOloop((Uint32*)val, len2 >> 2); Uint32 tmp = 0; for (Uint32 i = 0; i < len-len2; i++) { char* p = (char*)&tmp; p[i] = ((char*)val)[len2+i]; } insertATTRINFO(tmp); } theErrorLine++; DBUG_RETURN(0); } int NdbOperation::branch_col_eq(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_eq %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::EQ, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_ne(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_ne %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::NE, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_lt(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_lt %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::LT, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_le(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_le %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::LE, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_gt(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_gt %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::GT, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_ge(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_ge %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::GE, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_like(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_like %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::LIKE, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_notlike(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_notlike %u %.*s(%u,%d) -> %u", ColId, len, (char*) val, len, nopad, Label)); return branch_col(Interpreter::NOT_LIKE, ColId, val, len, nopad, Label); } int NdbOperation::branch_col_null(Uint32 type, Uint32 ColId, Uint32 Label){ if (initial_interpreterCheck() == -1) return -1; if (insertATTRINFO(type) == -1) return -1; if (insertBranch(Label) == -1) return -1; Uint32 attrId= NdbColumnImpl::getImpl(* m_currentTable->getColumn(ColId)).m_attrId; if (insertATTRINFO(Interpreter::BranchCol_2(attrId))) return -1; theErrorLine++; return 0; } int NdbOperation::branch_col_eq_null(Uint32 ColId, Uint32 Label){ INT_DEBUG(("branch_col_eq_null %u -> %u", ColId, Label)); return branch_col_null(Interpreter::BRANCH_ATTR_EQ_NULL, ColId, Label); } int NdbOperation::branch_col_ne_null(Uint32 ColId, Uint32 Label){ INT_DEBUG(("branch_col_ne_null %u -> %u", ColId, Label)); return branch_col_null(Interpreter::BRANCH_ATTR_NE_NULL, ColId, Label); }