1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
* Search key vs node prefix or entry.
22
* The comparison starts at given attribute position. The position is
23
* updated by number of equal initial attributes found. The entry data
24
* may be partial in which case CmpUnknown may be returned.
26
* The attributes are normalized and have variable size given in words.
29
Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen)
31
const unsigned numAttrs = frag.m_numAttrs;
32
const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
33
// skip to right position in search key only
34
for (unsigned i = 0; i < start; i++) {
36
searchKey += AttributeHeaderSize + ah(searchKey).getDataSize();
38
// number of words of entry data left
39
unsigned len2 = maxlen;
41
while (start < numAttrs) {
42
if (len2 <= AttributeHeaderSize) {
44
ret = NdbSqlUtil::CmpUnknown;
47
len2 -= AttributeHeaderSize;
48
if (! ah(searchKey).isNULL()) {
49
if (! ah(entryData).isNULL()) {
51
// verify attribute id
52
const DescAttr& descAttr = descEnt.m_descAttr[start];
53
ndbrequire(ah(searchKey).getAttributeId() == descAttr.m_primaryAttrId);
54
ndbrequire(ah(entryData).getAttributeId() == descAttr.m_primaryAttrId);
56
const unsigned size1 = ah(searchKey).getDataSize();
57
const unsigned size2 = min(ah(entryData).getDataSize(), len2);
60
NdbSqlUtil::Cmp* const cmp = c_sqlCmp[start];
61
const Uint32* const p1 = &searchKey[AttributeHeaderSize];
62
const Uint32* const p2 = &entryData[AttributeHeaderSize];
63
const bool full = (maxlen == MaxAttrDataSize);
64
ret = (*cmp)(0, p1, size1 << 2, p2, size2 << 2, full);
76
if (! ah(entryData).isNULL()) {
83
searchKey += AttributeHeaderSize + ah(searchKey).getDataSize();
84
entryData += AttributeHeaderSize + ah(entryData).getDataSize();
91
* Scan bound vs node prefix or entry.
93
* Compare lower or upper bound and index entry data. The entry data
94
* may be partial in which case CmpUnknown may be returned. Otherwise
95
* returns -1 if the bound is to the left of the entry and +1 if the
96
* bound is to the right of the entry.
98
* The routine is similar to cmpSearchKey, but 0 is never returned.
99
* Suppose all attributes compare equal. Recall that all bounds except
100
* possibly the last one are non-strict. Use the given bound direction
101
* (0-lower 1-upper) and strictness of last bound to return -1 or +1.
103
* Following example illustrates this. We are at (a=2, b=3).
105
* idir bounds strict return
106
* 0 a >= 2 and b >= 3 no -1
107
* 0 a >= 2 and b > 3 yes +1
108
* 1 a <= 2 and b <= 3 no +1
109
* 1 a <= 2 and b < 3 yes -1
111
* The attributes are normalized and have variable size given in words.
114
Dbtux::cmpScanBound(const Frag& frag, unsigned idir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen)
116
const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
117
// direction 0-lower 1-upper
118
ndbrequire(idir <= 1);
119
// number of words of data left
120
unsigned len2 = maxlen;
121
// in case of no bounds, init last type to something non-strict
123
while (boundCount != 0) {
124
if (len2 <= AttributeHeaderSize) {
126
return NdbSqlUtil::CmpUnknown;
128
len2 -= AttributeHeaderSize;
129
// get and skip bound type (it is used after the loop)
132
if (! ah(boundInfo).isNULL()) {
133
if (! ah(entryData).isNULL()) {
135
// verify attribute id
136
const Uint32 index = ah(boundInfo).getAttributeId();
137
ndbrequire(index < frag.m_numAttrs);
138
const DescAttr& descAttr = descEnt.m_descAttr[index];
139
ndbrequire(ah(entryData).getAttributeId() == descAttr.m_primaryAttrId);
141
const unsigned size1 = ah(boundInfo).getDataSize();
142
const unsigned size2 = min(ah(entryData).getDataSize(), len2);
145
NdbSqlUtil::Cmp* const cmp = c_sqlCmp[index];
146
const Uint32* const p1 = &boundInfo[AttributeHeaderSize];
147
const Uint32* const p2 = &entryData[AttributeHeaderSize];
148
const bool full = (maxlen == MaxAttrDataSize);
149
int ret = (*cmp)(0, p1, size1 << 2, p2, size2 << 2, full);
161
if (! ah(entryData).isNULL()) {
167
boundInfo += AttributeHeaderSize + ah(boundInfo).getDataSize();
168
entryData += AttributeHeaderSize + ah(entryData).getDataSize();
171
// all attributes were equal
172
const int strict = (type & 0x1);
173
return (idir == 0 ? (strict == 0 ? -1 : +1) : (strict == 0 ? +1 : -1));