Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
f34debd9
Commit
f34debd9
authored
Jul 27, 2004
by
pekka@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wl-1884 storing NULL in ordered index
parent
43efb3cc
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
150 additions
and
117 deletions
+150
-117
ndb/include/ndbapi/NdbIndexScanOperation.hpp
ndb/include/ndbapi/NdbIndexScanOperation.hpp
+13
-14
ndb/src/kernel/blocks/dbtux/Dbtux.hpp
ndb/src/kernel/blocks/dbtux/Dbtux.hpp
+5
-1
ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp
ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp
+66
-56
ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
+2
-2
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
+2
-0
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
+1
-1
ndb/src/kernel/blocks/dbtux/Times.txt
ndb/src/kernel/blocks/dbtux/Times.txt
+14
-6
ndb/src/ndbapi/NdbScanOperation.cpp
ndb/src/ndbapi/NdbScanOperation.cpp
+13
-12
ndb/test/ndbapi/testOIBasic.cpp
ndb/test/ndbapi/testOIBasic.cpp
+34
-25
No files found.
ndb/include/ndbapi/NdbIndexScanOperation.hpp
View file @
f34debd9
...
...
@@ -86,26 +86,25 @@ public:
/**
* Define bound on index key in range scan.
*
* Each index key can have
not null lower and/or upper bound, or can
*
be set equal to not null value. The bounds can be defined in any
*
order but
a duplicate definition is an error.
* Each index key can have
lower and/or upper bound, or can be set
*
equal to a value. The bounds can be defined in any order but
* a duplicate definition is an error.
*
* The scan is most effective when bounds are given for an initial
* sequence of non-nullable index keys, and all but the last one is an
* equality. In this case the scan returns a contiguous range from
* each ordered index fragment.
* The bounds must specify a single range i.e. they are on an initial
* sequence of index keys and the condition is equality for all but
* (at most) the last key which has a lower and/or upper bound.
*
*
@note This release implements only the case described above,
*
except for the non-nullable limitation. Other sets of
*
bounds return error or empty result set
.
*
NULL is treated like a normal value which is less than any not-NULL
*
value and equal to another NULL value. To search for NULL use
*
setBound with null pointer (0)
.
*
*
@note In this release a null key value satisfies any lower
*
bound and no upper bound. This may change
.
*
An index stores also all-NULL keys (this may become optional).
*
Doing index scan with empty bound set returns all table tuples
.
*
* @param attrName Attribute name, alternatively:
* @param anAttrId Index column id (starting from 0)
.
* @param anAttrId Index column id (starting from 0)
* @param type Type of bound
* @param value Pointer to bound value
* @param value Pointer to bound value
, 0 for NULL
* @param len Value length in bytes.
* Fixed per datatype and can be omitted
* @return 0 if successful otherwise -1
...
...
ndb/src/kernel/blocks/dbtux/Dbtux.hpp
View file @
f34debd9
...
...
@@ -446,6 +446,7 @@ private:
Uint32
m_descPage
;
// descriptor page
Uint16
m_descOff
;
// offset within the page
Uint16
m_numAttrs
;
bool
m_storeNullKey
;
union
{
Uint32
nextPool
;
};
...
...
@@ -469,6 +470,7 @@ private:
Uint32
m_descPage
;
// copy from index level
Uint16
m_descOff
;
Uint16
m_numAttrs
;
bool
m_storeNullKey
;
TreeHead
m_tree
;
TupLoc
m_freeLoc
;
// one node pre-allocated for insert
DLList
<
ScanOp
>
m_scanList
;
// current scans on this fragment
...
...
@@ -993,7 +995,8 @@ Dbtux::Index::Index() :
m_numFrags
(
0
),
m_descPage
(
RNIL
),
m_descOff
(
0
),
m_numAttrs
(
0
)
m_numAttrs
(
0
),
m_storeNullKey
(
false
)
{
for
(
unsigned
i
=
0
;
i
<
MaxIndexFragments
;
i
++
)
{
m_fragId
[
i
]
=
ZNIL
;
...
...
@@ -1012,6 +1015,7 @@ Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
m_descPage
(
RNIL
),
m_descOff
(
0
),
m_numAttrs
(
ZNIL
),
m_storeNullKey
(
false
),
m_tree
(),
m_freeLoc
(),
m_scanList
(
scanOpPool
),
...
...
ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp
View file @
f34debd9
...
...
@@ -62,15 +62,15 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, Cons
}
}
else
{
jam
();
// not NULL
<
NULL
ret
=
-
1
;
// not NULL
>
NULL
ret
=
+
1
;
break
;
}
}
else
{
if
(
!
entryData
.
ah
().
isNULL
())
{
jam
();
// NULL
>
not NULL
ret
=
+
1
;
// NULL
<
not NULL
ret
=
-
1
;
break
;
}
}
...
...
@@ -116,15 +116,15 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, Tabl
}
}
else
{
jam
();
// not NULL
<
NULL
ret
=
-
1
;
// not NULL
>
NULL
ret
=
+
1
;
break
;
}
}
else
{
if
(
*
entryKey
!=
0
)
{
jam
();
// NULL
>
not NULL
ret
=
+
1
;
// NULL
<
not NULL
ret
=
-
1
;
break
;
}
}
...
...
@@ -180,7 +180,7 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne
// get and skip bound type
type
=
boundInfo
[
0
];
boundInfo
+=
1
;
ndbrequire
(
!
boundInfo
.
ah
().
isNULL
());
if
(
!
boundInfo
.
ah
().
isNULL
())
{
if
(
!
entryData
.
ah
().
isNULL
())
{
jam
();
// current attribute
...
...
@@ -205,12 +205,17 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne
}
}
else
{
jam
();
/*
* NULL is bigger than any bound, thus the boundary is always to
* the left of NULL.
*/
// not NULL > NULL
return
+
1
;
}
}
else
{
jam
();
if
(
!
entryData
.
ah
().
isNULL
())
{
jam
();
// NULL < not NULL
return
-
1
;
}
}
boundInfo
+=
AttributeHeaderSize
+
boundInfo
.
ah
().
getDataSize
();
entryData
+=
AttributeHeaderSize
+
entryData
.
ah
().
getDataSize
();
boundCount
-=
1
;
...
...
@@ -258,7 +263,7 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne
// get and skip bound type
type
=
boundInfo
[
0
];
boundInfo
+=
1
;
ndbrequire
(
!
boundInfo
.
ah
().
isNULL
());
if
(
!
boundInfo
.
ah
().
isNULL
())
{
if
(
*
entryKey
!=
0
)
{
jam
();
// current attribute
...
...
@@ -279,12 +284,17 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne
}
}
else
{
jam
();
/*
* NULL is bigger than any bound, thus the boundary is always to
* the left of NULL.
*/
// not NULL > NULL
return
+
1
;
}
}
else
{
jam
();
if
(
*
entryKey
!=
0
)
{
jam
();
// NULL < not NULL
return
-
1
;
}
}
boundInfo
+=
AttributeHeaderSize
+
boundInfo
.
ah
().
getDataSize
();
entryKey
+=
1
;
boundCount
-=
1
;
...
...
ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
View file @
f34debd9
...
...
@@ -82,8 +82,8 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
ent
.
m_fragBit
=
fragBit
;
// read search key
readKeyAttrs
(
frag
,
ent
,
0
,
c_searchKey
);
if
(
!
frag
.
m_storeNullKey
)
{
// check if all keys are null
{
const
unsigned
numAttrs
=
frag
.
m_numAttrs
;
bool
allNull
=
true
;
for
(
unsigned
i
=
0
;
i
<
numAttrs
;
i
++
)
{
...
...
ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
View file @
f34debd9
...
...
@@ -85,6 +85,7 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
fragPtr
.
p
->
m_fragOff
=
req
->
fragOff
;
fragPtr
.
p
->
m_fragId
=
req
->
fragId
;
fragPtr
.
p
->
m_numAttrs
=
req
->
noOfAttr
;
fragPtr
.
p
->
m_storeNullKey
=
true
;
// not yet configurable
fragPtr
.
p
->
m_tupIndexFragPtrI
=
req
->
tupIndexFragPtrI
;
fragPtr
.
p
->
m_tupTableFragPtrI
[
0
]
=
req
->
tupTableFragPtrI
[
0
];
fragPtr
.
p
->
m_tupTableFragPtrI
[
1
]
=
req
->
tupTableFragPtrI
[
1
];
...
...
@@ -111,6 +112,7 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
indexPtr
.
p
->
m_tableId
=
req
->
primaryTableId
;
indexPtr
.
p
->
m_fragOff
=
req
->
fragOff
;
indexPtr
.
p
->
m_numAttrs
=
req
->
noOfAttr
;
indexPtr
.
p
->
m_storeNullKey
=
true
;
// not yet configurable
// allocate attribute descriptors
if
(
!
allocDescEnt
(
indexPtr
))
{
jam
();
...
...
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
View file @
f34debd9
...
...
@@ -137,7 +137,7 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal)
const
Uint32
*
const
data
=
(
Uint32
*
)
sig
+
TuxBoundInfo
::
SignalLength
;
unsigned
offset
=
5
;
// walk through entries
while
(
offset
+
2
<
req
->
boundAiLength
)
{
while
(
offset
+
2
<
=
req
->
boundAiLength
)
{
jam
();
const
unsigned
type
=
data
[
offset
];
if
(
type
>
4
)
{
...
...
ndb/src/kernel/blocks/dbtux/Times.txt
View file @
f34debd9
...
...
@@ -21,11 +21,11 @@ shows ms / 1000 rows for each and pct overhead
c
1 million rows, index on PK, full table scan, full index scan
shows ms / 1000 rows for each and index time
pct
shows ms / 1000 rows for each and index time
overhead
d
1 million rows, index on PK, read table via each pk, scan index for each pk
shows ms / 1000 rows for each and index time
pct
shows ms / 1000 rows for each and index time
overhead
samples 10% of all PKs (100,000 pk reads, 100,000 scans)
040616 mc02/a 40 ms 87 ms 114 pct
...
...
@@ -66,12 +66,20 @@ optim 11 mc02/a 43 ms 63 ms 46 pct
optim 12 mc02/a 38 ms 55 ms 43 pct
mc02/b 47 ms 77 ms 63 pct
mc02/c 10 ms 14 ms
1
47 pct
mc02/d 176 ms 281 ms
1
59 pct
mc02/c 10 ms 14 ms
47 pct
mc02/d 176 ms 281 ms
59 pct
optim 13 mc02/a 40 ms 57 ms 42 pct
mc02/b 47 ms 77 ms 61 pct
mc02/c 9 ms 13 ms 150 pct
mc02/d 170 ms 256 ms 150 pct
mc02/c 9 ms 13 ms 50 pct
mc02/d 170 ms 256 ms 50 pct
after wl-1884 store all-NULL keys (the tests have pctnull=10 per column)
[ what happened to PK read performance? ]
optim 13 mc02/a 39 ms 59 ms 50 pct
mc02/b 47 ms 77 ms 61 pct
mc02/c 9 ms 12 ms 44 pct
mc02/d 246 ms 289 ms 17 pct
vim: set et:
ndb/src/ndbapi/NdbScanOperation.cpp
View file @
f34debd9
...
...
@@ -1125,7 +1125,6 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
if
(
theOperationType
==
OpenRangeScanRequest
&&
theStatus
==
SetBound
&&
(
0
<=
type
&&
type
<=
4
)
&&
aValue
!=
NULL
&&
len
<=
8000
)
{
// bound type
...
...
@@ -1136,11 +1135,12 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
setErrorCodeAbort
(
4209
);
return
-
1
;
}
len
=
sizeInBytes
;
len
=
aValue
!=
NULL
?
sizeInBytes
:
0
;
Uint32
tIndexAttrId
=
tAttrInfo
->
m_attrId
;
Uint32
sizeInWords
=
(
len
+
3
)
/
4
;
AttributeHeader
ah
(
tIndexAttrId
,
sizeInWords
);
insertATTRINFO
(
ah
.
m_value
);
if
(
len
!=
0
)
{
// attribute data
if
((
UintPtr
(
aValue
)
&
0x3
)
==
0
&&
(
len
&
0x3
)
==
0
)
insertATTRINFOloop
((
const
Uint32
*
)
aValue
,
sizeInWords
);
...
...
@@ -1151,6 +1151,7 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
((
char
*
)
temp
)[
len
++
]
=
0
;
insertATTRINFOloop
(
temp
,
sizeInWords
);
}
}
/**
* Do sorted stuff
...
...
@@ -1236,7 +1237,7 @@ NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols,
Uint32
*
d2
=
(
Uint32
*
)
r2
->
aRef
();
unsigned
r1_null
=
r1
->
isNULL
();
if
((
r1_null
^
(
unsigned
)
r2
->
isNULL
())){
return
(
r1_null
?
1
:
-
1
);
return
(
r1_null
?
-
1
:
1
);
}
Uint32
type
=
NdbColumnImpl
::
getImpl
(
*
r1
->
m_column
).
m_extType
;
Uint32
size
=
(
r1
->
theAttrSize
*
r1
->
theArraySize
+
3
)
/
4
;
...
...
ndb/test/ndbapi/testOIBasic.cpp
View file @
f34debd9
...
...
@@ -85,7 +85,7 @@ printhelp()
<<
" -dups allow duplicate tuples from index scan ["
<<
d
.
m_dups
<<
"]"
<<
endl
<<
" -fragtype T fragment type single/small/medium/large"
<<
endl
<<
" -index xyz only given index numbers (digits 1-9)"
<<
endl
<<
" -loop N loop count full suite
forever=0
["
<<
d
.
m_loop
<<
"]"
<<
endl
<<
" -loop N loop count full suite
0=forever
["
<<
d
.
m_loop
<<
"]"
<<
endl
<<
" -nologging create tables in no-logging mode"
<<
endl
<<
" -rows N rows per thread ["
<<
d
.
m_rows
<<
"]"
<<
endl
<<
" -samples N samples for some timings (0=all) ["
<<
d
.
m_samples
<<
"]"
<<
endl
...
...
@@ -102,6 +102,12 @@ printhelp()
printtables
();
}
// not yet configurable
static
const
bool
g_store_null_key
=
true
;
// compare NULL like normal value (NULL < not NULL, NULL == NULL)
static
const
bool
g_compare_null
=
true
;
// log and error macros
static
NdbMutex
ndbout_mutex
=
NDB_MUTEX_INITIALIZER
;
...
...
@@ -306,8 +312,8 @@ Tmr::pct(const Tmr& t1)
const
char
*
Tmr
::
over
(
const
Tmr
&
t1
)
{
if
(
0
<
t1
.
m_ms
&&
t1
.
m_ms
<
m_ms
)
{
sprintf
(
m_text
,
"%
u
pct"
,
(
100
*
(
m_ms
-
t1
.
m_ms
))
/
t1
.
m_ms
);
if
(
0
<
t1
.
m_ms
)
{
sprintf
(
m_text
,
"%
d
pct"
,
(
100
*
(
m_ms
-
t1
.
m_ms
))
/
t1
.
m_ms
);
}
else
{
sprintf
(
m_text
,
"[cannot measure]"
);
}
...
...
@@ -1168,9 +1174,9 @@ Val::cmp(const Val& val2) const
assert
(
col
.
m_type
==
col2
.
m_type
&&
col
.
m_length
==
col2
.
m_length
);
if
(
m_null
||
val2
.
m_null
)
{
if
(
!
m_null
)
return
-
1
;
if
(
!
val2
.
m_null
)
return
+
1
;
if
(
!
val2
.
m_null
)
return
-
1
;
return
0
;
}
// verify data formats
...
...
@@ -1695,8 +1701,8 @@ int
BVal
::
setbnd
(
Par
par
)
const
{
Con
&
con
=
par
.
con
();
const
char
*
addr
=
(
const
char
*
)
dataaddr
(
);
assert
(
!
m_null
)
;
assert
(
g_compare_null
||
!
m_null
);
const
char
*
addr
=
!
m_null
?
(
const
char
*
)
dataaddr
()
:
0
;
const
ICol
&
icol
=
m_icol
;
CHK
(
con
.
setBound
(
icol
.
m_num
,
m_type
,
addr
)
==
0
);
return
0
;
...
...
@@ -1785,6 +1791,7 @@ BSet::calc(Par par)
if
(
k
+
1
<
itab
.
m_icols
)
bval
.
m_type
=
4
;
// value generation parammeters
if
(
!
g_compare_null
)
par
.
m_pctnull
=
0
;
par
.
m_pctrange
=
50
;
// bit higher
do
{
...
...
@@ -1842,6 +1849,7 @@ BSet::filter(const Set& set, Set& set2) const
if
(
!
set
.
exist
(
i
))
continue
;
const
Row
&
row
=
*
set
.
m_row
[
i
];
if
(
!
g_store_null_key
)
{
bool
ok1
=
false
;
for
(
unsigned
k
=
0
;
k
<
itab
.
m_icols
;
k
++
)
{
const
ICol
&
icol
=
itab
.
m_icol
[
k
];
...
...
@@ -1854,6 +1862,7 @@ BSet::filter(const Set& set, Set& set2) const
}
if
(
!
ok1
)
continue
;
}
bool
ok2
=
true
;
for
(
unsigned
j
=
0
;
j
<
m_bvals
;
j
++
)
{
const
BVal
&
bval
=
*
m_bval
[
j
];
...
...
@@ -2727,13 +2736,13 @@ tpkops(Par par)
RUNSTEP
(
par
,
pkinsert
,
MT
);
RUNSTEP
(
par
,
createindex
,
ST
);
RUNSTEP
(
par
,
invalidateindex
,
MT
);
RUNSTEP
(
par
,
readverify
,
M
T
);
RUNSTEP
(
par
,
readverify
,
S
T
);
for
(
unsigned
i
=
0
;
i
<
par
.
m_subloop
;
i
++
)
{
RUNSTEP
(
par
,
pkupdatescanread
,
MT
);
RUNSTEP
(
par
,
readverify
,
M
T
);
RUNSTEP
(
par
,
readverify
,
S
T
);
}
RUNSTEP
(
par
,
pkdelete
,
MT
);
RUNSTEP
(
par
,
readverify
,
M
T
);
RUNSTEP
(
par
,
readverify
,
S
T
);
return
0
;
}
...
...
@@ -2746,10 +2755,10 @@ tmixedops(Par par)
RUNSTEP
(
par
,
pkinsert
,
MT
);
RUNSTEP
(
par
,
createindex
,
ST
);
RUNSTEP
(
par
,
invalidateindex
,
MT
);
RUNSTEP
(
par
,
readverify
,
M
T
);
RUNSTEP
(
par
,
readverify
,
S
T
);
for
(
unsigned
i
=
0
;
i
<
par
.
m_subloop
;
i
++
)
{
RUNSTEP
(
par
,
mixedoperations
,
MT
);
RUNSTEP
(
par
,
readverify
,
M
T
);
RUNSTEP
(
par
,
readverify
,
S
T
);
}
return
0
;
}
...
...
@@ -2832,7 +2841,7 @@ ttimescan(Par par)
}
LL1
(
"full scan table - "
<<
t1
.
time
());
LL1
(
"full scan PK index - "
<<
t2
.
time
());
LL1
(
"
index time pct - "
<<
t2
.
pct
(
t1
));
LL1
(
"
overhead - "
<<
t2
.
over
(
t1
));
return
0
;
}
...
...
@@ -2854,7 +2863,7 @@ ttimepkread(Par par)
}
LL1
(
"pk read table - "
<<
t1
.
time
());
LL1
(
"pk read PK index - "
<<
t2
.
time
());
LL1
(
"
index time pct - "
<<
t2
.
pct
(
t1
));
LL1
(
"
overhead - "
<<
t2
.
over
(
t1
));
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment