19 #include <ndb_global.h>
20 #include <NdbDictionary.hpp>
21 #include <NdbIndexScanOperation.hpp>
22 #include "NdbQueryBuilder.hpp"
23 #include "NdbQueryOperation.hpp"
25 #include "NdbQueryBuilderImpl.hpp"
26 #include "NdbQueryOperationImpl.hpp"
27 #include "NdbInterpretedCode.hpp"
29 #include <signaldata/TcKeyReq.hpp>
30 #include <signaldata/TcKeyRef.hpp>
31 #include <signaldata/ScanTab.hpp>
32 #include <signaldata/QueryTree.hpp>
33 #include <signaldata/DbspjErr.hpp>
35 #include "AttributeHeader.hpp"
37 #include <Bitmask.hpp>
40 #define DEBUG_CRASH() assert(false)
48 #define UNUSED(x) ((void)(x))
51 static const bool testNextReq =
false;
54 static const int Err_TupleNotFound = 626;
55 static const int Err_MemoryAlloc = 4000;
56 static const int Err_SendFailed = 4002;
57 static const int Err_FunctionNotImplemented = 4003;
58 static const int Err_UnknownColumn = 4004;
59 static const int Err_ReceiveTimedOut = 4008;
60 static const int Err_NodeFailCausedAbort = 4028;
61 static const int Err_ParameterError = 4118;
62 static const int Err_SimpleDirtyReadFailed = 4119;
63 static const int Err_WrongFieldLength = 4209;
64 static const int Err_ReadTooMuch = 4257;
65 static const int Err_InvalidRangeNo = 4286;
66 static const int Err_DifferentTabForKeyRecAndAttrRec = 4287;
67 static const int Err_KeyIsNULL = 4316;
68 static const int Err_FinaliseNotCalled = 4519;
69 static const int Err_InterpretedCodeWrongTab = 4524;
72 static const Uint16 tupleNotFound = 0xffff;
75 const bool traceSignals =
false;
83 Parallelism_adaptive = 0xffff0000,
89 Parallelism_max = 0xffff0001
110 static const Uint32 wordCount = 1;
113 : m_correlation((tupleNotFound<<16) | tupleNotFound)
120 Uint32 toUint32()
const
121 {
return m_correlation; }
123 Uint16 getTupleId()
const
124 {
return m_correlation & 0xffff;}
126 Uint16 getParentTupleId()
const
127 {
return m_correlation >> 16;}
130 Uint32 m_correlation;
136 static const Uint32 wordCount = 3;
139 m_corrPart(tupleData + tupleLength - wordCount)
141 assert(tupleLength >= wordCount);
143 == AttributeHeader::CORR_FACTOR64);
144 assert(
AttributeHeader(m_corrPart[0]).getByteSize() == 2*
sizeof(Uint32));
145 assert(getTupleCorrelation().getTupleId()<tupleNotFound);
146 assert(getTupleCorrelation().getParentTupleId()<tupleNotFound);
149 Uint32 getRootReceiverId()
const
150 {
return m_corrPart[2];}
156 const Uint32*
const m_corrPart;
203 Uint32 getFragNo()
const
220 void incrOutstandingResults(Int32 delta)
222 m_outstandingResults += delta;
225 void clearOutstandingResults()
227 m_outstandingResults = 0;
230 void setConfReceived(Uint32 tcPtrI);
244 assert(m_fragNo!=voidFragNo);
245 return m_confReceived && m_outstandingResults==0;
257 {
return getResultStream(op.getQueryOperationDef().getQueryOperationIx()); }
260 Uint32 getReceiverTcPtrI()
const;
280 m_remainingScans = nodeMask;
291 STATIC_CONST( voidFragNo = 0xffffffff);
307 Uint32 m_availResultSets;
317 Int32 m_outstandingResults;
332 Uint32 m_remainingScans;
362 Uint32 maxRows, Uint32 rowSize);
367 receiver.prepareReceive(m_buffer);
372 receiver.prepareRead(m_buffer,m_rowCount);
375 Uint32 getRowCount()
const
376 {
return m_rowCount; }
387 Uint32* m_batchOverflowCheck;
430 {
return m_receiver; }
433 {
return m_receiver; }
435 const char* getCurrentRow()
436 {
return m_receiver.get_row(); }
470 {
return m_iterState == Iter_finished; }
485 const Uint32 internalOpNo = m_operation.getQueryOperationDef().getQueryOperationId();
487 const bool complete = !((remainingScans >> internalOpNo) & 1);
488 assert(complete || isScanResult());
492 bool isScanQuery()
const
493 {
return (m_properties & Is_Scan_Query); }
495 bool isScanResult()
const
496 {
return (m_properties & Is_Scan_Result); }
498 bool isInnerJoin()
const
499 {
return (m_properties & Is_Inner_Join); }
542 explicit TupleSet() : m_hash_head(tupleNotFound)
564 const enum properties
566 Is_Scan_Query = 0x01,
567 Is_Scan_Result = 0x02,
603 TupleSet* m_tupleSet;
605 void buildResultCorrelations();
607 Uint16 getTupleId(Uint16 tupleNo)
const
608 {
return (m_tupleSet) ? m_tupleSet[tupleNo].m_tupleId : 0; }
610 Uint16 getCurrentTupleId()
const
611 {
return (m_currentRow==tupleNotFound) ? tupleNotFound : getTupleId(m_currentRow); }
613 Uint16 findTupleWithParentId(Uint16 parentId)
const;
615 Uint16 findNextTuple(Uint16 tupleNo)
const;
635 assert(m_buffer == NULL);
638 m_buffer =
new char[m_objSize*m_maxObjs+1];
639 if (unlikely(m_buffer == NULL))
641 return Err_MemoryAlloc;
643 m_buffer[m_maxObjs * m_objSize] = endMarker;
649 assert(m_buffer == NULL || m_buffer[m_maxObjs * m_objSize] == endMarker);
651 assert(m_buffer == NULL ||
652 memset(m_buffer, 0xff, m_maxObjs * m_objSize) != NULL);
661 assert(m_nextObjNo + noOfObjs <= m_maxObjs);
662 void *
const result = m_buffer+m_objSize*m_nextObjNo;
663 m_nextObjNo += noOfObjs;
664 return m_nextObjNo > m_maxObjs ? NULL : result;
670 NdbResultSet::NdbResultSet() :
672 m_batchOverflowCheck(NULL),
673 m_correlations(NULL),
685 const int bufferSize = rowSize * maxRows;
687 m_buffer =
reinterpret_cast<char*
>(bufferAlloc.
allocObjMem(bufferSize));
690 m_batchOverflowCheck =
691 reinterpret_cast<Uint32*
>(bufferAlloc.
allocObjMem(
sizeof(Uint32)));
692 *m_batchOverflowCheck = 0xacbd1234;
709 m_rootFrag(rootFrag),
710 m_operation(operation),
711 m_parent(operation.getParentOperation()
712 ? &rootFrag.getResultStream(*operation.getParentOperation())
716 ((operation.getQueryDef().isScanQuery()
718 | (operation.getQueryOperationDef().isScanOperation()
719 ? Is_Scan_Result : 0)
720 | (operation.getQueryOperationDef().getMatchType() !=
NdbQueryOptions::MatchAll
721 ? Is_Inner_Join : 0))),
722 m_receiver(operation.getQuery().getNdbTransaction().getNdb()),
723 m_resultSets(), m_read(0xffffffff), m_recv(0),
724 m_iterState(Iter_notStarted),
725 m_currentRow(tupleNotFound),
730 NdbResultStream::~NdbResultStream()
732 for (
int i = static_cast<int>(m_maxRows)-1;
i >= 0;
i--)
734 m_tupleSet[
i].~TupleSet();
741 const Uint32 rowSize = m_operation.
getRowSize();
751 new (query.getTupleSetAlloc().
allocObjMem(m_maxRows))
757 m_resultSets[0].init(query, m_maxRows, rowSize);
759 m_receiver.init(NdbReceiver::NDB_QUERY_OPERATION,
false, &m_operation);
760 m_receiver.do_setup_ndbrecord(
761 m_operation.getNdbRecord(),
766 m_resultSets[m_recv].m_buffer);
778 NdbResultStream::findTupleWithParentId(Uint16 parentId)
const
780 assert ((parentId==tupleNotFound) == (m_parent==NULL));
782 if (likely(m_resultSets[m_read].m_rowCount>0))
784 if (m_tupleSet==NULL)
786 assert (m_resultSets[m_read].m_rowCount <= 1);
790 const Uint16 hash = (parentId % m_maxRows);
791 Uint16 currentRow = m_tupleSet[hash].m_hash_head;
792 while (currentRow != tupleNotFound)
794 assert(currentRow < m_maxRows);
795 if (m_tupleSet[currentRow].m_skip ==
false &&
796 m_tupleSet[currentRow].m_parentId == parentId)
800 currentRow = m_tupleSet[currentRow].m_hash_next;
803 return tupleNotFound;
812 NdbResultStream::findNextTuple(Uint16 tupleNo)
const
814 if (tupleNo!=tupleNotFound && m_tupleSet!=NULL)
816 assert(tupleNo < m_maxRows);
817 Uint16 parentId = m_tupleSet[tupleNo].m_parentId;
818 Uint16 nextRow = m_tupleSet[tupleNo].m_hash_next;
820 while (nextRow != tupleNotFound)
822 assert(nextRow < m_maxRows);
823 if (m_tupleSet[nextRow].m_skip ==
false &&
824 m_tupleSet[nextRow].m_parentId == parentId)
828 nextRow = m_tupleSet[nextRow].m_hash_next;
831 return tupleNotFound;
838 Uint16 parentId = tupleNotFound;
841 parentId = m_parent->getCurrentTupleId();
842 if (parentId == tupleNotFound)
844 m_currentRow = tupleNotFound;
845 m_iterState = Iter_finished;
846 return tupleNotFound;
850 if ((m_currentRow=findTupleWithParentId(parentId)) != tupleNotFound)
852 m_iterState = Iter_started;
853 m_receiver.setCurrentRow(m_resultSets[m_read].m_buffer, m_currentRow);
857 m_iterState = Iter_finished;
858 return tupleNotFound;
862 NdbResultStream::nextResult()
865 if (m_currentRow != tupleNotFound &&
866 (m_currentRow=findNextTuple(m_currentRow)) != tupleNotFound)
868 m_iterState = Iter_started;
869 m_receiver.setCurrentRow(m_resultSets[m_read].m_buffer, m_currentRow);
872 m_iterState = Iter_finished;
873 return tupleNotFound;
889 receiveSet.m_correlations[receiveSet.m_rowCount] = correlation;
892 m_receiver.execTRANSID_AI(ptr, len);
893 receiveSet.m_rowCount++;
904 assert (isScanQuery());
906 m_iterState = Iter_notStarted;
907 m_currentRow = tupleNotFound;
908 m_resultSets[m_recv].prepareReceive(m_receiver);
914 for (Uint32 childNo = 0; childNo < m_operation.getNoOfChildOperations();
933 assert(isComplete || isScanResult());
939 readResult.prepareRead(m_receiver);
946 if (m_tupleSet!=NULL)
948 const bool newResults = (m_iterState!=Iter_finished);
951 buildResultCorrelations();
956 for (Uint32 tupleNo=0; tupleNo<readResult.getRowCount(); tupleNo++)
958 m_tupleSet[tupleNo].m_skip =
false;
969 for (Uint32 childNo=0; childNo < m_operation.getNoOfChildOperations(); childNo++)
973 const bool allSubScansComplete = childStream.
prepareResultSet(remainingScans);
975 Uint32 childId = child.getQueryOperationDef().getQueryOperationIx();
978 const bool skipNonMatches = !allSubScansComplete ||
979 childStream.isInnerJoin();
981 if (m_tupleSet!=NULL)
983 for (Uint32 tupleNo=0; tupleNo<readResult.getRowCount(); tupleNo++)
985 if (!m_tupleSet[tupleNo].m_skip)
987 Uint16 tupleId = getTupleId(tupleNo);
988 if (childStream.findTupleWithParentId(tupleId)!=tupleNotFound)
989 m_tupleSet[tupleNo].m_hasMatchingChild.set(childId);
1000 else if (skipNonMatches
1001 || m_tupleSet[tupleNo].m_hasMatchingChild.get(childId))
1002 m_tupleSet[tupleNo].m_skip =
true;
1006 isComplete &= allSubScansComplete;
1010 m_iterState = Iter_notStarted;
1011 m_currentRow = tupleNotFound;
1030 NdbResultStream::buildResultCorrelations()
1035 assert(readResult.m_batchOverflowCheck==NULL ||
1036 *readResult.m_batchOverflowCheck==0xacbd1234);
1041 for (Uint32
i=0;
i<m_maxRows;
i++)
1043 m_tupleSet[
i].m_hash_head = tupleNotFound;
1047 for (Uint32 tupleNo=0; tupleNo<readResult.m_rowCount; tupleNo++)
1049 const Uint16 tupleId = readResult.m_correlations[tupleNo].getTupleId();
1050 const Uint16 parentId = (m_parent!=NULL)
1051 ? readResult.m_correlations[tupleNo].getParentTupleId()
1054 m_tupleSet[tupleNo].m_skip =
false;
1055 m_tupleSet[tupleNo].m_parentId = parentId;
1056 m_tupleSet[tupleNo].m_tupleId = tupleId;
1060 const Uint16 hash = (parentId % m_maxRows);
1069 m_tupleSet[hash].m_hash_head = tupleNo;
1071 m_tupleSet[tupleNo-1].m_hash_next = tupleNo;
1072 m_tupleSet[tupleNo].m_hash_next = tupleNotFound;
1077 m_tupleSet[tupleNo].m_hash_next = m_tupleSet[hash].m_hash_head;
1078 m_tupleSet[hash].m_hash_head = tupleNo;
1091 for(Uint32 fragNo = 0; fragNo < noOfFrags; fragNo++)
1098 assert((receiverId & 0x3) == 0);
1100 (receiverId >> 2) % noOfFrags;
1101 frags[fragNo].m_idMapNext = frags[hash].m_idMapHead;
1102 frags[hash].m_idMapHead = fragNo;
1116 assert((receiverId & 0x3) == 0);
1117 const int hash = (receiverId >> 2) % noOfFrags;
1118 int current = frags[hash].m_idMapHead;
1119 assert(current < static_cast<int>(noOfFrags));
1120 while (current >= 0 && frags[current].
getReceiverId() != receiverId)
1122 current = frags[current].m_idMapNext;
1123 assert(current < static_cast<int>(noOfFrags));
1125 if (unlikely (current < 0))
1131 return frags+current;
1136 NdbRootFragment::NdbRootFragment():
1138 m_fragNo(voidFragNo),
1139 m_resultStreams(NULL),
1140 m_availResultSets(0),
1141 m_outstandingResults(0),
1142 m_confReceived(false),
1143 m_remainingScans(0),
1149 NdbRootFragment::~NdbRootFragment()
1151 assert(m_resultStreams==NULL);
1156 assert(m_fragNo==voidFragNo);
1162 assert(m_resultStreams!=NULL);
1168 m_resultStreams[opNo].
prepare();
1179 if (m_resultStreams != NULL)
1183 m_resultStreams[opNo].~NdbResultStream();
1191 m_resultStreams = NULL;
1197 assert(m_resultStreams);
1198 return m_resultStreams[operationNo];
1207 if (rootFrags != NULL)
1209 for (Uint32 fragNo = 0; fragNo < noOfFrags; fragNo++)
1211 rootFrags[fragNo].m_availResultSets = 0;
1224 assert(m_availResultSets==0);
1225 m_availResultSets++;
1237 return (m_availResultSets > 0);
1242 assert(m_fragNo!=voidFragNo);
1243 assert(m_outstandingResults == 0);
1244 assert(m_confReceived);
1258 m_confReceived =
false;
1269 assert(m_availResultSets>0);
1270 m_availResultSets--;
1280 void NdbRootFragment::setConfReceived(Uint32 tcPtrI)
1288 m_confReceived =
true;
1293 return m_confReceived && getReceiverTcPtrI()==RNIL;
1314 Uint32 NdbRootFragment::getReceiverTcPtrI()
const
1327 NdbQuery::~NdbQuery()
1331 NdbQuery::getNoOfOperations()
const
1337 NdbQuery::getQueryOperation(Uint32
index)
const
1339 return &m_impl.getQueryOperation(index).getInterface();
1343 NdbQuery::getQueryOperation(
const char* ident)
const
1346 return (op) ? &op->getInterface() : NULL;
1350 NdbQuery::getNoOfParameters()
const
1356 NdbQuery::getParameter(
const char*
name)
const
1358 return m_impl.getParameter(name);
1362 NdbQuery::getParameter(Uint32 num)
const
1364 return m_impl.getParameter(num);
1368 NdbQuery::setBound(
const NdbRecord *keyRecord,
1371 const int error = m_impl.setBound(keyRecord,bound);
1372 if (unlikely(error)) {
1383 return m_impl.
nextResult(fetchAllowed, forceSend);
1389 m_impl.
close(forceSend);
1395 return &m_impl.getNdbTransaction();
1400 return m_impl.getNdbError();
1411 NdbQueryOperation::~NdbQueryOperation()
1415 NdbQueryOperation::getNoOfParentOperations()
const
1417 return m_impl.getNoOfParentOperations();
1421 NdbQueryOperation::getParentOperation(Uint32
i)
const
1423 return &m_impl.getParentOperation(i).getInterface();
1427 NdbQueryOperation::getNoOfChildOperations()
const
1429 return m_impl.getNoOfChildOperations();
1433 NdbQueryOperation::getChildOperation(Uint32 i)
const
1435 return &m_impl.getChildOperation(i).getInterface();
1439 NdbQueryOperation::getQueryOperationDef()
const
1441 return m_impl.getQueryOperationDef().getInterface();
1445 NdbQueryOperation::getQuery()
const {
1446 return m_impl.getQuery().getInterface();
1453 return m_impl.getValue(anAttrName, resultBuffer);
1460 return m_impl.getValue(anAttrId, resultBuffer);
1467 if (unlikely(column==NULL)) {
1471 return m_impl.getValue(NdbColumnImpl::getImpl(*column), resultBuffer);
1478 const unsigned char* result_mask)
1480 if (unlikely(rec==0 || resBuffer==0)) {
1484 return m_impl.setResultRowBuf(rec, resBuffer, result_mask);
1488 NdbQueryOperation::setResultRowRef (
1490 const char* & bufRef,
1491 const unsigned char* result_mask)
1493 return m_impl.setResultRowRef(rec, bufRef, result_mask);
1505 return m_impl.getOrdering();
1532 return m_impl.firstResult();
1538 return m_impl.
nextResult(fetchAllowed, forceSend);
1542 NdbQueryOperation::isRowNULL()
const
1544 return m_impl.isRowNULL();
1548 NdbQueryOperation::isRowChanged()
const
1550 return m_impl.isRowChanged();
1569 NdbQueryParamValue::NdbQueryParamValue(Uint16 val) : m_type(Type_Uint16)
1570 { m_value.uint16 = val; }
1572 NdbQueryParamValue::NdbQueryParamValue(Uint32 val) : m_type(Type_Uint32)
1573 { m_value.uint32 = val; }
1575 NdbQueryParamValue::NdbQueryParamValue(Uint64 val) : m_type(Type_Uint64)
1576 { m_value.uint64 = val; }
1578 NdbQueryParamValue::NdbQueryParamValue(
double val) : m_type(Type_Double)
1579 { m_value.dbl = val; }
1582 NdbQueryParamValue::NdbQueryParamValue(
const char* val) : m_type(Type_string)
1583 { m_value.string = val; }
1586 NdbQueryParamValue::NdbQueryParamValue(
const void* val,
bool shrinkVarChar)
1587 : m_type(shrinkVarChar ? Type_raw_shrink : Type_raw)
1588 { m_value.raw = val; }
1591 NdbQueryParamValue::NdbQueryParamValue() : m_type(Type_NULL)
1601 const Uint32 maxSize = column.getSizeInBytes();
1604 dst.skipRestOfWord();
1624 return QRY_PARAMETER_HAS_WRONG_TYPE;
1626 len =
static_cast<Uint32
>(
sizeof(m_value.uint16));
1627 DBUG_ASSERT(len == maxSize);
1628 dst.appendBytes(&m_value.uint16, len);
1634 return QRY_PARAMETER_HAS_WRONG_TYPE;
1636 len =
static_cast<Uint32
>(
sizeof(m_value.uint32));
1637 DBUG_ASSERT(len == maxSize);
1638 dst.appendBytes(&m_value.uint32, len);
1644 return QRY_PARAMETER_HAS_WRONG_TYPE;
1646 len =
static_cast<Uint32
>(
sizeof(m_value.uint64));
1647 DBUG_ASSERT(len == maxSize);
1648 dst.appendBytes(&m_value.uint64, len);
1653 return QRY_PARAMETER_HAS_WRONG_TYPE;
1655 len =
static_cast<Uint32
>(
sizeof(m_value.dbl));
1656 DBUG_ASSERT(len == maxSize);
1657 dst.appendBytes(&m_value.dbl, len);
1664 return QRY_PARAMETER_HAS_WRONG_TYPE;
1666 len =
static_cast<Uint32
>(strlen(m_value.string));
1667 if (unlikely(len > maxSize))
1668 return QRY_CHAR_PARAMETER_TRUNCATED;
1670 dst.appendBytes(m_value.string, len);
1676 if (likely(column.m_arrayType == NDB_ARRAYTYPE_FIXED))
1679 dst.appendBytes(m_value.raw, maxSize);
1681 else if (column.m_arrayType == NDB_ARRAYTYPE_SHORT_VAR)
1683 len = 1+*((Uint8*)(m_value.raw));
1687 if (unlikely(len > 1+static_cast<Uint32>(column.
getLength())))
1688 return QRY_CHAR_PARAMETER_TRUNCATED;
1690 dst.appendBytes(m_value.raw, len);
1692 else if (column.m_arrayType == NDB_ARRAYTYPE_MEDIUM_VAR)
1694 len = 2+uint2korr((Uint8*)m_value.raw);
1698 if (unlikely(len > 2+static_cast<Uint32>(column.
getLength())))
1699 return QRY_CHAR_PARAMETER_TRUNCATED;
1700 dst.appendBytes(m_value.raw, len);
1708 case Type_raw_shrink:
1710 if (unlikely(column.m_arrayType != NDB_ARRAYTYPE_SHORT_VAR))
1711 return QRY_PARAMETER_HAS_WRONG_TYPE;
1718 len = 1+uint2korr((Uint8*)m_value.raw);
1719 assert(len <= 0x100);
1721 if (unlikely(len > 1+static_cast<Uint32>(column.
getLength())))
1722 return QRY_CHAR_PARAMETER_TRUNCATED;
1724 const Uint8 shortLen =
static_cast<Uint8
>(len-1);
1725 dst.appendBytes(&shortLen, 1);
1726 dst.appendBytes(((Uint8*)m_value.raw)+2, shortLen);
1733 if (unlikely(dst.isMemoryExhausted())) {
1734 return Err_MemoryAlloc;
1744 const NdbQueryDefImpl& queryDef):
1747 m_tcState(Inactive),
1749 m_queryDef(&queryDef),
1752 m_transaction(trans),
1753 m_scanTransaction(NULL),
1755 m_countOperations(0),
1761 m_finalBatchFrags(0),
1763 m_shortestBound(0xffffffff),
1766 m_startIndicator(false),
1767 m_commitIndicator(false),
1768 m_prunability(Prune_No),
1773 m_pointerAlloc(sizeof(void*)),
1774 m_rowBufferAlloc(sizeof(char))
1777 m_countOperations = queryDef.getNoOfOperations();
1778 const int error = m_operationAlloc.init(m_countOperations);
1779 if (unlikely(error != 0))
1781 setErrorCode(error);
1785 (m_operationAlloc.allocObjMem(m_countOperations));
1789 for (Uint32 i=0; i<m_countOperations; ++
i)
1791 const NdbQueryOperationDefImpl& def = queryDef.getQueryOperation(i);
1794 if (m_error.code != 0)
1797 for (
int j = static_cast<int>(i)-1; j>= 0; j--)
1799 m_operations[j].~NdbQueryOperationImpl();
1801 m_operations = NULL;
1807 m_attrInfo.append(queryDef.getSerialized());
1810 NdbQueryImpl::~NdbQueryImpl()
1817 assert(m_state==Closed);
1818 assert(m_rootFrags==NULL);
1823 if (m_operations != NULL) {
1824 for (
int i=m_countOperations-1; i>=0; --
i)
1825 { m_operations[
i].~NdbQueryOperationImpl();
1827 m_operations = NULL;
1829 m_state = Destructed;
1833 NdbQueryImpl::postFetchRelease()
1835 if (m_rootFrags != NULL)
1837 for (
unsigned i=0; i<m_rootFragCount; i++)
1841 if (m_operations != NULL)
1843 for (
unsigned i=0; i<m_countOperations; i++)
1844 { m_operations[
i].postFetchRelease();
1847 delete[] m_rootFrags;
1850 m_rowBufferAlloc.
reset();
1851 m_tupleSetAlloc.
reset();
1852 m_resultStreamAlloc.
reset();
1859 const NdbQueryDefImpl& queryDef)
1861 if (queryDef.getNoOfOperations()==0) {
1862 trans.setErrorCode(QRY_HAS_ZERO_OPERATIONS);
1867 if (unlikely(query==NULL)) {
1868 trans.setOperationErrorCodeAbort(Err_MemoryAlloc);
1871 if (unlikely(query->m_error.
code != 0))
1877 assert(query->m_state==Initial);
1897 const int error = getRoot().prepareKeyInfo(m_keyInfo, paramValues);
1898 if (unlikely(error != 0))
1908 if (
getQueryDef().getQueryOperation(i).getNoOfParameters() > 0)
1910 const int error = getQueryOperation(i).serializeParams(paramValues);
1911 if (unlikely(error != 0))
1918 assert(m_state<Defined);
1925 insert_bound(Uint32Buffer& keyInfo,
const NdbRecord *key_record,
1926 Uint32 column_index,
1930 char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE];
1933 bool is_null= column->is_null(row);
1935 const void *aValue= row+column->offset;
1941 if (column->flags & NdbRecord::IsMysqldShrinkVarchar)
1943 len_ok= column->shrink_varchar(row, len, buf);
1948 len_ok= column->get_var_length(row, len);
1951 return Err_WrongFieldLength;
1956 keyInfo.append(bound_type);
1957 keyInfo.append(ah.m_value);
1958 keyInfo.appendBytes(aValue,len);
1965 NdbQueryImpl::setBound(
const NdbRecord *key_record,
1968 m_prunability = Prune_Unknown;
1969 if (unlikely(bound==NULL))
1970 return QRY_REQ_ARG_IS_NULL;
1972 assert (getRoot().getQueryOperationDef().getType()
1974 int startPos = m_keyInfo.getSize();
1980 if (unlikely(bound->range_no > NdbIndexScanOperation::MaxRangeNo))
1983 return Err_InvalidRangeNo;
1985 assert (bound->range_no == m_num_bounds);
1988 Uint32 key_count= bound->low_key_count;
1989 Uint32 common_key_count= key_count;
1990 if (key_count < bound->high_key_count)
1991 key_count= bound->high_key_count;
1993 common_key_count= bound->high_key_count;
1995 if (m_shortestBound > common_key_count)
1997 m_shortestBound = common_key_count;
2000 const bool openRange= ((bound->low_key == NULL || bound->low_key_count == 0) &&
2001 (bound->high_key == NULL || bound->high_key_count == 0));
2002 if (likely(!openRange))
2010 const bool isEqRange=
2011 (bound->low_key == bound->high_key) &&
2012 (bound->low_key_count == bound->high_key_count) &&
2013 (bound->low_inclusive && bound->high_inclusive);
2018 for (
unsigned j= 0; j<key_count; j++)
2021 insert_bound(m_keyInfo, key_record, key_record->key_indexes[j],
2023 if (unlikely(error))
2034 for (
unsigned j= 0; j<key_count; j++)
2038 if (bound->low_key && j<bound->low_key_count)
2041 bound_type= bound->low_inclusive || j+1 < bound->low_key_count ?
2044 insert_bound(m_keyInfo, key_record, key_record->key_indexes[j],
2045 bound->low_key, bound_type);
2046 if (unlikely(error))
2050 if (bound->high_key && j<bound->high_key_count)
2053 bound_type= bound->high_inclusive || j+1 < bound->high_key_count ?
2056 insert_bound(m_keyInfo, key_record, key_record->key_indexes[j],
2057 bound->high_key, bound_type);
2058 if (unlikely(error))
2072 m_keyInfo.append(ah.m_value);
2075 Uint32 length = m_keyInfo.getSize()-startPos;
2076 if (unlikely(m_keyInfo.isMemoryExhausted())) {
2077 return Err_MemoryAlloc;
2078 }
else if (unlikely(length > 0xFFFF)) {
2079 return QRY_DEFINITION_TOO_LARGE;
2080 }
else if (likely(length > 0)) {
2081 m_keyInfo.put(startPos, m_keyInfo.get(startPos) | (length << 16) | (bound->range_no << 4));
2084 #ifdef TRACE_SERIALIZATION
2085 ndbout <<
"Serialized KEYINFO w/ bounds for indexScan root : ";
2086 for (Uint32 i = startPos; i < m_keyInfo.getSize(); i++) {
2088 sprintf(buf,
"%.8x", m_keyInfo.get(i));
2089 ndbout << buf <<
" ";
2094 assert(m_state<=Defined);
2103 return m_countOperations;
2109 return getQueryOperation(Uint32(0)).getNoOfLeafOperations();
2113 NdbQueryImpl::getQueryOperation(Uint32 index)
const
2115 assert(index<m_countOperations);
2116 return m_operations[
index];
2120 NdbQueryImpl::getQueryOperation(
const char* ident)
const
2122 for(Uint32 i = 0; i<m_countOperations; i++){
2123 if(strcmp(m_operations[i].getQueryOperationDef().getName(), ident) == 0){
2124 return &m_operations[
i];
2137 NdbQueryImpl::getParameter(
const char* name)
const
2143 NdbQueryImpl::getParameter(Uint32 num)
const
2160 if (unlikely(m_state < Executing || m_state >= Closed)) {
2161 assert (m_state >= Initial && m_state < Destructed);
2162 if (m_state == Failed)
2167 return NdbQuery::NextResult_error;
2172 while (m_state != EndOfData)
2175 getQueryOperation(m_globalCursor).
nextResult(fetchAllowed,forceSend);
2177 if (unlikely(res == NdbQuery::NextResult_error))
2180 else if (res == NdbQuery::NextResult_scanComplete)
2182 if (m_globalCursor == 0)
2187 else if (res == NdbQuery::NextResult_gotRow)
2194 res = getQueryOperation(child).firstResult();
2195 if (unlikely(res == NdbQuery::NextResult_error))
2197 else if (res == NdbQuery::NextResult_gotRow)
2198 m_globalCursor = child;
2200 return NdbQuery::NextResult_gotRow;
2204 assert (res == NdbQuery::NextResult_bufferEmpty);
2209 assert (m_state == EndOfData);
2210 return NdbQuery::NextResult_scanComplete;
2222 NdbQueryImpl::nextRootResult(
bool fetchAllowed,
bool forceSend)
2228 while (m_state != EndOfData)
2231 if (unlikely(rootFrag==NULL))
2240 const FetchResult fetchResult = awaitMoreResults(forceSend);
2241 switch (fetchResult) {
2243 case FetchResult_ok:
2244 assert(m_state != Failed);
2245 rootFrag = m_applFrags.getCurrent();
2246 assert (rootFrag!=NULL);
2249 case FetchResult_noMoreData:
2250 assert(m_state != Failed);
2251 assert (m_applFrags.getCurrent()==NULL);
2252 getRoot().nullifyResult();
2253 m_state = EndOfData;
2255 return NdbQuery::NextResult_scanComplete;
2257 case FetchResult_noMoreCache:
2258 assert(m_state != Failed);
2259 assert (m_applFrags.getCurrent()==NULL);
2260 getRoot().nullifyResult();
2265 return NdbQuery::NextResult_bufferEmpty;
2267 case FetchResult_gotError:
2268 assert (m_error.
code != 0);
2269 return NdbQuery::NextResult_error;
2279 m_applFrags.reorganize();
2281 rootFrag = m_applFrags.getCurrent();
2294 const Uint32 cnt = m_applFrags.getFetchMore(frags);
2295 if (cnt > 0 && sendFetchMore(frags, cnt, forceSend) != 0)
2297 return NdbQuery::NextResult_error;
2305 return NdbQuery::NextResult_gotRow;
2309 assert (m_state == EndOfData);
2310 return NdbQuery::NextResult_scanComplete;
2319 NdbQueryImpl::FetchResult
2320 NdbQueryImpl::awaitMoreResults(
bool forceSend)
2322 assert(m_applFrags.getCurrent() == NULL);
2327 assert (m_scanTransaction);
2328 assert (m_state==Executing);
2340 while (likely(!hasReceivedError()))
2345 m_applFrags.prepareMoreResults(m_rootFrags,m_rootFragCount);
2346 if (m_applFrags.getCurrent() != NULL)
2348 return FetchResult_ok;
2354 if (m_pendingFrags == 0)
2358 : FetchResult_noMoreData;
2361 const Uint32 timeout = ndb->get_waitfor_timeout();
2363 const Uint32 seq = m_transaction.theNodeSequence;
2366 const FetchResult waitResult =
static_cast<FetchResult
>
2367 (poll_guard.wait_scan(3*timeout,
2371 if (ndb->getNodeSequence(nodeId) != seq)
2372 setFetchTerminated(Err_NodeFailCausedAbort,
false);
2373 else if (likely(waitResult == FetchResult_ok))
2375 else if (waitResult == FetchResult_timeOut)
2376 setFetchTerminated(Err_ReceiveTimedOut,
false);
2378 setFetchTerminated(Err_NodeFailCausedAbort,
false);
2380 assert (m_state != Failed);
2385 assert (m_error.
code);
2386 return FetchResult_gotError;
2395 m_applFrags.prepareMoreResults(m_rootFrags,m_rootFragCount);
2396 if (m_applFrags.getCurrent() != NULL)
2398 return FetchResult_ok;
2406 assert(m_pendingFrags == 0);
2408 return FetchResult_noMoreData;
2425 ndbout <<
"NdbQueryImpl::handleBatchComplete"
2426 <<
", fragNo=" << rootFrag.getFragNo()
2427 <<
", pendingFrags=" << (m_pendingFrags-1)
2428 <<
", finalBatchFrags=" << m_finalBatchFrags
2436 if (likely(m_errorReceived == 0))
2440 assert(m_pendingFrags > 0);
2441 assert(m_pendingFrags <= m_rootFragCount);
2446 m_finalBatchFrags++;
2447 assert(m_finalBatchFrags <= m_rootFragCount);
2465 assert (m_state >= Initial && m_state < Destructed);
2466 if (m_state != Closed)
2468 if (m_tcState != Inactive)
2473 res = closeTcCursor(forceSend);
2478 m_applFrags.clear();
2480 Ndb*
const ndb = m_transaction.
getNdb();
2481 if (m_scanTransaction != NULL)
2483 assert (m_state != Closed);
2484 assert (m_scanTransaction->m_scanningQuery ==
this);
2485 m_scanTransaction->m_scanningQuery = NULL;
2487 ndb->theRemainingStartTransactions--;
2488 m_scanTransaction = NULL;
2508 assert (m_state >= Initial && m_state < Destructed);
2509 if (m_state != Closed) {
2519 assert (aErrorCode!=0);
2520 m_error.
code = aErrorCode;
2521 m_transaction.theErrorLine = 0;
2522 m_transaction.theErrorOperation = NULL;
2527 case Err_TupleNotFound:
2529 case Err_SimpleDirtyReadFailed:
2534 case Err_FunctionNotImplemented:
2535 case Err_UnknownColumn:
2536 case Err_WrongFieldLength:
2537 case Err_InvalidRangeNo:
2538 case Err_DifferentTabForKeyRecAndAttrRec:
2540 case QRY_REQ_ARG_IS_NULL:
2541 case QRY_PARAMETER_HAS_WRONG_TYPE:
2542 case QRY_RESULT_ROW_ALREADY_DEFINED:
2543 case QRY_CHAR_OPERAND_TRUNCATED:
2544 case QRY_WRONG_OPERATION_TYPE:
2545 case QRY_SEQUENTIAL_SCAN_SORTED:
2546 case QRY_SCAN_ORDER_ALREADY_SET:
2547 case QRY_MULTIPLE_SCAN_SORTED:
2548 m_transaction.setOperationErrorCode(aErrorCode);
2554 m_transaction.setOperationErrorCodeAbort(aErrorCode);
2564 NdbQueryImpl::setFetchTerminated(
int errorCode,
bool needClose)
2573 m_errorReceived = errorCode;
2584 NdbQueryImpl::hasReceivedError()
2586 if (unlikely(m_errorReceived))
2599 ndbout <<
"NdbQueryImpl::execTCKEYCONF()" << endl;
2605 rootFrag.setConfReceived(RNIL);
2606 rootFrag.incrOutstandingResults(-1);
2611 ret = handleBatchComplete(rootFrag);
2615 ndbout <<
"NdbQueryImpl::execTCKEYCONF(): returns:" << ret
2616 <<
", m_pendingFrags=" << m_pendingFrags
2628 ndbout <<
"NdbQueryImpl::execCLOSE_SCAN_REP()" << endl;
2630 setFetchTerminated(errorCode,needClose);
2636 if (unlikely(m_state != Defined)) {
2637 assert (m_state >= Initial && m_state < Destructed);
2638 if (m_state == Failed)
2653 if (getQueryOperation(0
U).m_parallelism == Parallelism_max)
2656 = getRoot().getQueryOperationDef().getTable().getFragmentCount();
2660 assert(getQueryOperation(0
U).m_parallelism != Parallelism_adaptive);
2662 = MIN(getRoot().getQueryOperationDef().getTable().getFragmentCount(),
2663 getQueryOperation(0
U).m_parallelism);
2665 Ndb*
const ndb = m_transaction.
getNdb();
2670 ndb->theRemainingStartTransactions++;
2672 if (scanTxn==NULL) {
2673 ndb->theRemainingStartTransactions--;
2677 scanTxn->theMagicNumber = 0x37412619;
2678 scanTxn->m_scanningQuery =
this;
2679 this->m_scanTransaction = scanTxn;
2683 m_rootFragCount = 1;
2693 error = m_pointerAlloc.
init(m_rootFragCount *
2694 (OrderedFragSet::pointersPerFragment));
2702 getRoot().calculateBatchedRows(NULL);
2703 getRoot().setBatchedRows(1);
2709 Uint32 totalBuffSize = 0;
2716 totalBuffSize +=
sizeof(Uint32);
2719 m_rowBufferAlloc.
init(m_rootFragCount * totalBuffSize);
2722 Uint32 totalRows = 0;
2727 error = m_tupleSetAlloc.
init(m_rootFragCount * totalRows);
2728 if (unlikely(error != 0))
2741 if (m_rootFrags == NULL)
2746 for (Uint32 i = 0; i<m_rootFragCount; i++)
2748 m_rootFrags[
i].
init(*
this, i);
2752 for (Uint32 i = 0; i < m_countOperations; i++) {
2753 const int error = m_operations[
i].prepareAttrInfo(m_attrInfo);
2754 if (unlikely(error))
2761 if (unlikely(m_attrInfo.isMemoryExhausted() || m_keyInfo.isMemoryExhausted())) {
2766 if (unlikely(m_attrInfo.getSize() > ScanTabReq::MaxTotalAttrInfo ||
2767 m_keyInfo.getSize() > ScanTabReq::MaxTotalAttrInfo)) {
2774 if(getRoot().getQueryOperationDef().getIndex()!=NULL)
2777 keyRec = getRoot().getQueryOperationDef().getIndex()->getDefaultRecord();
2778 assert(keyRec!=NULL);
2780 m_applFrags.prepare(m_pointerAlloc,
2781 getRoot().getOrdering(),
2784 getRoot().m_ndbRecord);
2791 #ifdef TRACE_SERIALIZATION
2792 ndbout <<
"Serialized ATTRINFO : ";
2793 for(Uint32 i = 0; i < m_attrInfo.getSize(); i++){
2795 sprintf(buf,
"%.8x", m_attrInfo.get(i));
2796 ndbout << buf <<
" ";
2801 assert (m_pendingFrags==0);
2816 :m_rootFrags(rootFrags),
2831 virtual void reset()
2832 { m_currFragNo = 0;};
2840 static const Uint32 bufSize = 16;
2844 const Uint32 m_fragCount;
2848 Uint32 m_currFragNo;
2850 Uint32 m_receiverIds[bufSize];
2859 if (m_currFragNo >= m_fragCount)
2867 while (cnt < bufSize && m_currFragNo < m_fragCount)
2869 m_receiverIds[cnt] = m_rootFrags[m_currFragNo].
getReceiverId();
2874 return m_receiverIds;
2885 :m_rootFrags(rootFrags),
2900 virtual void reset()
2901 { m_currFragNo = 0;};
2909 static const Uint32 bufSize = 16;
2913 const Uint32 m_fragCount;
2917 Uint32 m_currFragNo;
2919 Uint32 m_receiverIds[bufSize];
2928 if (m_currFragNo >= m_fragCount)
2936 while (cnt < bufSize && m_currFragNo < m_fragCount)
2938 m_receiverIds[cnt] = m_rootFrags[m_currFragNo]->getReceiverTcPtrI();
2943 return m_receiverIds;
2963 if (unlikely(m_state != Prepared)) {
2964 assert (m_state >= Initial && m_state < Destructed);
2965 if (m_state == Failed)
2977 const NdbQueryOperationDefImpl& rootDef = root.getQueryOperationDef();
2978 const NdbTableImpl*
const rootTable = rootDef.getIndex()
2979 ? rootDef.getIndex()->getIndexTable()
2980 : &rootDef.getTable();
2982 Uint32 tTableId = rootTable->m_id;
2983 Uint32 tSchemaVersion = rootTable->m_version;
2985 if (rootDef.isScanOperation())
2987 Uint32 scan_flags = 0;
2989 bool tupScan = (scan_flags & NdbScanOperation::SF_TupScan);
2990 bool rangeScan =
false;
2994 if (unlikely(error != 0))
2998 if ( (
int) rootTable->m_indexType ==
3004 const Uint32 descending =
3005 root.getOrdering()==NdbQueryOptions::ScanOrdering_descending ? 1 : 0;
3006 assert(descending==0 || (
int) rootTable->m_indexType ==
3007 (
int) NdbDictionary::Index::OrderedIndex);
3012 tSignal.setSignal(GSN_SCAN_TABREQ, refToBlock(m_scanTransaction->m_tcRef));
3019 scanTabReq->apiConnectPtr = m_scanTransaction->theTCConPtr;
3020 scanTabReq->buddyConPtr = m_scanTransaction->theBuddyConPtr;
3021 scanTabReq->spare = 0;
3022 scanTabReq->tableId = tTableId;
3023 scanTabReq->tableSchemaVersion = tSchemaVersion;
3024 scanTabReq->storedProcId = 0xFFFF;
3025 scanTabReq->transId1 = (Uint32) transId;
3026 scanTabReq->transId2 = (Uint32) (transId >> 32);
3029 Uint32 batchByteSize, firstBatchRows;
3030 NdbReceiver::calculate_batch_size(* ndb.theImpl,
3032 root.m_firstRecAttr,
3039 assert(batchRows==firstBatchRows);
3040 ScanTabReq::setScanBatch(reqInfo, batchRows);
3041 scanTabReq->batch_byte_size = batchByteSize;
3042 scanTabReq->first_batch_size = firstBatchRows;
3044 ScanTabReq::setViaSPJFlag(reqInfo, 1);
3045 ScanTabReq::setPassAllConfsFlag(reqInfo, 1);
3047 ScanTabReq::setRangeScanFlag(reqInfo, rangeScan);
3048 ScanTabReq::setDescendingFlag(reqInfo, descending);
3049 ScanTabReq::setTupScanFlag(reqInfo, tupScan);
3050 ScanTabReq::setNoDiskFlag(reqInfo, !root.diskInUserProjection());
3051 ScanTabReq::set4WordConf(reqInfo, 1);
3054 ScanTabReq::setLockMode(reqInfo,
false);
3055 ScanTabReq::setHoldLockFlag(reqInfo,
false);
3056 ScanTabReq::setReadCommittedFlag(reqInfo,
true);
3061 if (m_prunability == Prune_Yes)
3064 ScanTabReq::setDistributionKeyFlag(reqInfo, 1);
3065 scanTabReq->distributionKey= m_pruneHashVal;
3066 tSignal.setLength(ScanTabReq::StaticLength + 1);
3068 tSignal.setLength(ScanTabReq::StaticLength);
3070 scanTabReq->requestInfo = reqInfo;
3087 secs[0].sectionIter= &receiverIdIter;
3090 secs[1].sectionIter= &attrInfoIter;
3091 secs[1].sz= m_attrInfo.getSize();
3093 Uint32 numSections= 2;
3094 if (m_keyInfo.getSize() > 0)
3096 secs[2].sectionIter= &keyInfoIter;
3097 secs[2].sz= m_keyInfo.getSize();
3102 const int res = impl->sendFragmentedSignal(&tSignal, nodeId, secs, numSections);
3103 if (unlikely(res == -1))
3106 return FetchResult_sendFail;
3113 tSignal.setSignal(GSN_TCKEYREQ, refToBlock(m_transaction.m_tcRef));
3118 tcKeyReq->apiConnectPtr = m_transaction.theTCConPtr;
3119 tcKeyReq->apiOperationPtr = root.getIdOfReceiver();
3120 tcKeyReq->tableId = tTableId;
3121 tcKeyReq->tableSchemaVersion = tSchemaVersion;
3122 tcKeyReq->transId1 = (Uint32) transId;
3123 tcKeyReq->transId2 = (Uint32) (transId >> 32);
3126 tcKeyReq->setAttrinfoLen(attrLen, 0);
3127 tcKeyReq->setAPIVersion(attrLen, NDB_VERSION);
3128 tcKeyReq->attrLen = attrLen;
3131 Uint32 interpretedFlag= root.hasInterpretedCode() &&
3135 TcKeyReq::setViaSPJFlag(reqInfo,
true);
3136 TcKeyReq::setKeyLength(reqInfo, 0);
3137 TcKeyReq::setAIInTcKeyReq(reqInfo, 0);
3138 TcKeyReq::setInterpretedFlag(reqInfo, interpretedFlag);
3139 TcKeyReq::setStartFlag(reqInfo, m_startIndicator);
3140 TcKeyReq::setExecuteFlag(reqInfo, lastFlag);
3141 TcKeyReq::setNoDiskFlag(reqInfo, !root.diskInUserProjection());
3144 TcKeyReq::setDirtyFlag(reqInfo,
true);
3145 TcKeyReq::setSimpleFlag(reqInfo,
true);
3146 TcKeyReq::setCommitFlag(reqInfo, m_commitIndicator);
3147 tcKeyReq->requestInfo = reqInfo;
3149 tSignal.setLength(TcKeyReq::StaticLength);
3171 secs[TcKeyReq::KeyInfoSectionNum].p= m_keyInfo.addr();
3172 secs[TcKeyReq::KeyInfoSectionNum].sz= m_keyInfo.getSize();
3173 Uint32 numSections= 1;
3175 if (m_attrInfo.getSize() > 0)
3177 secs[TcKeyReq::AttrInfoSectionNum].p= m_attrInfo.addr();
3178 secs[TcKeyReq::AttrInfoSectionNum].sz= m_attrInfo.getSize();
3182 const int res = impl->sendSignal(&tSignal, nodeId, secs, numSections);
3183 if (unlikely(res == -1))
3186 return FetchResult_sendFail;
3188 m_transaction.OpSent();
3193 assert (m_pendingFrags==0);
3194 m_pendingFrags = m_rootFragCount;
3197 m_keyInfo.releaseExtend();
3198 m_attrInfo.releaseExtend();
3207 m_state = Executing;
3228 for (Uint32 i=0; i<cnt; i++)
3236 Ndb& ndb = *getNdbTransaction().
getNdb();
3238 tSignal.setSignal(GSN_SCAN_NEXTREQ, refToBlock(m_scanTransaction->m_tcRef));
3242 assert (m_scanTransaction);
3245 scanNextReq->apiConnectPtr = m_scanTransaction->theTCConPtr;
3246 scanNextReq->stopScan = 0;
3247 scanNextReq->transId1 = (Uint32) transId;
3248 scanNextReq->transId2 = (Uint32) (transId >> 32);
3249 tSignal.setLength(ScanNextReq::SignalLength);
3254 secs[ScanNextReq::ReceiverIdsSectionNum].sectionIter = &receiverIdIter;
3255 secs[ScanNextReq::ReceiverIdsSectionNum].sz = cnt;
3259 Uint32 seq = m_transaction.theNodeSequence;
3266 if (unlikely(hasReceivedError()))
3271 if (impl->getNodeSequence(nodeId) != seq ||
3272 impl->sendSignal(&tSignal, nodeId, secs, 1) != 0)
3277 impl->do_forceSend(forceSend);
3279 m_pendingFrags += cnt;
3286 NdbQueryImpl::closeTcCursor(
bool forceSend)
3291 const Uint32 timeout = ndb->get_waitfor_timeout();
3293 const Uint32 seq = m_transaction.theNodeSequence;
3300 if (unlikely(ndb->getNodeSequence(nodeId) != seq))
3307 while (m_pendingFrags > 0)
3309 const FetchResult result =
static_cast<FetchResult
>
3310 (poll_guard.wait_scan(3*timeout, nodeId, forceSend));
3312 if (unlikely(ndb->getNodeSequence(nodeId) != seq))
3313 setFetchTerminated(Err_NodeFailCausedAbort,
false);
3314 else if (unlikely(result != FetchResult_ok))
3316 if (result == FetchResult_timeOut)
3317 setFetchTerminated(Err_ReceiveTimedOut,
false);
3319 setFetchTerminated(Err_NodeFailCausedAbort,
false);
3321 if (hasReceivedError())
3327 assert(m_pendingFrags==0);
3329 m_errorReceived = 0;
3336 if (unlikely(error))
3342 while (m_pendingFrags > 0)
3344 const FetchResult result =
static_cast<FetchResult
>
3345 (poll_guard.wait_scan(3*timeout, nodeId, forceSend));
3347 if (unlikely(ndb->getNodeSequence(nodeId) != seq))
3348 setFetchTerminated(Err_NodeFailCausedAbort,
false);
3349 else if (unlikely(result != FetchResult_ok))
3351 if (result == FetchResult_timeOut)
3352 setFetchTerminated(Err_ReceiveTimedOut,
false);
3354 setFetchTerminated(Err_NodeFailCausedAbort,
false);
3356 if (hasReceivedError())
3371 NdbQueryImpl::sendClose(
int nodeId)
3378 tSignal.setSignal(GSN_SCAN_NEXTREQ, refToBlock(m_scanTransaction->m_tcRef));
3381 assert (m_scanTransaction);
3384 scanNextReq->apiConnectPtr = m_scanTransaction->theTCConPtr;
3385 scanNextReq->stopScan =
true;
3386 scanNextReq->transId1 = (Uint32) transId;
3387 scanNextReq->transId2 = (Uint32) (transId >> 32);
3388 tSignal.setLength(ScanNextReq::SignalLength);
3391 return impl->sendSignal(&tSignal, nodeId);
3398 if (m_prunability == Prune_Unknown)
3400 const int error = getRoot().getQueryOperationDef()
3401 .checkPrunable(m_keyInfo, m_shortestBound, prunable, m_pruneHashVal);
3402 if (unlikely(error != 0))
3408 m_prunability = prunable ? Prune_Yes : Prune_No;
3410 prunable = (m_prunability == Prune_Yes);
3419 NdbQueryImpl::OrderedFragSet::OrderedFragSet():
3421 m_activeFragCount(0),
3422 m_fetchMoreFragCount(0),
3423 m_finalFragCount(0),
3426 m_resultRecord(NULL),
3427 m_activeFrags(NULL),
3428 m_fetchMoreFrags(NULL)
3432 NdbQueryImpl::OrderedFragSet::~OrderedFragSet()
3434 m_activeFrags = NULL;
3435 m_fetchMoreFrags = NULL;
3438 void NdbQueryImpl::OrderedFragSet::clear()
3440 m_activeFragCount = 0;
3441 m_fetchMoreFragCount = 0;
3451 assert(m_activeFrags==NULL);
3452 assert(m_capacity==0);
3457 m_capacity = capacity;
3467 m_ordering = ordering;
3468 m_keyRecord = keyRecord;
3469 m_resultRecord = resultRecord;
3481 NdbQueryImpl::OrderedFragSet::getCurrent()
const
3489 if (unlikely(m_activeFragCount+m_finalFragCount < m_capacity))
3495 if (unlikely(m_activeFragCount==0))
3501 assert(!m_activeFrags[m_activeFragCount-1]->isEmpty());
3502 return m_activeFrags[m_activeFragCount-1];
3514 NdbQueryImpl::OrderedFragSet::reorganize()
3516 assert(m_activeFragCount > 0);
3528 m_fetchMoreFrags[m_fetchMoreFragCount++] = frag;
3530 m_activeFragCount--;
3531 assert(m_activeFragCount + m_fetchMoreFragCount + m_finalFragCount
3548 int last = m_activeFragCount-1;
3549 int middle = (first+last)/2;
3553 assert(middle<m_activeFragCount);
3554 const int cmpRes =
compare(*frag, *m_activeFrags[middle]);
3559 else if (cmpRes == 0)
3561 last = first = middle;
3567 middle = (first+last)/2;
3571 if (middle < m_activeFragCount-1)
3573 assert(
compare(*frag, *m_activeFrags[middle]) >= 0);
3574 memmove(m_activeFrags+middle+1,
3575 m_activeFrags+middle,
3577 m_activeFrags[middle] = frag;
3579 assert(verifySortOrder());
3581 assert(m_activeFragCount + m_fetchMoreFragCount + m_finalFragCount
3588 assert(m_activeFragCount+m_finalFragCount < m_capacity);
3590 m_activeFrags[m_activeFragCount++] = &frag;
3595 NdbQueryImpl::OrderedFragSet::prepareMoreResults(
NdbRootFragment rootFrags[], Uint32 cnt)
3597 for (Uint32 fragNo = 0; fragNo < cnt; fragNo++)
3607 assert(m_activeFragCount + m_fetchMoreFragCount + m_finalFragCount
3614 const int cnt = m_fetchMoreFragCount;
3615 frags = m_fetchMoreFrags;
3616 m_fetchMoreFragCount = 0;
3621 NdbQueryImpl::OrderedFragSet::verifySortOrder()
const
3623 for (
int i = 0; i<m_activeFragCount-1; i++)
3625 if (
compare(*m_activeFrags[i], *m_activeFrags[i+1]) < 0)
3664 == NdbQueryOptions::ScanOrdering_descending,
3674 NdbQueryOperationImpl::NdbQueryOperationImpl(
3676 const NdbQueryOperationDefImpl& def):
3679 m_queryImpl(queryImpl),
3680 m_operationDef(def),
3682 m_children(def.getNoOfChildOperations()),
3685 m_resultBuffer(NULL),
3690 m_firstRecAttr(NULL),
3691 m_lastRecAttr(NULL),
3693 m_interpretedCode(NULL),
3694 m_diskInUserProjection(false),
3695 m_parallelism(def.getQueryOperationIx() == 0
3696 ? Parallelism_max : Parallelism_adaptive),
3697 m_rowSize(0xffffffff)
3699 if (errno == ENOMEM)
3706 const NdbQueryOperationDefImpl* parent = def.getParentOperation();
3709 const Uint32 ix = parent->getQueryOperationIx();
3710 assert (ix < m_queryImpl.getNoOfOperations());
3711 m_parent = &m_queryImpl.getQueryOperation(ix);
3712 const int res = m_parent->m_children.push_back(
this);
3723 static_cast<const NdbQueryIndexScanOperationDefImpl&
>(def).getOrdering();
3727 m_ordering = defOrdering;
3732 NdbQueryOperationImpl::~NdbQueryOperationImpl()
3738 assert (m_firstRecAttr == NULL);
3739 assert (m_interpretedCode == NULL);
3747 NdbQueryOperationImpl::postFetchRelease()
3749 Ndb*
const ndb = m_queryImpl.getNdbTransaction().
getNdb();
3751 while (recAttr != NULL) {
3753 recAttr = recAttr->next();
3754 ndb->releaseRecAttr(saveRecAttr);
3756 m_firstRecAttr = NULL;
3760 if (m_resultRef!=NULL) {
3761 *m_resultRef = NULL;
3765 delete m_interpretedCode;
3766 m_interpretedCode = NULL;
3771 NdbQueryOperationImpl::getNoOfParentOperations()
const
3773 return (m_parent) ? 1 : 0;
3777 NdbQueryOperationImpl::getParentOperation(Uint32 i)
const
3779 assert(i==0 && m_parent!=NULL);
3783 NdbQueryOperationImpl::getParentOperation()
const
3789 NdbQueryOperationImpl::getNoOfChildOperations()
const
3791 return m_children.size();
3795 NdbQueryOperationImpl::getChildOperation(Uint32 i)
const
3797 return *m_children[
i];
3800 Int32 NdbQueryOperationImpl::getNoOfDescendantOperations()
const
3804 for (
unsigned i = 0; i < getNoOfChildOperations(); i++)
3805 children += 1 + getChildOperation(i).getNoOfDescendantOperations();
3811 NdbQueryOperationImpl::getNoOfLeafOperations()
const
3813 if (getNoOfChildOperations() == 0)
3820 for (
unsigned i = 0; i < getNoOfChildOperations(); i++)
3821 sum += getChildOperation(i).getNoOfLeafOperations();
3828 NdbQueryOperationImpl::getValue(
3829 const char* anAttrName,
3833 = m_operationDef.getTable().getColumn(anAttrName);
3834 if(unlikely(column==NULL)){
3838 return getValue(*column, resultBuffer);
3843 NdbQueryOperationImpl::getValue(
3848 = m_operationDef.getTable().getColumn(anAttrId);
3849 if(unlikely(column==NULL)){
3853 return getValue(*column, resultBuffer);
3858 NdbQueryOperationImpl::getValue(
3862 if (unlikely(getQuery().m_state != NdbQueryImpl::Defined)) {
3863 int state = getQuery().m_state;
3864 assert (state >= NdbQueryImpl::Initial && state < NdbQueryImpl::Destructed);
3866 if (state == NdbQueryImpl::Failed)
3873 Ndb*
const ndb = getQuery().getNdbTransaction().
getNdb();
3874 NdbRecAttr*
const recAttr = ndb->getRecAttr();
3875 if(unlikely(recAttr == NULL)) {
3879 if(unlikely(recAttr->setup(&column, resultBuffer))) {
3880 ndb->releaseRecAttr(recAttr);
3885 if(m_firstRecAttr == NULL){
3886 m_firstRecAttr = recAttr;
3888 m_lastRecAttr->next(recAttr);
3890 m_lastRecAttr = recAttr;
3891 assert(recAttr->next()==NULL);
3896 NdbQueryOperationImpl::setResultRowBuf (
3899 const unsigned char* result_mask)
3901 if (unlikely(rec==0)) {
3905 if (unlikely(getQuery().m_state != NdbQueryImpl::Defined)) {
3906 int state = getQuery().m_state;
3907 assert (state >= NdbQueryImpl::Initial && state < NdbQueryImpl::Destructed);
3909 if (state == NdbQueryImpl::Failed)
3917 static_cast<Uint32>(m_operationDef.getTable().getTableId())){
3920 getQuery().
setErrorCode(Err_DifferentTabForKeyRecAndAttrRec);
3923 if (unlikely(m_ndbRecord != NULL)) {
3924 getQuery().
setErrorCode(QRY_RESULT_ROW_ALREADY_DEFINED);
3928 m_read_mask = result_mask;
3929 m_resultBuffer = resBuffer;
3934 NdbQueryOperationImpl::setResultRowRef (
3936 const char* & bufRef,
3937 const unsigned char* result_mask)
3939 m_resultRef = &bufRef;
3940 *m_resultRef = NULL;
3941 return setResultRowBuf(rec, NULL, result_mask);
3945 NdbQueryOperationImpl::firstResult()
3947 if (unlikely(getQuery().m_state < NdbQueryImpl::Executing ||
3948 getQuery().m_state >= NdbQueryImpl::Closed)) {
3949 int state = getQuery().m_state;
3950 assert (state >= NdbQueryImpl::Initial && state < NdbQueryImpl::Destructed);
3951 if (state == NdbQueryImpl::Failed)
3956 return NdbQuery::NextResult_error;
3961 #if 0 // TODO ::firstResult() on root operation is unused, incomplete & untested
3962 if (unlikely(getParentOperation()==NULL))
3967 m_resultStreams[
i]->firstResult();
3969 rootFrag = m_queryImpl.m_applFrags.reorganize();
3970 assert(rootFrag==NULL || rootFrag==m_queryImpl.m_applFrags.getCurrent());
3976 assert(getParentOperation()!=NULL);
3977 rootFrag = m_queryImpl.m_applFrags.getCurrent();
3980 if (rootFrag != NULL)
3985 fetchRow(resultStream);
3986 return NdbQuery::NextResult_gotRow;
3990 return NdbQuery::NextResult_scanComplete;
3997 if (unlikely(getQuery().m_state < NdbQueryImpl::Executing ||
3998 getQuery().m_state >= NdbQueryImpl::Closed)) {
3999 int state = getQuery().m_state;
4000 assert (state >= NdbQueryImpl::Initial && state < NdbQueryImpl::Destructed);
4001 if (state == NdbQueryImpl::Failed)
4006 return NdbQuery::NextResult_error;
4011 return m_queryImpl.nextRootResult(fetchAllowed,forceSend);
4017 else if (m_operationDef.isScanOperation())
4019 const NdbRootFragment* rootFrag = m_queryImpl.m_applFrags.getCurrent();
4023 if (resultStream.nextResult() != tupleNotFound)
4025 fetchRow(resultStream);
4026 return NdbQuery::NextResult_gotRow;
4031 return NdbQuery::NextResult_scanComplete;
4038 const char* buff = resultStream.getCurrentRow();
4039 assert(buff!=NULL || (m_firstRecAttr==NULL && m_ndbRecord==NULL));
4041 m_isRowNull =
false;
4042 if (m_firstRecAttr != NULL)
4045 Uint32 posInRow = 0;
4046 while (recAttr != NULL)
4048 const char *attrData = NULL;
4049 Uint32 attrSize = 0;
4050 const int retVal1 = resultStream.getReceiver()
4051 .getScanAttrData(attrData, attrSize, posInRow);
4054 assert(attrData!=NULL);
4055 const bool retVal2 = recAttr
4056 ->receive_data(reinterpret_cast<const Uint32*>(attrData), attrSize);
4059 recAttr = recAttr->next();
4062 if (m_ndbRecord != NULL)
4064 if (m_resultRef!=NULL)
4067 *m_resultRef = buff;
4071 assert(m_resultBuffer!=NULL);
4073 memcpy(m_resultBuffer, buff,
4074 resultStream.getReceiver().m_record.m_ndb_record->m_row_size);
4081 NdbQueryOperationImpl::nullifyResult()
4087 if (m_resultRef!=NULL)
4090 *m_resultRef = NULL;
4093 for (Uint32 i = 0; i<getNoOfChildOperations(); i++)
4095 getChildOperation(i).nullifyResult();
4101 NdbQueryOperationImpl::isRowNULL()
const
4107 NdbQueryOperationImpl::isRowChanged()
const
4113 static bool isSetInMask(
const unsigned char* mask,
int bitNo)
4115 return mask[bitNo>>3] & 1<<(bitNo&7);
4119 NdbQueryOperationImpl::serializeProject(Uint32Buffer& attrInfo)
4121 Uint32 startPos = attrInfo.getSize();
4122 attrInfo.append(0
U);
4130 if (m_ndbRecord != NULL) {
4132 Uint32 requestedCols= 0;
4133 Uint32 maxAttrId= 0;
4135 for (Uint32 i= 0; i<m_ndbRecord->noOfColumns; i++)
4138 Uint32 attrId= col->attrId;
4140 if (m_read_mask == NULL || isSetInMask(m_read_mask, i))
4141 {
if (attrId > maxAttrId)
4144 readMask.
set(attrId);
4147 const NdbColumnImpl*
const column = getQueryOperationDef().getTable()
4148 .getColumn(col->column_no);
4149 if (column->getStorageType() == NDB_STORAGETYPE_DISK)
4151 m_diskInUserProjection =
true;
4157 if (requestedCols == (
unsigned)m_operationDef.getTable().getNoOfColumns()) {
4160 attrInfo.append(ah);
4161 }
else if (requestedCols > 0) {
4163 const Uint32 wordCount = 1+maxAttrId/32;
4164 Uint32* dst = attrInfo.alloc(wordCount+1);
4166 AttributeHeader::READ_PACKED, 4*wordCount);
4167 memcpy(dst+1, &readMask, 4*wordCount);
4181 attrInfo.append(ah);
4182 if (recAttr->getColumn()->getStorageType() == NDB_STORAGETYPE_DISK)
4184 m_diskInUserProjection =
true;
4186 recAttr = recAttr->next();
4189 bool withCorrelation =
getRoot().getQueryDef().isScanQuery();
4190 if (withCorrelation) {
4193 attrInfo.append(ah);
4197 Uint32 length = attrInfo.getSize() - startPos - 1 ;
4198 attrInfo.put(startPos, length);
4204 if (unlikely(paramValues == NULL))
4206 return QRY_REQ_ARG_IS_NULL;
4209 const NdbQueryOperationDefImpl& def = getQueryOperationDef();
4210 for (Uint32 i=0; i<def.getNoOfParameters(); i++)
4212 const NdbParamOperandImpl& paramDef = def.getParameter(i);
4221 const Uint32 oldSize = m_params.getSize();
4226 paramValue.
serializeValue(*paramDef.getColumn(), m_params, len, null);
4227 if (unlikely(error))
4230 return Err_KeyIsNULL;
4232 if(unlikely(m_params.isMemoryExhausted())){
4233 return Err_MemoryAlloc;
4236 m_params.put(oldSize, len);
4242 NdbQueryOperationImpl
4246 if (m_operationDef.isScanOperation())
4248 myClosestScan =
this;
4252 myClosestScan = closestScan;
4255 Uint32 maxBatchRows = 0;
4256 if (myClosestScan != NULL)
4265 const Ndb& ndb = *getQuery().getNdbTransaction().
getNdb();
4277 Uint32 batchByteSize, firstBatchRows;
4283 maxBatchRows = myClosestScan->m_maxBatchRows;
4284 NdbReceiver::calculate_batch_size(* ndb.theImpl,
4289 == Parallelism_max ?
4295 assert(maxBatchRows > 0);
4296 assert(firstBatchRows == maxBatchRows);
4300 for (Uint32 i = 0; i < m_children.size(); i++)
4302 const Uint32 childMaxBatchRows =
4303 m_children[
i]->calculateBatchedRows(myClosestScan);
4304 maxBatchRows = MIN(maxBatchRows, childMaxBatchRows);
4307 if (m_operationDef.isScanOperation())
4310 m_maxBatchRows = maxBatchRows;
4317 return maxBatchRows;
4323 NdbQueryOperationImpl::setBatchedRows(Uint32 batchedRows)
4325 if (!m_operationDef.isScanOperation())
4330 m_maxBatchRows = batchedRows;
4333 for (Uint32 i = 0; i < m_children.size(); i++)
4335 m_children[
i]->setBatchedRows(m_maxBatchRows);
4340 NdbQueryOperationImpl::prepareAttrInfo(Uint32Buffer& attrInfo)
4342 const NdbQueryOperationDefImpl& def = getQueryOperationDef();
4354 Uint32 startPos = attrInfo.getSize();
4355 attrInfo.alloc(QN_LookupParameters::NodeSize);
4356 Uint32 requestInfo = 0;
4358 if (m_params.getSize() > 0)
4362 requestInfo |= DABits::PI_KEY_PARAMS;
4363 attrInfo.append(m_params);
4367 if (unlikely(param==NULL))
4368 return Err_MemoryAlloc;
4370 param->requestInfo = requestInfo;
4371 param->resultData = getIdOfReceiver();
4372 Uint32 length = attrInfo.getSize() - startPos;
4373 if (unlikely(length > 0xFFFF)) {
4374 return QRY_DEFINITION_TOO_LARGE;
4376 QueryNodeParameters::setOpLen(param->len,
4377 QueryNodeParameters::QN_LOOKUP,
4380 #ifdef __TRACE_SERIALIZATION
4381 ndbout <<
"Serialized params for index node "
4382 << m_operationDef.getQueryOperationId()-1 <<
" : ";
4383 for(Uint32 i = startPos; i < attrInfo.getSize(); i++){
4385 sprintf(buf,
"%.8x", attrInfo.get(i));
4386 ndbout << buf <<
" ";
4394 Uint32 startPos = attrInfo.getSize();
4395 Uint32 requestInfo = 0;
4396 bool isRoot = (def.getQueryOperationIx()==0);
4398 QueryNodeParameters::OpType paramType =
4399 !def.isScanOperation() ? QueryNodeParameters::QN_LOOKUP
4400 : (isRoot) ? QueryNodeParameters::QN_SCAN_FRAG
4401 : QueryNodeParameters::QN_SCAN_INDEX;
4403 if (paramType == QueryNodeParameters::QN_SCAN_INDEX)
4404 attrInfo.alloc(QN_ScanIndexParameters::NodeSize);
4405 else if (paramType == QueryNodeParameters::QN_SCAN_FRAG)
4406 attrInfo.alloc(QN_ScanFragParameters::NodeSize);
4408 attrInfo.alloc(QN_LookupParameters::NodeSize);
4411 if (m_params.getSize() > 0 &&
4416 requestInfo |= DABits::PI_KEY_PARAMS;
4417 attrInfo.append(m_params);
4420 if (hasInterpretedCode())
4423 const int error= prepareInterpretedCode(attrInfo);
4424 if (unlikely(error))
4430 if (m_ndbRecord!=NULL || m_firstRecAttr!=NULL)
4432 requestInfo |= DABits::PI_ATTR_LIST;
4433 const int error = serializeProject(attrInfo);
4434 if (unlikely(error)) {
4439 if (diskInUserProjection())
4444 Uint32 length = attrInfo.getSize() - startPos;
4445 if (unlikely(length > 0xFFFF)) {
4446 return QRY_DEFINITION_TOO_LARGE;
4449 if (paramType == QueryNodeParameters::QN_SCAN_INDEX)
4452 if (unlikely(param==NULL))
4453 return Err_MemoryAlloc;
4455 Ndb& ndb = *m_queryImpl.getNdbTransaction().
getNdb();
4458 Uint32 batchByteSize, firstBatchRows;
4459 NdbReceiver::calculate_batch_size(* ndb.theImpl,
4467 assert(batchRows == firstBatchRows);
4469 assert(m_parallelism == Parallelism_max ||
4470 m_parallelism == Parallelism_adaptive);
4471 if (m_parallelism == Parallelism_max)
4475 param->requestInfo = requestInfo;
4477 assert(
getMaxBatchRows() < (1<<QN_ScanIndexParameters::BatchRowBits));
4478 assert(batchByteSize < (1 << (
sizeof param->batchSize * 8
4479 - QN_ScanIndexParameters::BatchRowBits)));
4481 param->resultData = getIdOfReceiver();
4482 QueryNodeParameters::setOpLen(param->len, paramType, length);
4484 else if (paramType == QueryNodeParameters::QN_SCAN_FRAG)
4487 if (unlikely(param==NULL))
4488 return Err_MemoryAlloc;
4490 param->requestInfo = requestInfo;
4491 param->resultData = getIdOfReceiver();
4492 QueryNodeParameters::setOpLen(param->len, paramType, length);
4496 assert(paramType == QueryNodeParameters::QN_LOOKUP);
4498 if (unlikely(param==NULL))
4499 return Err_MemoryAlloc;
4501 param->requestInfo = requestInfo;
4502 param->resultData = getIdOfReceiver();
4503 QueryNodeParameters::setOpLen(param->len, paramType, length);
4506 #ifdef __TRACE_SERIALIZATION
4507 ndbout <<
"Serialized params for node "
4508 << m_operationDef.getQueryOperationId() <<
" : ";
4509 for(Uint32 i = startPos; i < attrInfo.getSize(); i++){
4511 sprintf(buf,
"%.8x", attrInfo.get(i));
4512 ndbout << buf <<
" ";
4519 m_params.releaseExtend();
4526 NdbQueryOperationImpl::prepareKeyInfo(
4527 Uint32Buffer& keyInfo,
4531 #ifdef TRACE_SERIALIZATION
4532 int startPos = keyInfo.getSize();
4535 const NdbQueryOperationDefImpl::IndexBound* bounds = m_operationDef.getBounds();
4538 const int error = prepareIndexKeyInfo(keyInfo, bounds, actualParam);
4539 if (unlikely(error))
4543 const NdbQueryOperandImpl*
const* keys = m_operationDef.getKeyOperands();
4546 const int error = prepareLookupKeyInfo(keyInfo, keys, actualParam);
4547 if (unlikely(error))
4551 if (unlikely(keyInfo.isMemoryExhausted())) {
4552 return Err_MemoryAlloc;
4555 #ifdef TRACE_SERIALIZATION
4556 ndbout <<
"Serialized KEYINFO for NdbQuery root : ";
4557 for (Uint32 i = startPos; i < keyInfo.getSize(); i++) {
4559 sprintf(buf,
"%.8x", keyInfo.get(i));
4560 ndbout << buf <<
" ";
4578 serializeConstOp(
const NdbConstOperandImpl& constOp,
4579 Uint32Buffer& buffer,
4584 buffer.skipRestOfWord();
4585 len = constOp.getSizeInBytes();
4587 switch (constOp.getColumn()->getArrayType()) {
4588 case NdbDictionary::Column::ArrayTypeFixed:
4589 buffer.appendBytes(constOp.getAddr(), len);
4592 case NdbDictionary::Column::ArrayTypeShortVar:
4593 if (unlikely(len > 0xFF))
4594 return QRY_CHAR_OPERAND_TRUNCATED;
4595 shortLen[0] = (
unsigned char)len;
4596 buffer.appendBytes(shortLen, 1);
4597 buffer.appendBytes(constOp.getAddr(), len);
4601 case NdbDictionary::Column::ArrayTypeMediumVar:
4602 if (unlikely(len > 0xFFFF))
4603 return QRY_CHAR_OPERAND_TRUNCATED;
4604 shortLen[0] = (
unsigned char)(len & 0xFF);
4605 shortLen[1] = (
unsigned char)(len >> 8);
4606 buffer.appendBytes(shortLen, 2);
4607 buffer.appendBytes(constOp.getAddr(), len);
4614 if (unlikely(buffer.isMemoryExhausted())) {
4615 return Err_MemoryAlloc;
4621 appendBound(Uint32Buffer& keyInfo,
4627 keyInfo.append(type);
4628 const Uint32 oldSize = keyInfo.getSize();
4631 switch(bound->getKind()){
4632 case NdbQueryOperandImpl::Const:
4634 const NdbConstOperandImpl& constOp =
4635 static_cast<const NdbConstOperandImpl&
>(*bound);
4637 const int error = serializeConstOp(constOp, keyInfo, len);
4638 if (unlikely(error))
4643 case NdbQueryOperandImpl::Param:
4645 const NdbParamOperandImpl*
const paramOp
4646 =
static_cast<const NdbParamOperandImpl*
>(bound);
4647 const int paramNo = paramOp->getParamIx();
4648 assert(actualParam != NULL);
4652 actualParam[paramNo].
serializeValue(*paramOp->getColumn(), keyInfo,
4654 if (unlikely(error))
4657 return Err_KeyIsNULL;
4660 case NdbQueryOperandImpl::Linked:
4666 keyInfo.put(oldSize,
4674 NdbQueryOperationImpl::prepareIndexKeyInfo(
4675 Uint32Buffer& keyInfo,
4676 const NdbQueryOperationDefImpl::IndexBound* bounds,
4679 int startPos = keyInfo.getSize();
4680 if (bounds->lowKeys==0 && bounds->highKeys==0)
4683 const unsigned key_count =
4684 (bounds->lowKeys >= bounds->highKeys) ? bounds->lowKeys : bounds->highKeys;
4686 for (
unsigned keyNo = 0; keyNo < key_count; keyNo++)
4691 if (keyNo < bounds->lowKeys &&
4692 keyNo < bounds->highKeys &&
4693 bounds->low[keyNo] == bounds->high[keyNo])
4697 int error = appendBound(keyInfo, bound_type, bounds->low[keyNo], actualParam);
4698 if (unlikely(error))
4704 if (keyNo < bounds->lowKeys)
4707 bound_type= bounds->lowIncl || keyNo+1 < bounds->lowKeys ?
4710 int error = appendBound(keyInfo, bound_type, bounds->low[keyNo], actualParam);
4711 if (unlikely(error))
4716 if (keyNo < bounds->highKeys)
4719 bound_type= bounds->highIncl || keyNo+1 < bounds->highKeys ?
4722 int error = appendBound(keyInfo, bound_type, bounds->high[keyNo], actualParam);
4723 if (unlikely(error))
4729 Uint32 length = keyInfo.getSize()-startPos;
4730 if (unlikely(keyInfo.isMemoryExhausted())) {
4731 return Err_MemoryAlloc;
4732 }
else if (unlikely(length > 0xFFFF)) {
4733 return QRY_DEFINITION_TOO_LARGE;
4734 }
else if (likely(length > 0)) {
4735 keyInfo.put(startPos, keyInfo.get(startPos) | (length << 16));
4738 m_queryImpl.m_shortestBound =(bounds->lowKeys <= bounds->highKeys) ? bounds->lowKeys : bounds->highKeys;
4744 NdbQueryOperationImpl::prepareLookupKeyInfo(
4745 Uint32Buffer& keyInfo,
4746 const NdbQueryOperandImpl*
const keys[],
4749 const int keyCount = m_operationDef.getIndex()!=NULL ?
4750 static_cast<int>(m_operationDef.getIndex()->getNoOfColumns()) :
4751 m_operationDef.getTable().getNoOfPrimaryKeys();
4753 for (
int keyNo = 0; keyNo<keyCount; keyNo++)
4757 switch(keys[keyNo]->getKind()){
4758 case NdbQueryOperandImpl::Const:
4760 const NdbConstOperandImpl*
const constOp
4761 =
static_cast<const NdbConstOperandImpl*
>(keys[keyNo]);
4763 serializeConstOp(*constOp, keyInfo, dummy);
4764 if (unlikely(error))
4769 case NdbQueryOperandImpl::Param:
4771 const NdbParamOperandImpl*
const paramOp
4772 =
static_cast<const NdbParamOperandImpl*
>(keys[keyNo]);
4773 int paramNo = paramOp->getParamIx();
4774 assert(actualParam != NULL);
4778 actualParam[paramNo].
serializeValue(*paramOp->getColumn(), keyInfo,
4781 if (unlikely(error))
4784 return Err_KeyIsNULL;
4787 case NdbQueryOperandImpl::Linked:
4793 if (unlikely(keyInfo.isMemoryExhausted())) {
4794 return Err_MemoryAlloc;
4807 if (getQueryDef().isScanQuery())
4810 const Uint32 receiverId = correlData.getRootReceiverId();
4820 if (unlikely(rootFrag == NULL))
4827 tupleCorrelation = correlData.getTupleCorrelation();
4828 len -= CorrelationData::wordCount;
4832 ndbout <<
"NdbQueryOperationImpl::execTRANSID_AI()"
4833 <<
", operation no: " << getQueryOperationDef().getQueryOperationIx()
4834 <<
", fragment no: " << rootFrag->getFragNo()
4840 rootFrag->incrOutstandingResults(-1);
4845 ret = m_queryImpl.handleBatchComplete(*rootFrag);
4849 ndbout <<
"NdbQueryOperationImpl::execTRANSID_AI(): returns:" << ret
4850 <<
", *this=" << *
this << endl;
4860 ndbout <<
"NdbQueryOperationImpl::execTCKEYREF()" << endl;
4864 assert(!getQueryDef().isScanQuery());
4867 if (!getQuery().m_transaction.checkState_TransId(ref->transId))
4869 #ifdef NDB_NO_DROPPED_SIGNAL
4877 ref->errorCode != static_cast<Uint32>(Err_TupleNotFound))
4880 if (aSignal->getLength() == TcKeyRef::SignalLength)
4883 getQuery().m_error.
details = (
char *)ref->errorData;
4889 if (ref->errorCode != DbspjErr::NodeFailure)
4895 cnt += getNoOfDescendantOperations();
4896 if (getNoOfChildOperations() > 0)
4898 cnt += getNoOfLeafOperations();
4900 rootFrag.incrOutstandingResults(- Int32(cnt));
4905 rootFrag.clearOutstandingResults();
4911 ret = m_queryImpl.handleBatchComplete(rootFrag);
4915 ndbout <<
"NdbQueryOperationImpl::execTCKEYREF(): returns:" << ret
4917 <<
", *this=" << *
this << endl;
4929 ndbout <<
"NdbQueryOperationImpl::execSCAN_TABCONF(rows: " << rowCount
4930 <<
" nodeMask: H'" << hex << nodeMask <<
")" << endl;
4932 assert((tcPtrI==RNIL && nodeMask==0) ||
4933 (tcPtrI!=RNIL && nodeMask!=0));
4937 assert(m_operationDef.isScanOperation());
4943 if (unlikely(rootFrag == NULL))
4949 rootFrag->setConfReceived(tcPtrI);
4950 rootFrag->setRemainingSubScans(nodeMask);
4951 rootFrag->incrOutstandingResults(rowCount);
4954 ndbout <<
" resultStream {" << rootFrag->getResultStream(*
this)
4955 <<
"} fragNo" << rootFrag->getFragNo()
4960 if (rootFrag->isFragBatchComplete())
4963 ret = m_queryImpl.handleBatchComplete(*rootFrag);
4966 ndbout <<
"NdbQueryOperationImpl::execSCAN_TABCONF():, returns:" << ret
4967 <<
", tcPtrI=" << tcPtrI <<
" rowCount=" << rowCount
4968 <<
" *this=" << *
this << endl;
4982 if (m_parallelism != Parallelism_max)
4988 if(static_cast<const NdbQueryIndexScanOperationDefImpl&>
4989 (getQueryOperationDef())
5006 m_ordering = ordering;
5012 if (code.m_instructions_length == 0)
5027 if (unlikely((code.m_flags & NdbInterpretedCode::Finalised)
5036 if (likely(m_interpretedCode == NULL))
5040 if (unlikely(m_interpretedCode==NULL))
5051 const int error = m_interpretedCode->
copy(code);
5052 if (unlikely(error))
5061 if (!getQueryOperationDef().isScanOperation())
5066 else if (getOrdering() == NdbQueryOptions::ScanOrdering_ascending ||
5067 getOrdering() == NdbQueryOptions::ScanOrdering_descending)
5072 else if (getQueryOperationDef().getQueryOperationIx() > 0)
5077 else if (parallelism < 1 || parallelism > MAX_NDB_PARTITIONS)
5082 m_parallelism = parallelism;
5087 if (!getQueryOperationDef().isScanOperation())
5092 m_parallelism = Parallelism_max;
5097 if (!getQueryOperationDef().isScanOperation())
5102 else if (getQueryOperationDef().getQueryOperationIx() == 0)
5107 m_parallelism = Parallelism_adaptive;
5112 if (!getQueryOperationDef().isScanOperation())
5118 batchSize < getQueryOperationDef().getTable().getFragmentCount())
5125 m_maxBatchRows = batchSize;
5130 NdbQueryOperationImpl::hasInterpretedCode()
const
5132 return (m_interpretedCode && m_interpretedCode->m_instructions_length > 0) ||
5133 (getQueryOperationDef().getInterpretedCode() != NULL);
5137 NdbQueryOperationImpl::prepareInterpretedCode(Uint32Buffer& attrInfo)
const
5140 (m_interpretedCode && m_interpretedCode->m_instructions_length > 0)
5142 : getQueryOperationDef().getInterpretedCode();
5145 assert(interpretedCode->m_first_sub_instruction_pos==0);
5146 assert(interpretedCode->m_instructions_length > 0);
5147 assert(interpretedCode->m_instructions_length <= 0xffff);
5150 Uint32*
const buffer =
5151 attrInfo.alloc(1+interpretedCode->m_instructions_length);
5152 if(unlikely(buffer==NULL))
5154 return Err_MemoryAlloc;
5157 buffer[0] = interpretedCode->m_instructions_length;
5159 interpretedCode->m_buffer,
5160 interpretedCode->m_instructions_length *
sizeof(Uint32));
5166 NdbQueryOperationImpl::getIdOfReceiver()
const {
5174 if (m_rowSize == 0xffffffff)
5177 NdbReceiver::ndbrecord_rowsize(m_ndbRecord, m_firstRecAttr, 0,
false);
5184 out <<
"[ this: " << &op
5185 <<
" m_magic: " << op.m_magic;
5186 out <<
" op.operationDef.getQueryOperationIx()"
5187 << op.m_operationDef.getQueryOperationIx();
5188 if (op.getParentOperation()){
5189 out <<
" m_parent: " << op.getParentOperation();
5191 for(
unsigned int i = 0; i<op.getNoOfChildOperations(); i++){
5192 out <<
" m_children[" << i <<
"]: " << &op.getChildOperation(i);
5194 out <<
" m_queryImpl: " << &op.m_queryImpl;
5195 out <<
" m_operationDef: " << &op.m_operationDef;
5198 out <<
" m_resultStream[" << i <<
"]{" << rootFrag.
getResultStream(op) <<
"}";
5200 out <<
" m_isRowNull " << op.m_isRowNull;
5206 out <<
" received rows: " << stream.m_resultSets[stream.m_recv].getRowCount();