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
7c6b884e
Commit
7c6b884e
authored
20 years ago
by
mskold@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for NULL in unique index
parent
a454b977
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
180 additions
and
58 deletions
+180
-58
mysql-test/r/ndb_index_unique.result
mysql-test/r/ndb_index_unique.result
+50
-1
mysql-test/t/ndb_index_ordered.test
mysql-test/t/ndb_index_ordered.test
+20
-0
mysql-test/t/ndb_index_unique.test
mysql-test/t/ndb_index_unique.test
+60
-1
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+0
-10
ndb/src/kernel/blocks/dbtc/Dbtc.hpp
ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+1
-0
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+33
-32
ndb/src/kernel/blocks/trix/Trix.cpp
ndb/src/kernel/blocks/trix/Trix.cpp
+2
-2
ndb/src/ndbapi/NdbDictionaryImpl.cpp
ndb/src/ndbapi/NdbDictionaryImpl.cpp
+0
-7
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.cc
+14
-5
No files found.
mysql-test/r/ndb_index_unique.result
View file @
7c6b884e
...
...
@@ -21,6 +21,28 @@ insert into t1 values(7,8,3);
select * from t1 where b = 4 order by a;
a b c
3 4 6
insert into t1 values(8, 2, 3);
ERROR 23000: Can't write, because of unique constraint, to table 't1'
select * from t1 order by a;
a b c
1 2 3
2 3 5
3 4 6
4 5 8
5 6 2
6 7 2
7 8 3
delete from t1 where a = 1;
insert into t1 values(8, 2, 3);
select * from t1 order by a;
a b c
2 3 5
3 4 6
4 5 8
5 6 2
6 7 2
7 8 3
8 2 3
drop table t1;
CREATE TABLE t2 (
a int unsigned NOT NULL PRIMARY KEY,
...
...
@@ -42,6 +64,28 @@ insert into t2 values(7,8,3);
select * from t2 where b = 4 order by a;
a b c
3 4 6
insert into t2 values(8, 2, 3);
ERROR 23000: Can't write, because of unique constraint, to table 't2'
select * from t2 order by a;
a b c
1 2 3
2 3 5
3 4 6
4 5 8
5 6 2
6 7 2
7 8 3
delete from t2 where a = 1;
insert into t2 values(8, 2, 3);
select * from t2 order by a;
a b c
2 3 5
3 4 6
4 5 8
5 6 2
6 7 2
7 8 3
8 2 3
drop table t2;
CREATE TABLE t3 (
a int unsigned NOT NULL,
...
...
@@ -74,8 +118,10 @@ INSERT INTO t1 VALUES (8,'dummy');
CREATE TABLE t2 (
cid bigint(20) unsigned NOT NULL auto_increment,
cap varchar(255) NOT NULL default '',
PRIMARY KEY (cid)
PRIMARY KEY (cid),
UNIQUE KEY (cid, cap)
) engine=ndbcluster;
INSERT INTO t2 VALUES (NULL,'another dummy');
CREATE TABLE t3 (
gid bigint(20) unsigned NOT NULL auto_increment,
gn varchar(255) NOT NULL default '',
...
...
@@ -132,6 +178,9 @@ cid cv
8 dummy
select * from t1 where cv = 'test';
cid cv
select * from t2 where cap = 'another dummy';
cid cap
0 another dummy
select * from t4 where uid = 1 and gid=1 and rid=2 and cid=4;
uid gid rid cid
1 1 2 4
...
...
This diff is collapsed.
Click to expand it.
mysql-test/t/ndb_index_ordered.test
View file @
7c6b884e
...
...
@@ -114,3 +114,23 @@ select * from t1 where b=4 and c<=5 order by a;
select
*
from
t1
where
b
<=
4
and
c
<=
5
order
by
a
;
select
*
from
t1
where
b
<=
5
and
c
=
0
or
b
<=
5
and
c
=
2
;
drop
table
t1
;
#
# Indexing NULL values
#
#CREATE TABLE t1 (
# a int unsigned NOT NULL PRIMARY KEY,
# b int unsigned,
# c int unsigned,
# KEY bc(b,c)
#) engine = ndb;
#insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL);
#select * from t1 use index (bc);
#select count(*) from t1 use index (bc);
#select count(*) from t1 use index (PRIMARY) where b IS NULL;
#select count(*) from t1 use index (bc) where b IS NULL;
#select count(*) from t1 use index (bc) where b IS NULL and c = 2;
#select count(*) from t1 use index (bc) where b IS NOT NULL;
#drop table t1;
This diff is collapsed.
Click to expand it.
mysql-test/t/ndb_index_unique.test
View file @
7c6b884e
...
...
@@ -21,6 +21,13 @@ select * from t1 where b = 4 order by b;
insert
into
t1
values
(
7
,
8
,
3
);
select
*
from
t1
where
b
=
4
order
by
a
;
--
error
1169
insert
into
t1
values
(
8
,
2
,
3
);
select
*
from
t1
order
by
a
;
delete
from
t1
where
a
=
1
;
insert
into
t1
values
(
8
,
2
,
3
);
select
*
from
t1
order
by
a
;
drop
table
t1
;
...
...
@@ -42,6 +49,13 @@ select * from t2 where c = 6;
insert
into
t2
values
(
7
,
8
,
3
);
select
*
from
t2
where
b
=
4
order
by
a
;
--
error
1169
insert
into
t2
values
(
8
,
2
,
3
);
select
*
from
t2
order
by
a
;
delete
from
t2
where
a
=
1
;
insert
into
t2
values
(
8
,
2
,
3
);
select
*
from
t2
order
by
a
;
drop
table
t2
;
#
...
...
@@ -64,6 +78,48 @@ select * from t3 where b = 4 order by a;
drop
table
t3
;
#
# Indexes on NULL-able columns
#
#CREATE TABLE t1 (
# pk int NOT NULL PRIMARY KEY,
# a int unsigned,
# UNIQUE KEY (a)
#) engine=ndbcluster;
#insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4);
#select * from t1 order by pk;
#--error 1169
#insert into t1 values (5,0);
#select * from t1 order by pk;
#delete from t1 where a = 0;
#insert into t1 values (5,0);
#select * from t1 order by pk;
#CREATE TABLE t2 (
# pk int NOT NULL PRIMARY KEY,
# a int unsigned,
# b tinyint NOT NULL,
# c VARCHAR(10),
# UNIQUE KEY si(a, c)
#) engine=ndbcluster;
#insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc');
#select * from t2 order by pk;
#--error 1169
#insert into t2 values(2,3,19,'abc');
#select * from t2 order by pk;
#delete from t2 where c IS NOT NULL;
#insert into t2 values(2,3,19,'abc');
#select * from t2 order by pk;
#drop table t1, t2;
#
# More complex tables
#
...
...
@@ -78,8 +134,10 @@ INSERT INTO t1 VALUES (8,'dummy');
CREATE
TABLE
t2
(
cid
bigint
(
20
)
unsigned
NOT
NULL
auto_increment
,
cap
varchar
(
255
)
NOT
NULL
default
''
,
PRIMARY
KEY
(
cid
)
PRIMARY
KEY
(
cid
),
UNIQUE
KEY
(
cid
,
cap
)
)
engine
=
ndbcluster
;
INSERT
INTO
t2
VALUES
(
NULL
,
'another dummy'
);
CREATE
TABLE
t3
(
gid
bigint
(
20
)
unsigned
NOT
NULL
auto_increment
,
gn
varchar
(
255
)
NOT
NULL
default
''
,
...
...
@@ -134,6 +192,7 @@ INSERT INTO t7 VALUES(10, 5, 1, 1, 10);
select
*
from
t1
where
cv
=
'dummy'
;
select
*
from
t1
where
cv
=
'test'
;
select
*
from
t2
where
cap
=
'another dummy'
;
select
*
from
t4
where
uid
=
1
and
gid
=
1
and
rid
=
2
and
cid
=
4
;
select
*
from
t4
where
uid
=
1
and
gid
=
1
and
rid
=
1
and
cid
=
4
;
select
*
from
t4
where
uid
=
1
order
by
cid
;
...
...
This diff is collapsed.
Click to expand it.
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
View file @
7c6b884e
...
...
@@ -6255,16 +6255,6 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
jam
();
found
=
true
;
const
Uint32
a
=
aRec
->
attributeDescriptor
;
bool
isNullable
=
AttributeDescriptor
::
getNullable
(
a
);
// We do not allow more than one NULLable attribute for hash index
if
(
isNullable
&&
indexPtr
.
p
->
isHashIndex
()
&&
(
opPtr
.
p
->
m_attrList
.
sz
>
1
))
{
jam
();
opPtr
.
p
->
m_errorCode
=
CreateIndxRef
::
AttributeNullable
;
opPtr
.
p
->
m_errorLine
=
__LINE__
;
return
;
}
if
(
indexPtr
.
p
->
isHashIndex
())
{
const
Uint32
s1
=
AttributeDescriptor
::
getSize
(
a
);
const
Uint32
s2
=
AttributeDescriptor
::
getArraySize
(
a
);
...
...
This diff is collapsed.
Click to expand it.
ndb/src/kernel/blocks/dbtc/Dbtc.hpp
View file @
7c6b884e
...
...
@@ -139,6 +139,7 @@
#define ZNOT_FOUND 626
#define ZALREADYEXIST 630
#define ZINCONSISTENTHASHINDEX 892
#define ZNOTUNIQUE 893
#endif
class
Dbtc
:
public
SimulatedBlock
{
...
...
This diff is collapsed.
Click to expand it.
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
View file @
7c6b884e
...
...
@@ -4925,7 +4925,9 @@ void Dbtc::execLQHKEYREF(Signal* signal)
// The operation executed an index trigger
const
Uint32
opType
=
regTcPtr
->
operation
;
if
(
!
(
opType
==
ZDELETE
&&
errCode
==
ZNOT_FOUND
))
{
if
(
errCode
==
ZALREADYEXIST
)
errCode
=
terrorCode
=
ZNOTUNIQUE
;
else
if
(
!
(
opType
==
ZDELETE
&&
errCode
==
ZNOT_FOUND
))
{
jam
();
/**
* "Normal path"
...
...
@@ -12168,34 +12170,33 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
// Calculate key length and renumber attribute id:s
AttributeBuffer
::
DataBufferPool
&
pool
=
c_theAttributeBufferPool
;
LocalDataBuffer
<
11
>
afterValues
(
pool
,
firedTriggerData
->
afterValues
);
bool
skipNull
=
false
;
for
(
bool
moreKeyAttrs
=
afterValues
.
first
(
iter
);
moreKeyAttrs
;
attrId
++
)
{
jam
();
AttributeHeader
*
attrHeader
=
(
AttributeHeader
*
)
iter
.
data
;
// Filter out NULL valued attributes
if
(
attrHeader
->
isNULL
())
{
skipNull
=
true
;
break
;
}
attrHeader
->
setAttributeId
(
attrId
);
keyLength
+=
attrHeader
->
getDataSize
();
hops
=
attrHeader
->
getHeaderSize
()
+
attrHeader
->
getDataSize
();
moreKeyAttrs
=
afterValues
.
next
(
iter
,
hops
);
}
// Filter out single NULL attributes
if
(
attrId
==
1
)
{
if
(
skipNull
)
{
jam
();
afterValues
.
first
(
iter
);
AttributeHeader
*
attrHeader
=
(
AttributeHeader
*
)
iter
.
data
;
if
(
attrHeader
->
isNULL
()
&&
!
afterValues
.
next
(
iter
))
{
jam
();
opRecord
->
triggerExecutionCount
--
;
if
(
opRecord
->
triggerExecutionCount
==
0
)
{
/*
We have completed current trigger execution
Continue triggering operation
*/
jam
();
continueTriggeringOp
(
signal
,
opRecord
);
}
//if
return
;
opRecord
->
triggerExecutionCount
--
;
if
(
opRecord
->
triggerExecutionCount
==
0
)
{
/*
We have completed current trigger execution
Continue triggering operation
*/
jam
();
continueTriggeringOp
(
signal
,
opRecord
);
}
//if
return
;
}
//if
// Calculate total length of primary key to be stored in index table
...
...
@@ -12523,36 +12524,36 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
// Calculate key length and renumber attribute id:s
AttributeBuffer
::
DataBufferPool
&
pool
=
c_theAttributeBufferPool
;
LocalDataBuffer
<
11
>
beforeValues
(
pool
,
firedTriggerData
->
beforeValues
);
bool
skipNull
=
false
;
for
(
bool
moreKeyAttrs
=
beforeValues
.
first
(
iter
);
(
moreKeyAttrs
);
attrId
++
)
{
jam
();
AttributeHeader
*
attrHeader
=
(
AttributeHeader
*
)
iter
.
data
;
// Filter out NULL valued attributes
if
(
attrHeader
->
isNULL
())
{
skipNull
=
true
;
break
;
}
attrHeader
->
setAttributeId
(
attrId
);
keyLength
+=
attrHeader
->
getDataSize
();
hops
=
attrHeader
->
getHeaderSize
()
+
attrHeader
->
getDataSize
();
moreKeyAttrs
=
beforeValues
.
next
(
iter
,
hops
);
}
// Filter out single NULL attributes
if
(
attrId
==
1
)
{
if
(
skipNull
)
{
jam
();
beforeValues
.
first
(
iter
);
AttributeHeader
*
attrHeader
=
(
AttributeHeader
*
)
iter
.
data
;
if
(
attrHeader
->
isNULL
()
&&
!
beforeValues
.
next
(
iter
))
{
jam
();
opRecord
->
triggerExecutionCount
--
;
if
(
opRecord
->
triggerExecutionCount
==
0
)
{
/*
opRecord
->
triggerExecutionCount
--
;
if
(
opRecord
->
triggerExecutionCount
==
0
)
{
/*
We have completed current trigger execution
Continue triggering operation
*/
jam
();
continueTriggeringOp
(
signal
,
opRecord
);
}
//if
return
;
*/
jam
();
continueTriggeringOp
(
signal
,
opRecord
);
}
//if
return
;
}
//if
TcKeyReq
::
setKeyLength
(
tcKeyRequestInfo
,
keyLength
);
...
...
This diff is collapsed.
Click to expand it.
ndb/src/kernel/blocks/trix/Trix.cpp
View file @
7c6b884e
...
...
@@ -814,8 +814,8 @@ void Trix::executeInsertTransaction(Signal* signal,
for
(
Uint32
i
=
0
;
i
<
headerPtr
.
sz
;
i
++
)
{
AttributeHeader
*
keyAttrHead
=
(
AttributeHeader
*
)
headerBuffer
+
i
;
// Filter out
single
NULL attributes
if
(
keyAttrHead
->
isNULL
()
&&
(
i
==
(
Uint32
)
0
)
&&
(
headerPtr
.
sz
==
(
Uint32
)
2
)
)
// Filter out NULL attributes
if
(
keyAttrHead
->
isNULL
())
return
;
if
(
i
<
subRec
->
noOfIndexColumns
)
...
...
This diff is collapsed.
Click to expand it.
ndb/src/ndbapi/NdbDictionaryImpl.cpp
View file @
7c6b884e
...
...
@@ -1851,13 +1851,6 @@ NdbDictInterface::createIndex(Ndb & ndb,
m_error
.
code
=
4245
;
return
-
1
;
}
if
(
it
==
DictTabInfo
::
UniqueHashIndex
&&
(
col
->
m_nullable
)
&&
(
attributeList
.
sz
>
1
))
{
// We only support one NULL attribute
m_error
.
code
=
4246
;
return
-
1
;
}
attributeList
.
id
[
i
]
=
col
->
m_attrId
;
}
if
(
it
==
DictTabInfo
::
UniqueHashIndex
)
{
...
...
This diff is collapsed.
Click to expand it.
sql/ha_ndbcluster.cc
View file @
7c6b884e
...
...
@@ -1040,11 +1040,11 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
bounds
[
bound
],
field
->
field_name
));
DBUG_DUMP
(
"key"
,
(
char
*
)
key_ptr
,
field_len
);
if
(
op
->
setBound
(
field
->
field_name
,
bound
,
key_ptr
,
field_len
)
!=
0
)
field
->
is_null
()
?
0
:
key_ptr
,
field
->
is_null
()
?
0
:
field
_len
)
!=
0
)
ERR_RETURN
(
op
->
getNdbError
());
key_ptr
+=
field_len
;
...
...
@@ -1293,8 +1293,6 @@ int ha_ndbcluster::write_row(byte *record)
update_timestamp
(
record
+
table
->
timestamp_default_now
-
1
);
has_auto_increment
=
(
table
->
next_number_field
&&
record
==
table
->
record
[
0
]);
skip_auto_increment
=
table
->
auto_increment_field_not_null
;
if
((
has_auto_increment
)
&&
(
!
skip_auto_increment
))
update_auto_increment
();
if
(
!
(
op
=
trans
->
getNdbOperation
(
m_tabname
)))
ERR_RETURN
(
trans
->
getNdbError
());
...
...
@@ -1313,6 +1311,10 @@ int ha_ndbcluster::write_row(byte *record)
else
{
int
res
;
if
((
has_auto_increment
)
&&
(
!
skip_auto_increment
))
update_auto_increment
();
if
((
res
=
set_primary_key
(
op
)))
return
res
;
}
...
...
@@ -1323,7 +1325,10 @@ int ha_ndbcluster::write_row(byte *record)
Field
*
field
=
table
->
field
[
i
];
if
(
!
(
field
->
flags
&
PRI_KEY_FLAG
)
&&
set_ndb_value
(
op
,
field
,
i
))
{
skip_auto_increment
=
true
;
ERR_RETURN
(
op
->
getNdbError
());
}
}
/*
...
...
@@ -1345,7 +1350,10 @@ int ha_ndbcluster::write_row(byte *record)
(
int
)
rows_inserted
,
(
int
)
bulk_insert_rows
));
bulk_insert_not_flushed
=
false
;
if
(
trans
->
execute
(
NoCommit
)
!=
0
)
{
skip_auto_increment
=
true
;
DBUG_RETURN
(
ndb_err
(
trans
));
}
}
if
((
has_auto_increment
)
&&
(
skip_auto_increment
))
{
...
...
@@ -3068,6 +3076,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
m_ndb
(
NULL
),
m_table
(
NULL
),
m_table_flags
(
HA_REC_NOT_IN_SEQ
|
//HA_NULL_IN_KEY |
HA_NOT_EXACT_COUNT
|
HA_NO_PREFIX_CHAR_KEYS
),
m_use_write
(
false
),
...
...
This diff is collapsed.
Click to expand it.
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