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
6e91d6a8
Commit
6e91d6a8
authored
Oct 09, 2002
by
peter@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/pz/mysql/mysql-4.1-root
into mysql.com:/home/pz/mysql/mysql-4.1
parents
ba8c05da
40c0fd1c
Changes
24
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
601 additions
and
237 deletions
+601
-237
Docs/manual.texi
Docs/manual.texi
+200
-164
heap/hp_create.c
heap/hp_create.c
+5
-1
heap/hp_hash.c
heap/hp_hash.c
+48
-0
heap/hp_info.c
heap/hp_info.c
+2
-0
heap/hp_test1.c
heap/hp_test1.c
+5
-1
heap/hp_test2.c
heap/hp_test2.c
+5
-2
heap/hp_update.c
heap/hp_update.c
+8
-4
heap/hp_write.c
heap/hp_write.c
+2
-0
include/heap.h
include/heap.h
+14
-2
mysql-test/r/bdb.result
mysql-test/r/bdb.result
+8
-8
mysql-test/r/create.result
mysql-test/r/create.result
+1
-2
mysql-test/r/heap_auto_increment.result
mysql-test/r/heap_auto_increment.result
+41
-0
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+16
-2
mysql-test/t/create.test
mysql-test/t/create.test
+2
-2
mysql-test/t/heap_auto_increment.test
mysql-test/t/heap_auto_increment.test
+30
-0
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+21
-2
sql/ha_heap.cc
sql/ha_heap.cc
+32
-3
sql/ha_heap.h
sql/ha_heap.h
+3
-2
sql/item.cc
sql/item.cc
+31
-12
sql/item_subselect.cc
sql/item_subselect.cc
+38
-12
sql/item_subselect.h
sql/item_subselect.h
+9
-2
sql/mysql_priv.h
sql/mysql_priv.h
+6
-1
sql/sql_base.cc
sql/sql_base.cc
+72
-13
sql/sql_select.cc
sql/sql_select.cc
+2
-2
No files found.
Docs/manual.texi
View file @
6e91d6a8
This diff is collapsed.
Click to expand it.
heap/hp_create.c
View file @
6e91d6a8
...
...
@@ -21,7 +21,8 @@ static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
ulong
max_records
);
int
heap_create
(
const
char
*
name
,
uint
keys
,
HP_KEYDEF
*
keydef
,
uint
reclength
,
ulong
max_records
,
ulong
min_records
)
uint
reclength
,
ulong
max_records
,
ulong
min_records
,
HP_CREATE_INFO
*
create_info
)
{
uint
i
,
j
,
key_segs
,
max_length
,
length
;
HP_SHARE
*
share
;
...
...
@@ -120,6 +121,9 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
share
->
keys
=
keys
;
share
->
max_key_length
=
max_length
;
share
->
changed
=
0
;
share
->
auto_key
=
create_info
->
auto_key
;
share
->
auto_key_type
=
create_info
->
auto_key_type
;
share
->
auto_increment
=
create_info
->
auto_increment
;
if
(
!
(
share
->
name
=
my_strdup
(
name
,
MYF
(
0
))))
{
my_free
((
gptr
)
share
,
MYF
(
0
));
...
...
heap/hp_hash.c
View file @
6e91d6a8
...
...
@@ -537,3 +537,51 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
}
return
0
;
}
void
heap_update_auto_increment
(
HP_INFO
*
info
,
const
byte
*
record
)
{
ulonglong
value
;
HA_KEYSEG
*
keyseg
=
info
->
s
->
keydef
[
info
->
s
->
auto_key
-
1
].
seg
;
const
uchar
*
key
=
(
uchar
*
)
record
+
keyseg
->
start
;
switch
(
info
->
s
->
auto_key_type
)
{
case
HA_KEYTYPE_INT8
:
case
HA_KEYTYPE_BINARY
:
value
=
(
ulonglong
)
*
(
uchar
*
)
key
;
break
;
case
HA_KEYTYPE_SHORT_INT
:
case
HA_KEYTYPE_USHORT_INT
:
value
=
(
ulonglong
)
uint2korr
(
key
);
break
;
case
HA_KEYTYPE_LONG_INT
:
case
HA_KEYTYPE_ULONG_INT
:
value
=
(
ulonglong
)
uint4korr
(
key
);
break
;
case
HA_KEYTYPE_INT24
:
case
HA_KEYTYPE_UINT24
:
value
=
(
ulonglong
)
uint3korr
(
key
);
break
;
case
HA_KEYTYPE_FLOAT
:
/* This shouldn't be used */
{
float
f_1
;
float4get
(
f_1
,
key
);
value
=
(
ulonglong
)
f_1
;
break
;
}
case
HA_KEYTYPE_DOUBLE
:
/* This shouldn't be used */
{
double
f_1
;
float8get
(
f_1
,
key
);
value
=
(
ulonglong
)
f_1
;
break
;
}
case
HA_KEYTYPE_LONGLONG
:
case
HA_KEYTYPE_ULONGLONG
:
value
=
uint8korr
(
key
);
break
;
default:
value
=
0
;
/* Error */
break
;
}
set_if_bigger
(
info
->
s
->
auto_increment
,
value
);
}
heap/hp_info.c
View file @
6e91d6a8
...
...
@@ -55,5 +55,7 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x,
x
->
index_length
=
info
->
s
->
index_length
;
x
->
max_records
=
info
->
s
->
max_records
;
x
->
errkey
=
info
->
errkey
;
if
(
flag
&
HA_STATUS_AUTO
)
x
->
auto_increment
=
info
->
s
->
auto_increment
+
1
;
DBUG_RETURN
(
0
);
}
/* heap_info */
heap/hp_test1.c
View file @
6e91d6a8
...
...
@@ -37,11 +37,14 @@ int main(int argc, char **argv)
const
char
*
filename
;
HP_KEYDEF
keyinfo
[
10
];
HA_KEYSEG
keyseg
[
4
];
HP_CREATE_INFO
hp_create_info
;
MY_INIT
(
argv
[
0
]);
filename
=
"test1"
;
get_options
(
argc
,
argv
);
bzero
(
&
hp_create_info
,
sizeof
(
hp_create_info
));
keyinfo
[
0
].
keysegs
=
1
;
keyinfo
[
0
].
seg
=
keyseg
;
keyinfo
[
0
].
algorithm
=
HA_KEY_ALG_HASH
;
...
...
@@ -55,7 +58,8 @@ int main(int argc, char **argv)
bzero
((
gptr
)
flags
,
sizeof
(
flags
));
printf
(
"- Creating heap-file
\n
"
);
if
(
heap_create
(
filename
,
1
,
keyinfo
,
30
,(
ulong
)
flag
*
100000l
,
10l
)
||
if
(
heap_create
(
filename
,
1
,
keyinfo
,
30
,(
ulong
)
flag
*
100000l
,
10l
,
&
hp_create_info
)
||
!
(
file
=
heap_open
(
filename
,
2
)))
goto
err
;
printf
(
"- Writing records:s
\n
"
);
...
...
heap/hp_test2.c
View file @
6e91d6a8
...
...
@@ -63,6 +63,7 @@ int main(int argc, char *argv[])
HP_KEYDEF
keyinfo
[
MAX_KEYS
];
HA_KEYSEG
keyseg
[
MAX_KEYS
*
5
];
HEAP_PTR
position
;
HP_CREATE_INFO
hp_create_info
;
MY_INIT
(
argv
[
0
]);
/* init my_sys library & pthreads */
LINT_INIT
(
position
);
...
...
@@ -71,6 +72,8 @@ int main(int argc, char *argv[])
file
=
file2
=
0
;
get_options
(
argc
,
argv
);
bzero
(
&
hp_create_info
,
sizeof
(
hp_create_info
));
write_count
=
update
=
opt_delete
=
0
;
key_check
=
0
;
...
...
@@ -122,7 +125,7 @@ int main(int argc, char *argv[])
printf
(
"- Creating heap-file
\n
"
);
if
(
heap_create
(
filename
,
keys
,
keyinfo
,
reclength
,(
ulong
)
flag
*
100000L
,
(
ulong
)
recant
/
2
)
||
(
ulong
)
recant
/
2
,
&
hp_create_info
)
||
!
(
file
=
heap_open
(
filename
,
2
)))
goto
err
;
signal
(
SIGINT
,
endprog
);
...
...
@@ -557,7 +560,7 @@ int main(int argc, char *argv[])
heap_close
(
file2
);
printf
(
"- Creating output heap-file 2
\n
"
);
if
(
heap_create
(
filename2
,
1
,
keyinfo
,
reclength
,
0L
,
0L
)
||
if
(
heap_create
(
filename2
,
1
,
keyinfo
,
reclength
,
0L
,
0L
,
&
hp_create_info
)
||
!
(
file2
=
heap_open
(
filename2
,
2
)))
goto
err
;
...
...
heap/hp_update.c
View file @
6e91d6a8
...
...
@@ -22,7 +22,8 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
{
HP_KEYDEF
*
keydef
,
*
end
,
*
p_lastinx
;
byte
*
pos
;
HP_SHARE
*
share
=
info
->
s
;
bool
auto_key_changed
=
0
;
HP_SHARE
*
share
=
info
->
s
;
DBUG_ENTER
(
"heap_update"
);
test_active
(
info
);
...
...
@@ -33,20 +34,23 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
if
(
--
(
share
->
records
)
<
share
->
blength
>>
1
)
share
->
blength
>>=
1
;
share
->
changed
=
1
;
p_lastinx
=
share
->
keydef
+
info
->
lastinx
;
for
(
keydef
=
share
->
keydef
,
end
=
keydef
+
share
->
keys
;
keydef
<
end
;
keydef
++
)
p_lastinx
=
share
->
keydef
+
info
->
lastinx
;
for
(
keydef
=
share
->
keydef
,
end
=
keydef
+
share
->
keys
;
keydef
<
end
;
keydef
++
)
{
if
(
hp_rec_key_cmp
(
keydef
,
old
,
heap_new
))
{
if
((
*
keydef
->
delete_key
)(
info
,
keydef
,
old
,
pos
,
keydef
==
p_lastinx
)
||
(
*
keydef
->
write_key
)(
info
,
keydef
,
heap_new
,
pos
))
goto
err
;
if
(
share
->
auto_key
==
(
uint
)
(
keydef
-
share
->
keydef
+
1
))
auto_key_changed
=
1
;
}
}
memcpy
(
pos
,
heap_new
,(
size_t
)
share
->
reclength
);
if
(
++
(
share
->
records
)
==
share
->
blength
)
share
->
blength
+=
share
->
blength
;
if
(
auto_key_changed
)
heap_update_auto_increment
(
info
,
heap_new
);
DBUG_RETURN
(
0
);
err:
...
...
heap/hp_write.c
View file @
6e91d6a8
...
...
@@ -61,6 +61,8 @@ int heap_write(HP_INFO *info, const byte *record)
info
->
current_ptr
=
pos
;
info
->
current_hash_ptr
=
0
;
info
->
update
|=
HA_STATE_AKTIV
;
if
(
share
->
auto_key
)
heap_update_auto_increment
(
info
,
record
);
DBUG_RETURN
(
0
);
err:
DBUG_PRINT
(
"info"
,(
"Duplicate key: %d"
,
keydef
-
share
->
keydef
));
...
...
include/heap.h
View file @
6e91d6a8
...
...
@@ -50,6 +50,7 @@ typedef struct st_heapinfo /* Struct from heap_info */
ulong
index_length
;
uint
reclength
;
/* Length of one record */
int
errkey
;
ulonglong
auto_increment
;
}
HEAPINFO
;
...
...
@@ -115,6 +116,9 @@ typedef struct st_heap_share
#endif
my_bool
delete_on_close
;
LIST
open_list
;
uint
auto_key
;
uint
auto_key_type
;
/* real type of the auto key segment */
ulonglong
auto_increment
;
}
HP_SHARE
;
struct
st_hp_hash_info
;
...
...
@@ -140,6 +144,13 @@ typedef struct st_heap_info
LIST
open_list
;
}
HP_INFO
;
typedef
struct
st_heap_create_info
{
uint
auto_key
;
uint
auto_key_type
;
ulonglong
auto_increment
;
}
HP_CREATE_INFO
;
/* Prototypes for heap-functions */
extern
HP_INFO
*
heap_open
(
const
char
*
name
,
int
mode
);
...
...
@@ -152,7 +163,8 @@ extern int heap_scan(register HP_INFO *info, byte *record);
extern
int
heap_delete
(
HP_INFO
*
info
,
const
byte
*
buff
);
extern
int
heap_info
(
HP_INFO
*
info
,
HEAPINFO
*
x
,
int
flag
);
extern
int
heap_create
(
const
char
*
name
,
uint
keys
,
HP_KEYDEF
*
keydef
,
uint
reclength
,
ulong
max_records
,
ulong
min_records
);
uint
reclength
,
ulong
max_records
,
ulong
min_records
,
HP_CREATE_INFO
*
create_info
);
extern
int
heap_delete_table
(
const
char
*
name
);
extern
int
heap_extra
(
HP_INFO
*
info
,
enum
ha_extra_function
function
);
extern
int
heap_rename
(
const
char
*
old_name
,
const
char
*
new_name
);
...
...
@@ -163,7 +175,7 @@ extern int heap_rprev(HP_INFO *info,byte *record);
extern
int
heap_rfirst
(
HP_INFO
*
info
,
byte
*
record
,
int
inx
);
extern
int
heap_rlast
(
HP_INFO
*
info
,
byte
*
record
,
int
inx
);
extern
void
heap_clear
(
HP_INFO
*
info
);
extern
void
heap_update_auto_increment
(
HP_INFO
*
info
,
const
byte
*
record
);
ha_rows
hp_rb_records_in_range
(
HP_INFO
*
info
,
int
inx
,
const
byte
*
start_key
,
uint
start_key_len
,
enum
ha_rkey_function
start_search_flag
,
...
...
mysql-test/r/bdb.result
View file @
6e91d6a8
...
...
@@ -139,14 +139,14 @@ id parent_id level
1015 102 2
1010 102 2
explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used; Using index
id select_type
table type possible_keys key key_len ref rows Extra
1 SIMPLE
t1 ref level level 1 const 1 where used; Using index
explain select level,id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used; Using index
id select_type
table type possible_keys key key_len ref rows Extra
1 SIMPLE
t1 ref level level 1 const 1 where used; Using index
explain select level,id,parent_id from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used
id select_type
table type possible_keys key key_len ref rows Extra
1 SIMPLE
t1 ref level level 1 const 1 where used
select level,id from t1 where level=1;
level id
1 1002
...
...
@@ -624,8 +624,8 @@ id parent_id level
1025 102 2
1016 102 2
explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 where used; Using index
id select_type
table type possible_keys key key_len ref rows Extra
1 SIMPLE
t1 ref level level 1 const 1 where used; Using index
select level,id from t1 where level=1;
level id
1 1004
...
...
mysql-test/r/create.result
View file @
6e91d6a8
...
...
@@ -22,14 +22,13 @@ drop table if exists t1,t2;
create table t1 (b char(0) not null, index(b));
The used table handler can't index column 'b'
create table t1 (a int not null auto_increment,primary key (a)) type=heap;
The used table type doesn't support AUTO_INCREMENT columns
create table t1 (a int not null,b text) type=heap;
The used table type doesn't support BLOB/TEXT columns
create table t1 (a int ,primary key(a)) type=heap;
All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
drop table if exists t1;
create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=heap;
The used table type doesn't support AUTO_INCREMENT columns
Incorrect table definition; There can only be one auto column and it must be defined as a key
create table t1 (ordid int(8), primary key (ordid));
All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead
create table not_existing_database.test (a int);
...
...
mysql-test/r/heap_auto_increment.result
0 → 100644
View file @
6e91d6a8
drop table if exists t1;
create table t1 (a int not null auto_increment,b int, primary key (a)) type=heap auto_increment=3;
insert into t1 values (1,1),(NULL,3),(NULL,4);
delete from t1 where a=4;
insert into t1 values (NULL,5),(NULL,6);
select * from t1;
a b
1 1
3 3
5 5
6 6
delete from t1 where a=6;
replace t1 values (3,1);
ALTER TABLE t1 add c int;
replace t1 values (3,3,3);
insert into t1 values (NULL,7,7);
update t1 set a=8,b=b+1,c=c+1 where a=7;
insert into t1 values (NULL,9,9);
select * from t1;
a b c
1 1 NULL
3 3 3
5 5 NULL
8 8 8
9 9 9
drop table t1;
create table t1 (
skey tinyint unsigned NOT NULL auto_increment PRIMARY KEY,
sval char(20)
) type=heap;
insert into t1 values (NULL, "hello");
insert into t1 values (NULL, "hey");
select * from t1;
skey sval
1 hello
2 hey
select _rowid,t1._rowid,skey,sval from t1;
_rowid _rowid skey sval
1 1 1 hello
2 2 2 hey
drop table t1;
mysql-test/r/subselect.result
View file @
6e91d6a8
select (select 2);
(select 2)
2
drop table if exists t1,t2,t3,t4,t5,attend,clinic;
drop table if exists t1,t2,t3,t4,t5,attend,clinic
,inscrit
;
create table t1 (a int);
create table t2 (a int, b int);
create table t3 (a int);
...
...
@@ -131,6 +131,8 @@ patient_uq clinic_uq
1 1
1 2
2 2
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
Column: 'a' in field list is ambiguous
drop table if exists t1,t2,t3;
CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
...
...
@@ -147,4 +149,16 @@ W 1
SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
a b
W a
drop table t1,t2,t3,t4,t5,attend,clinic;
drop table if exists inscrit;
CREATE TABLE `inscrit` (
`pseudo` varchar(35) character set latin1 NOT NULL default '',
`email` varchar(60) character set latin1 NOT NULL default '',
PRIMARY KEY (`pseudo`),
UNIQUE KEY `email` (`email`)
) TYPE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
Subselect returns more than 1 record
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
mysql-test/t/create.test
View file @
6e91d6a8
...
...
@@ -22,12 +22,12 @@ drop table if exists t1;
!
$
1146
create
table
t2
select
auto
+
1
from
t1
;
drop
table
if
exists
t1
,
t2
;
!
$
1167
create
table
t1
(
b
char
(
0
)
not
null
,
index
(
b
));
!
$
1164
create
table
t1
(
a
int
not
null
auto_increment
,
primary
key
(
a
))
type
=
heap
;
create
table
t1
(
a
int
not
null
auto_increment
,
primary
key
(
a
))
type
=
heap
;
!
$
1163
create
table
t1
(
a
int
not
null
,
b
text
)
type
=
heap
;
!
$
1171
create
table
t1
(
a
int
,
primary
key
(
a
))
type
=
heap
;
drop
table
if
exists
t1
;
!
$
1
164
create
table
t1
(
ordid
int
(
8
)
not
null
auto_increment
,
ord
varchar
(
50
)
not
null
,
primary
key
(
ord
,
ordid
))
type
=
heap
;
!
$
1
075
create
table
t1
(
ordid
int
(
8
)
not
null
auto_increment
,
ord
varchar
(
50
)
not
null
,
primary
key
(
ord
,
ordid
))
type
=
heap
;
!
$
1171
create
table
t1
(
ordid
int
(
8
),
primary
key
(
ordid
));
--
error
1044
,
1
...
...
mysql-test/t/heap_auto_increment.test
0 → 100644
View file @
6e91d6a8
#
# Test of auto_increment; The test for BDB tables is in bdb.test
#
drop
table
if
exists
t1
;
create
table
t1
(
a
int
not
null
auto_increment
,
b
int
,
primary
key
(
a
))
type
=
heap
auto_increment
=
3
;
insert
into
t1
values
(
1
,
1
),(
NULL
,
3
),(
NULL
,
4
);
delete
from
t1
where
a
=
4
;
insert
into
t1
values
(
NULL
,
5
),(
NULL
,
6
);
select
*
from
t1
;
delete
from
t1
where
a
=
6
;
#show table status like "t1";
replace
t1
values
(
3
,
1
);
ALTER
TABLE
t1
add
c
int
;
replace
t1
values
(
3
,
3
,
3
);
insert
into
t1
values
(
NULL
,
7
,
7
);
update
t1
set
a
=
8
,
b
=
b
+
1
,
c
=
c
+
1
where
a
=
7
;
insert
into
t1
values
(
NULL
,
9
,
9
);
select
*
from
t1
;
drop
table
t1
;
create
table
t1
(
skey
tinyint
unsigned
NOT
NULL
auto_increment
PRIMARY
KEY
,
sval
char
(
20
)
)
type
=
heap
;
insert
into
t1
values
(
NULL
,
"hello"
);
insert
into
t1
values
(
NULL
,
"hey"
);
select
*
from
t1
;
select
_rowid
,
t1
.
_rowid
,
skey
,
sval
from
t1
;
drop
table
t1
;
mysql-test/t/subselect.test
View file @
6e91d6a8
select
(
select
2
);
drop
table
if
exists
t1
,
t2
,
t3
,
t4
,
t5
,
attend
,
clinic
;
drop
table
if
exists
t1
,
t2
,
t3
,
t4
,
t5
,
attend
,
clinic
,
inscrit
;
create
table
t1
(
a
int
);
create
table
t2
(
a
int
,
b
int
);
create
table
t3
(
a
int
);
...
...
@@ -53,6 +53,10 @@ insert into clinic values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta"
insert
into
attend
values
(
1
,
1
),(
1
,
2
),(
2
,
2
),(
1
,
3
);
select
*
from
attend
where
exists
(
select
*
from
clinic
where
uq
=
clinic_uq
);
# not unique fields
--
error
1052
select
*
from
t1
where
a
=
(
select
a
from
t2
,
t4
where
t2
.
b
=
t4
.
b
);
# different tipes & group functions
drop
table
if
exists
t1
,
t2
,
t3
;
...
...
@@ -66,4 +70,19 @@ SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
SELECT
*
FROM
t2
WHERE
b
=
(
SELECT
MIN
(
b
)
FROM
t2
);
SELECT
*
FROM
t3
WHERE
b
=
(
SELECT
MIN
(
b
)
FROM
t3
);
drop
table
t1
,
t2
,
t3
,
t4
,
t5
,
attend
,
clinic
;
drop
table
if
exists
inscrit
;
CREATE
TABLE
`inscrit`
(
`pseudo`
varchar
(
35
)
character
set
latin1
NOT
NULL
default
''
,
`email`
varchar
(
60
)
character
set
latin1
NOT
NULL
default
''
,
PRIMARY
KEY
(
`pseudo`
),
UNIQUE
KEY
`email`
(
`email`
)
)
TYPE
=
MyISAM
CHARSET
=
latin1
ROW_FORMAT
=
DYNAMIC
;
INSERT
INTO
inscrit
(
pseudo
,
email
)
VALUES
(
'joce'
,
'test'
);
INSERT
INTO
inscrit
(
pseudo
,
email
)
VALUES
(
'joce1'
,
'test1'
);
INSERT
INTO
inscrit
(
pseudo
,
email
)
VALUES
(
'2joce1'
,
'2test1'
);
--
error
1240
SELECT
pseudo
FROM
inscrit
WHERE
pseudo
=
(
SELECT
pseudo
FROM
inscrit
WHERE
pseudo
LIKE
'%joce%'
);
drop
table
if
exists
t1
,
t2
,
t3
,
t4
,
t5
,
attend
,
clinic
,
inscrit
;
\ No newline at end of file
sql/ha_heap.cc
View file @
6e91d6a8
...
...
@@ -35,7 +35,9 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
if
(
!
(
file
=
heap_open
(
name
,
mode
))
&&
my_errno
==
ENOENT
)
{
if
(
!
create
(
name
,
table
,
NULL
))
HA_CREATE_INFO
create_info
;
bzero
(
&
create_info
,
sizeof
(
create_info
));
if
(
!
create
(
name
,
table
,
&
create_info
))
file
=
heap_open
(
name
,
mode
);
}
return
(
file
?
0
:
1
);
...
...
@@ -51,6 +53,8 @@ int ha_heap::write_row(byte * buf)
statistic_increment
(
ha_write_count
,
&
LOCK_status
);
if
(
table
->
time_stamp
)
update_timestamp
(
buf
+
table
->
time_stamp
-
1
);
if
(
table
->
next_number_field
&&
buf
==
table
->
record
[
0
])
update_auto_increment
();
return
heap_write
(
file
,
buf
);
}
...
...
@@ -161,6 +165,8 @@ void ha_heap::info(uint flag)
index_file_length
=
info
.
index_length
;
max_data_file_length
=
info
.
max_records
*
info
.
reclength
;
delete_length
=
info
.
deleted
*
info
.
reclength
;
if
(
flag
&
HA_STATUS_AUTO
)
auto_increment_value
=
info
.
auto_increment
;
}
int
ha_heap
::
extra
(
enum
ha_extra_function
operation
)
...
...
@@ -234,11 +240,11 @@ ha_rows ha_heap::records_in_range(int inx,
}
}
int
ha_heap
::
create
(
const
char
*
name
,
TABLE
*
table
,
HA_CREATE_INFO
*
create_info
)
{
uint
key
,
parts
,
mem_per_row
=
0
;
uint
auto_key
=
0
,
auto_key_type
=
0
;
ulong
max_rows
;
HP_KEYDEF
*
keydef
;
HA_KEYSEG
*
seg
;
...
...
@@ -296,19 +302,42 @@ int ha_heap::create(const char *name, TABLE *table,
seg
->
null_bit
=
0
;
seg
->
null_pos
=
0
;
}
if
(
field
->
flags
&
AUTO_INCREMENT_FLAG
)
{
auto_key
=
key
+
1
;
auto_key_type
=
field
->
key_type
();
}
}
}
mem_per_row
+=
MY_ALIGN
(
table
->
reclength
+
1
,
sizeof
(
char
*
));
max_rows
=
(
ulong
)
(
current_thd
->
variables
.
max_heap_table_size
/
mem_per_row
);
HP_CREATE_INFO
hp_create_info
;
hp_create_info
.
auto_key
=
auto_key
;
hp_create_info
.
auto_key_type
=
auto_key_type
;
hp_create_info
.
auto_increment
=
(
create_info
->
auto_increment_value
?
create_info
->
auto_increment_value
-
1
:
0
);
error
=
heap_create
(
fn_format
(
buff
,
name
,
""
,
""
,
4
+
2
),
table
->
keys
,
keydef
,
table
->
reclength
,
((
table
->
max_rows
<
max_rows
&&
table
->
max_rows
)
?
table
->
max_rows
:
max_rows
),
table
->
min_rows
);
table
->
min_rows
,
&
hp_create_info
);
my_free
((
gptr
)
keydef
,
MYF
(
0
));
if
(
file
)
info
(
HA_STATUS_NO_LOCK
|
HA_STATUS_CONST
|
HA_STATUS_VARIABLE
);
ref_length
=
sizeof
(
HEAP_PTR
);
return
(
error
);
}
void
ha_heap
::
update_create_info
(
HA_CREATE_INFO
*
create_info
)
{
table
->
file
->
info
(
HA_STATUS_AUTO
);
if
(
!
(
create_info
->
used_fields
&
HA_CREATE_USED_AUTO
))
create_info
->
auto_increment_value
=
auto_increment_value
;
}
longlong
ha_heap
::
get_auto_increment
()
{
ha_heap
::
info
(
HA_STATUS_AUTO
);
return
auto_increment_value
;
}
sql/ha_heap.h
View file @
6e91d6a8
...
...
@@ -40,8 +40,7 @@ class ha_heap: public handler
ulong
table_flags
()
const
{
return
(
HA_READ_RND_SAME
|
HA_NO_INDEX
|
HA_KEYPOS_TO_RNDPOS
|
HA_NO_BLOBS
|
HA_NULL_KEY
|
HA_REC_NOT_IN_SEQ
|
HA_NO_AUTO_INCREMENT
);
HA_NO_BLOBS
|
HA_NULL_KEY
|
HA_REC_NOT_IN_SEQ
);
}
ulong
index_flags
(
uint
inx
)
const
{
...
...
@@ -63,6 +62,7 @@ class ha_heap: public handler
int
write_row
(
byte
*
buf
);
int
update_row
(
const
byte
*
old_data
,
byte
*
new_data
);
int
delete_row
(
const
byte
*
buf
);
longlong
get_auto_increment
();
int
index_read
(
byte
*
buf
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
);
int
index_read_idx
(
byte
*
buf
,
uint
idx
,
const
byte
*
key
,
...
...
@@ -87,6 +87,7 @@ class ha_heap: public handler
int
delete_table
(
const
char
*
from
);
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
int
create
(
const
char
*
name
,
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
);
void
update_create_info
(
HA_CREATE_INFO
*
create_info
);
THR_LOCK_DATA
**
store_lock
(
THD
*
thd
,
THR_LOCK_DATA
**
to
,
enum
thr_lock_type
lock_type
);
...
...
sql/item.cc
View file @
6e91d6a8
...
...
@@ -432,7 +432,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
if
(
!
field
)
// If field is not checked
{
Field
*
tmp
;
if
(
!
(
tmp
=
find_field_in_tables
(
thd
,
this
,
tables
,
0
))
)
if
(
(
tmp
=
find_field_in_tables
(
thd
,
this
,
tables
,
0
))
==
not_found_field
)
{
/*
We can't find table field in table list of current select,
...
...
@@ -445,14 +445,18 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
*/
SELECT_LEX
*
last
=
0
;
for
(
SELECT_LEX
*
sl
=
thd
->
lex
.
select
->
outer_select
();
sl
&&
!
tmp
;
sl
;
sl
=
sl
->
outer_select
())
tmp
=
find_field_in_tables
(
thd
,
this
,
(
TABLE_LIST
*
)(
last
=
sl
)
->
table_list
.
first
,
0
);
if
((
tmp
=
find_field_in_tables
(
thd
,
this
,
(
TABLE_LIST
*
)
(
last
=
sl
)
->
table_list
.
first
,
0
))
!=
not_found_field
)
break
;
if
(
!
tmp
)
return
-
1
;
else
if
(
tmp
==
not_found_field
)
{
//
Call to produce appropriate error messag
e
//
call to return error cod
e
find_field_in_tables
(
thd
,
this
,
tables
,
1
);
return
-
1
;
}
...
...
@@ -479,6 +483,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
}
}
}
else
if
(
!
tmp
)
return
-
1
;
set_field
(
tmp
);
}
else
if
(
thd
&&
thd
->
set_query_id
&&
field
->
query_id
!=
thd
->
query_id
)
...
...
@@ -786,7 +793,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
{
if
(
!
ref
)
{
if
(
!
(
ref
=
find_item_in_list
(
this
,
thd
->
lex
.
select
->
item_list
,
0
)))
if
((
ref
=
find_item_in_list
(
this
,
thd
->
lex
.
select
->
item_list
,
REPORT_EXCEPT_NOT_FOUND
))
==
(
Item
**
)
not_found_item
)
{
/*
We can't find table field in table list of current select,
...
...
@@ -795,17 +804,25 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
of view rules. For example if both tables (outer & current) have
field 'field' it is not mistake to refer to this field without
mention of table name, but if we join tables in one list it will
cause error ER_NON_UNIQ_ERROR in find_
field_in_tables
.
cause error ER_NON_UNIQ_ERROR in find_
item_in_list
.
*/
SELECT_LEX
*
last
=
0
;
for
(
SELECT_LEX
*
sl
=
thd
->
lex
.
select
->
outer_select
();
sl
&&
!
ref
;
sl
;
sl
=
sl
->
outer_select
())
ref
=
find_item_in_list
(
this
,
(
last
=
sl
)
->
item_list
,
0
);
if
((
ref
=
find_item_in_list
(
this
,
(
last
=
sl
)
->
item_list
,
REPORT_EXCEPT_NOT_FOUND
))
!=
(
Item
**
)
not_found_item
)
break
;
if
(
!
ref
)
{
return
1
;
}
else
if
(
ref
==
(
Item
**
)
not_found_item
)
{
// Call to report error
find_item_in_list
(
this
,
thd
->
lex
.
select
->
item_list
,
1
);
find_item_in_list
(
this
,
thd
->
lex
.
select
->
item_list
,
REPORT_ALL_ERRORS
);
return
1
;
}
else
...
...
@@ -831,6 +848,8 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
}
}
}
else
if
(
!
ref
)
return
1
;
max_length
=
(
*
ref
)
->
max_length
;
maybe_null
=
(
*
ref
)
->
maybe_null
;
decimals
=
(
*
ref
)
->
decimals
;
...
...
sql/item_subselect.cc
View file @
6e91d6a8
...
...
@@ -32,11 +32,22 @@ SUBSELECT TODO:
#include "mysql_priv.h"
#include "sql_select.h"
Item_subselect
::
Item_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
)
:
Item_subselect
::
Item_subselect
()
:
Item
(),
engine_owner
(
1
),
value_assigned
(
0
)
{
DBUG_ENTER
(
"Item_subselect::Item_subselect"
);
assign_null
();
/*
item value is NULL if select_subselect not changed this value
(i.e. some rows will be found returned)
*/
null_value
=
1
;
}
void
Item_subselect
::
init
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
)
{
DBUG_ENTER
(
"Item_subselect::init"
);
DBUG_PRINT
(
"subs"
,
(
"select_lex 0x%xl"
,
(
long
)
select_lex
));
if
(
select_lex
->
next_select
())
...
...
@@ -45,12 +56,6 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex,
else
engine
=
new
subselect_single_select_engine
(
thd
,
select_lex
,
result
,
this
);
assign_null
();
/*
item value is NULL if select_subselect not changed this value
(i.e. some rows will be found returned)
*/
null_value
=
1
;
DBUG_VOID_RETURN
;
}
...
...
@@ -83,6 +88,7 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return
1
;
}
int
res
=
engine
->
prepare
();
if
(
!
res
)
fix_length_and_dec
();
return
res
;
}
...
...
@@ -99,8 +105,9 @@ inline table_map Item_subselect::used_tables() const
Item_singleval_subselect
::
Item_singleval_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
)
:
Item_subselect
(
thd
,
select_lex
,
new
select_singleval_subselect
(
this
)
)
Item_subselect
()
{
init
(
thd
,
select_lex
,
new
select_singleval_subselect
(
this
));
max_columns
=
1
;
maybe_null
=
1
;
}
...
...
@@ -119,28 +126,38 @@ Item::Type Item_subselect::type() const
double
Item_singleval_subselect
::
val
()
{
if
(
engine
->
exec
())
{
assign_null
();
return
0
;
}
return
real_value
;
}
longlong
Item_singleval_subselect
::
val_int
()
{
if
(
engine
->
exec
())
{
assign_null
();
return
0
;
}
return
int_value
;
}
String
*
Item_singleval_subselect
::
val_str
(
String
*
str
)
{
if
(
engine
->
exec
()
||
null_value
)
{
assign_null
();
return
0
;
}
return
&
str_value
;
}
Item_exists_subselect
::
Item_exists_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
)
:
Item_subselect
(
thd
,
select_lex
,
new
select_exists_subselect
(
this
)
)
Item_subselect
()
{
init
(
thd
,
select_lex
,
new
select_exists_subselect
(
this
));
max_columns
=
UINT_MAX
;
null_value
=
0
;
//can't be NULL
maybe_null
=
0
;
//can't be NULL
...
...
@@ -157,21 +174,30 @@ void Item_exists_subselect::fix_length_and_dec()
double
Item_exists_subselect
::
val
()
{
if
(
engine
->
exec
())
{
assign_null
();
return
0
;
}
return
(
double
)
value
;
}
longlong
Item_exists_subselect
::
val_int
()
{
if
(
engine
->
exec
())
{
assign_null
();
return
0
;
}
return
value
;
}
String
*
Item_exists_subselect
::
val_str
(
String
*
str
)
{
if
(
engine
->
exec
())
{
assign_null
();
return
0
;
}
str
->
set
(
value
);
return
str
;
}
...
...
sql/item_subselect.h
View file @
6e91d6a8
...
...
@@ -39,8 +39,7 @@ class Item_subselect :public Item
uint
max_columns
;
public:
Item_subselect
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
);
Item_subselect
();
Item_subselect
(
Item_subselect
*
item
)
{
null_value
=
item
->
null_value
;
...
...
@@ -50,6 +49,14 @@ class Item_subselect :public Item
engine_owner
=
0
;
name
=
item
->
name
;
}
/*
We need this method, because some compilers do not allow 'this'
pointer in constructor initialization list, but we need pass pointer
to subselect Item class to select_subselect classes constructor.
*/
void
init
(
THD
*
thd
,
st_select_lex
*
select_lex
,
select_subselect
*
result
);
~
Item_subselect
();
virtual
void
assign_null
()
{
...
...
sql/mysql_priv.h
View file @
6e91d6a8
...
...
@@ -457,6 +457,7 @@ bool wait_for_tables(THD *thd);
bool
table_is_used
(
TABLE
*
table
,
bool
wait_for_name_lock
);
bool
drop_locked_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
void
abort_locked_tables
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
extern
const
Field
*
not_found_field
;
Field
*
find_field_in_tables
(
THD
*
thd
,
Item_field
*
item
,
TABLE_LIST
*
tables
,
bool
report_error
);
Field
*
find_field_in_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
uint
length
,
...
...
@@ -546,7 +547,11 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
SQL_SELECT
*
make_select
(
TABLE
*
head
,
table_map
const_tables
,
table_map
read_tables
,
COND
*
conds
,
int
*
error
);
Item
**
find_item_in_list
(
Item
*
item
,
List
<
Item
>
&
items
,
bool
report_error
);
enum
find_item_error_report_type
{
REPORT_ALL_ERRORS
,
REPORT_EXCEPT_NOT_FOUND
,
IGNORE_ERRORS
};
extern
const
Item
**
not_found_item
;
Item
**
find_item_in_list
(
Item
*
item
,
List
<
Item
>
&
items
,
find_item_error_report_type
report_error
);
bool
insert_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
const
char
*
db_name
,
const
char
*
table_name
,
List_iterator
<
Item
>
*
it
);
...
...
sql/sql_base.cc
View file @
6e91d6a8
...
...
@@ -1781,9 +1781,29 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
return
field
;
}
// Special Field pointer for find_field_in_tables returning
const
Field
*
not_found_field
=
(
Field
*
)
0x1
;
/*
Find field in table list.
SYNOPSIS
find_field_in_tables()
thd - pointer to current thread structure
item - field item that should be found
tables - tables for scaning
report_error - if FALSE then do not report error if item not found and
return not_found_field;
RETURN VALUES
0 - field is not found or field is not unique, error message is
reported
not_found_field - function was called with report_error == FALSE and
field if not found, no error message reported
found field
*/
Field
*
find_field_in_tables
(
THD
*
thd
,
Item_field
*
item
,
TABLE_LIST
*
tables
,
find_field_in_tables
(
THD
*
thd
,
Item_field
*
item
,
TABLE_LIST
*
tables
,
bool
report_error
)
{
Field
*
found
=
0
;
...
...
@@ -1829,13 +1849,18 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
strxnmov
(
buff
,
sizeof
(
buff
)
-
1
,
db
,
"."
,
table_name
,
NullS
);
table_name
=
buff
;
}
my_printf_error
(
ER_UNKNOWN_TABLE
,
ER
(
ER_UNKNOWN_TABLE
),
MYF
(
0
),
table_name
,
thd
->
where
);
if
(
report_error
)
my_printf_error
(
ER_UNKNOWN_TABLE
,
ER
(
ER_UNKNOWN_TABLE
),
MYF
(
0
),
table_name
,
thd
->
where
);
else
return
(
Field
*
)
not_found_field
;
}
else
if
(
report_error
)
my_printf_error
(
ER_BAD_FIELD_ERROR
,
ER
(
ER_BAD_FIELD_ERROR
),
MYF
(
0
),
item
->
full_name
(),
thd
->
where
);
else
return
(
Field
*
)
not_found_field
;
return
(
Field
*
)
0
;
}
bool
allow_rowid
=
tables
&&
!
tables
->
next
;
// Only one table
...
...
@@ -1850,9 +1875,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
return
(
Field
*
)
0
;
if
(
found
)
{
if
(
!
report_error
)
// Returns first found
if
(
!
thd
->
where
)
// Returns first found
break
;
if
(
report_error
)
my_printf_error
(
ER_NON_UNIQ_ERROR
,
ER
(
ER_NON_UNIQ_ERROR
),
MYF
(
0
),
name
,
thd
->
where
);
return
(
Field
*
)
0
;
...
...
@@ -1865,11 +1889,39 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables,
if
(
report_error
)
my_printf_error
(
ER_BAD_FIELD_ERROR
,
ER
(
ER_BAD_FIELD_ERROR
),
MYF
(
0
),
item
->
full_name
(),
thd
->
where
);
else
return
(
Field
*
)
not_found_field
;
return
(
Field
*
)
0
;
}
// Special Item pointer for find_item_in_list returning
const
Item
**
not_found_item
=
(
const
Item
**
)
0x1
;
/*
Find Item in list of items (find_field_in_tables analog)
SYNOPSIS
find_item_in_list()
find - item to find
items - list of items
report_error
REPORT_ALL_ERRORS - report errors, return 0 if error
REPORT_EXCEPT_NOT_FOUND - do not report 'not found' error and return not_ found_item, report other errors, return 0
IGNORE_ERRORS - do not report errors, return 0 if error
RETURN VALUES
0 - item is not found or item is not unique, error message is
reported
not_found_item - function was called with report_error ==
REPORT_EXCEPT_NOT_FOUND and item if not found, no error
message reported
found field
*/
Item
**
find_item_in_list
(
Item
*
find
,
List
<
Item
>
&
items
,
bool
report_error
)
find_item_in_list
(
Item
*
find
,
List
<
Item
>
&
items
,
find_item_error_report_type
report_error
)
{
List_iterator
<
Item
>
li
(
items
);
Item
**
found
=
0
,
*
item
;
...
...
@@ -1894,7 +1946,7 @@ find_item_in_list(Item *find, List<Item> &items, bool report_error)
{
if
((
*
found
)
->
eq
(
item
,
0
))
continue
;
// Same field twice (Access?)
if
(
report_error
)
if
(
report_error
!=
IGNORE_ERRORS
)
my_printf_error
(
ER_NON_UNIQ_ERROR
,
ER
(
ER_NON_UNIQ_ERROR
),
MYF
(
0
),
find
->
full_name
(),
current_thd
->
where
);
return
(
Item
**
)
0
;
...
...
@@ -1917,10 +1969,17 @@ find_item_in_list(Item *find, List<Item> &items, bool report_error)
break
;
}
}
if
(
!
found
&&
report_error
)
if
(
found
)
return
found
;
else
if
(
report_error
!=
REPORT_EXCEPT_NOT_FOUND
)
{
if
(
report_error
==
REPORT_ALL_ERRORS
)
my_printf_error
(
ER_BAD_FIELD_ERROR
,
ER
(
ER_BAD_FIELD_ERROR
),
MYF
(
0
),
find
->
full_name
(),
current_thd
->
where
);
return
found
;
return
(
Item
**
)
0
;
}
else
return
(
Item
**
)
not_found_item
;
}
/****************************************************************************
...
...
sql/sql_select.cc
View file @
6e91d6a8
...
...
@@ -6487,7 +6487,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
order
->
in_field_list
=
1
;
return
0
;
}
Item
**
item
=
find_item_in_list
(
*
order
->
item
,
fields
,
0
);
Item
**
item
=
find_item_in_list
(
*
order
->
item
,
fields
,
IGNORE_ERRORS
);
if
(
item
)
{
order
->
item
=
item
;
// use it
...
...
@@ -6587,7 +6587,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
thd
->
set_query_id
=
1
;
// Not really needed, but...
for
(;
new_field
;
new_field
=
new_field
->
next
)
{
if
((
item
=
find_item_in_list
(
*
new_field
->
item
,
fields
,
0
)))
if
((
item
=
find_item_in_list
(
*
new_field
->
item
,
fields
,
IGNORE_ERRORS
)))
new_field
->
item
=
item
;
/* Change to shared Item */
else
{
...
...
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