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
6e06100b
Commit
6e06100b
authored
Feb 11, 2005
by
igor@rurik.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Manual merge
parents
9d785cd5
cdb40830
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
261 additions
and
827 deletions
+261
-827
BitKeeper/triggers/post-commit
BitKeeper/triggers/post-commit
+0
-1
sql/table.cc
sql/table.cc
+261
-826
No files found.
BitKeeper/triggers/post-commit
View file @
6e06100b
...
...
@@ -62,7 +62,6 @@ From: $FROM
To:
$INTERNALS
Subject: bk commit into
$VERSION
tree (
$CHANGESET
)
$BS
$BH
Below is the list of changes that have just been committed into a local
$VERSION
repository of
$USER
. When
$USER
does a push these changes will
be propagated to the main repository and, within 24 hours after the
...
...
sql/table.cc
View file @
6e06100b
...
...
@@ -20,7 +20,7 @@
#include "mysql_priv.h"
#include <errno.h>
#include <m_ctype.h>
#include "md5.h"
/* Functions defined in this file */
...
...
@@ -61,8 +61,8 @@ static byte* get_field_name(Field **buff,uint *length,
5 Error (see frm_error: charset unavailable)
*/
int
openfrm
(
THD
*
thd
,
const
char
*
name
,
const
char
*
alias
,
uint
db_stat
,
uint
prgflag
,
uint
ha_open_flags
,
TABLE
*
outparam
)
int
openfrm
(
const
char
*
name
,
const
char
*
alias
,
uint
db_stat
,
uint
prgflag
,
uint
ha_open_flags
,
TABLE
*
outparam
)
{
reg1
uint
i
;
reg2
uchar
*
strpos
;
...
...
@@ -76,94 +76,76 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
my_string
record
;
const
char
**
int_array
;
bool
use_hash
,
null_field_first
;
bool
error_reported
=
FALSE
;
File
file
;
Field
**
field_ptr
,
*
reg_field
;
KEY
*
keyinfo
;
KEY_PART_INFO
*
key_part
;
uchar
*
null_pos
;
uint
null_bit
_pos
,
new_frm_ver
,
field_pack_length
;
uint
null_bit
,
new_frm_ver
,
field_pack_length
;
SQL_CRYPT
*
crypted
=
0
;
MEM_ROOT
**
root_ptr
,
*
old_root
;
TABLE_SHARE
*
share
;
DBUG_ENTER
(
"openfrm"
);
DBUG_PRINT
(
"enter"
,(
"name: '%s' form:
0x
%lx"
,
name
,
outparam
));
DBUG_PRINT
(
"enter"
,(
"name: '%s' form: %lx"
,
name
,
outparam
));
error
=
1
;
disk_buff
=
NULL
;
bzero
((
char
*
)
outparam
,
sizeof
(
*
outparam
));
outparam
->
blob_ptr_size
=
sizeof
(
char
*
);
disk_buff
=
NULL
;
record
=
NULL
;
keynames
=
NullS
;
outparam
->
db_stat
=
db_stat
;
error
=
1
;
init_sql_alloc
(
&
outparam
->
mem_root
,
TABLE_ALLOC_BLOCK_SIZE
,
0
);
root_ptr
=
my_pthread_getspecific_ptr
(
MEM_ROOT
**
,
THR_MALLOC
);
old_root
=
*
root_ptr
;
*
root_ptr
=
&
outparam
->
mem_root
;
bzero
((
char
*
)
outparam
,
sizeof
(
*
outparam
));
outparam
->
in_use
=
thd
;
outparam
->
s
=
share
=
&
outparam
->
share_not_to_be_used
;
outparam
->
real_name
=
strdup_root
(
&
outparam
->
mem_root
,
name
+
dirname_length
(
name
));
outparam
->
table_name
=
my_strdup
(
alias
,
MYF
(
MY_WME
));
if
(
!
outparam
->
real_name
||
!
outparam
->
table_name
)
goto
err_end
;
*
fn_ext
(
outparam
->
real_name
)
=
'\0'
;
// Remove extension
if
((
file
=
my_open
(
fn_format
(
index_file
,
name
,
""
,
reg_ext
,
MY_UNPACK_FILENAME
),
if
((
file
=
my_open
(
fn_format
(
index_file
,
name
,
""
,
reg_ext
,
MY_UNPACK_FILENAME
),
O_RDONLY
|
O_SHARE
,
MYF
(
0
)))
<
0
)
goto
err
;
error
=
4
;
if
(
my_read
(
file
,(
byte
*
)
head
,
64
,
MYF
(
MY_NABP
)))
goto
err
;
if
(
memcmp
(
head
,
"TYPE="
,
5
)
==
0
)
{
// new .frm
my_close
(
file
,
MYF
(
MY_WME
));
if
(
db_stat
&
NO_ERR_ON_NEW_FRM
)
DBUG_RETURN
(
5
);
file
=
-
1
;
// caller can't process new .frm
goto
err
;
goto
err_end
;
/* purecov: inspected */
}
error
=
4
;
if
(
!
(
outparam
->
path
=
strdup_root
(
&
outparam
->
mem_root
,
name
)))
goto
err_not_open
;
*
fn_ext
(
outparam
->
path
)
=
'\0'
;
// Remove extension
share
->
blob_ptr_size
=
sizeof
(
char
*
);
outparam
->
db_stat
=
db_stat
;
init_sql_alloc
(
&
outparam
->
mem_root
,
TABLE_ALLOC_BLOCK_SIZE
,
0
);
*
root_ptr
=
&
outparam
->
mem_root
;
share
->
table_name
=
strdup_root
(
&
outparam
->
mem_root
,
name
+
dirname_length
(
name
));
share
->
path
=
strdup_root
(
&
outparam
->
mem_root
,
name
);
outparam
->
alias
=
my_strdup
(
alias
,
MYF
(
MY_WME
));
if
(
!
share
->
table_name
||
!
share
->
path
||
!
outparam
->
alias
)
goto
err
;
*
fn_ext
(
share
->
table_name
)
=
'\0'
;
// Remove extension
*
fn_ext
(
share
->
path
)
=
'\0'
;
// Remove extension
if
(
my_read
(
file
,(
byte
*
)
head
,
64
,
MYF
(
MY_NABP
)))
goto
err_not_open
;
if
(
head
[
0
]
!=
(
uchar
)
254
||
head
[
1
]
!=
1
||
(
head
[
2
]
!=
FRM_VER
&&
head
[
2
]
!=
FRM_VER
+
1
&&
!
(
head
[
2
]
>=
FRM_VER
+
3
&&
head
[
2
]
<=
FRM_VER
+
4
)))
goto
err
;
/* purecov: inspected */
(
head
[
2
]
!=
FRM_VER
&&
head
[
2
]
!=
FRM_VER
+
1
&&
head
[
2
]
!=
FRM_VER
+
3
))
goto
err_not_open
;
/* purecov: inspected */
new_field_pack_flag
=
head
[
27
];
new_frm_ver
=
(
head
[
2
]
-
FRM_VER
);
field_pack_length
=
new_frm_ver
<
2
?
11
:
17
;
error
=
3
;
if
(
!
(
pos
=
get_form_pos
(
file
,
head
,(
TYPELIB
*
)
0
)))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
*
fn_ext
(
index_file
)
=
'\0'
;
// Remove .frm extension
share
->
frm_version
=
head
[
2
];
share
->
db_type
=
ha_checktype
((
enum
db_type
)
(
uint
)
*
(
head
+
3
));
share
->
db_create_options
=
db_create_options
=
uint2korr
(
head
+
30
);
share
->
db_options_in_use
=
share
->
db_create_options
;
null_field_first
=
0
;
outparam
->
frm_version
=
head
[
2
];
outparam
->
db_type
=
ha_checktype
((
enum
db_type
)
(
uint
)
*
(
head
+
3
));
outparam
->
db_create_options
=
db_create_options
=
uint2korr
(
head
+
30
);
outparam
->
db_options_in_use
=
outparam
->
db_create_options
;
null_field_first
=
0
;
if
(
!
head
[
32
])
// New frm file in 3.23
{
share
->
avg_row_length
=
uint4korr
(
head
+
34
);
share
->
row_type
=
(
row_type
)
head
[
40
];
share
->
raid_type
=
head
[
41
];
share
->
raid_chunks
=
head
[
42
];
share
->
raid_chunksize
=
uint4korr
(
head
+
43
);
share
->
table_charset
=
get_charset
((
uint
)
head
[
38
],
MYF
(
0
));
null_field_first
=
1
;
outparam
->
avg_row_length
=
uint4korr
(
head
+
34
);
outparam
->
row_type
=
(
row_type
)
head
[
40
];
outparam
->
raid_type
=
head
[
41
];
outparam
->
raid_chunks
=
head
[
42
];
outparam
->
raid_chunksize
=
uint4korr
(
head
+
43
);
outparam
->
table_charset
=
get_charset
((
uint
)
head
[
38
],
MYF
(
0
));
null_field_first
=
1
;
}
if
(
!
share
->
table_charset
)
if
(
!
outparam
->
table_charset
)
{
/* unknown charset in head[38] or pre-3.23 frm */
if
(
use_mb
(
default_charset_info
))
...
...
@@ -174,34 +156,35 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
"so character column sizes may have changed"
,
name
);
}
share
->
table_charset
=
default_charset_info
;
outparam
->
table_charset
=
default_charset_info
;
}
share
->
db_record_offset
=
1
;
outparam
->
db_record_offset
=
1
;
if
(
db_create_options
&
HA_OPTION_LONG_BLOB_PTR
)
share
->
blob_ptr_size
=
portable_sizeof_char_ptr
;
/* Set temporar
i
ly a good value for db_low_byte_first */
share
->
db_low_byte_first
=
test
(
share
->
db_type
!=
DB_TYPE_ISAM
);
outparam
->
blob_ptr_size
=
portable_sizeof_char_ptr
;
/* Set temporar
y
ly a good value for db_low_byte_first */
outparam
->
db_low_byte_first
=
test
(
outparam
->
db_type
!=
DB_TYPE_ISAM
);
error
=
4
;
share
->
max_rows
=
uint4korr
(
head
+
18
);
share
->
min_rows
=
uint4korr
(
head
+
22
);
outparam
->
max_rows
=
uint4korr
(
head
+
18
);
outparam
->
min_rows
=
uint4korr
(
head
+
22
);
/* Read keyinformation */
key_info_length
=
(
uint
)
uint2korr
(
head
+
28
);
VOID
(
my_seek
(
file
,(
ulong
)
uint2korr
(
head
+
6
),
MY_SEEK_SET
,
MYF
(
0
)));
if
(
read_string
(
file
,(
gptr
*
)
&
disk_buff
,
key_info_length
))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
if
(
disk_buff
[
0
]
&
0x80
)
{
share
->
keys
=
keys
=
(
disk_buff
[
1
]
<<
7
)
|
(
disk_buff
[
0
]
&
0x7f
);
share
->
key_parts
=
key_parts
=
uint2korr
(
disk_buff
+
2
);
outparam
->
keys
=
keys
=
(
disk_buff
[
1
]
<<
7
)
|
(
disk_buff
[
0
]
&
0x7f
);
outparam
->
key_parts
=
key_parts
=
uint2korr
(
disk_buff
+
2
);
}
else
{
share
->
keys
=
keys
=
disk_buff
[
0
];
share
->
key_parts
=
key_parts
=
disk_buff
[
1
];
outparam
->
keys
=
keys
=
disk_buff
[
0
];
outparam
->
key_parts
=
key_parts
=
disk_buff
[
1
];
}
share
->
keys_for_keyread
.
init
(
0
);
share
->
keys_in_use
.
init
(
keys
);
outparam
->
keys_for_keyread
.
init
(
0
);
outparam
->
keys_in_use
.
init
(
keys
);
outparam
->
read_only_keys
.
init
(
keys
);
outparam
->
quick_keys
.
init
();
outparam
->
used_keys
.
init
();
outparam
->
keys_in_use_for_query
.
init
();
...
...
@@ -209,7 +192,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
n_length
=
keys
*
sizeof
(
KEY
)
+
key_parts
*
sizeof
(
KEY_PART_INFO
);
if
(
!
(
keyinfo
=
(
KEY
*
)
alloc_root
(
&
outparam
->
mem_root
,
n_length
+
uint2korr
(
disk_buff
+
4
))))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
bzero
((
char
*
)
keyinfo
,
n_length
);
outparam
->
key_info
=
keyinfo
;
key_part
=
my_reinterpret_cast
(
KEY_PART_INFO
*
)
(
keyinfo
+
keys
);
...
...
@@ -218,12 +201,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
ulong
*
rec_per_key
;
if
(
!
(
rec_per_key
=
(
ulong
*
)
alloc_root
(
&
outparam
->
mem_root
,
sizeof
(
ulong
*
)
*
key_parts
)))
goto
err
;
goto
err
_not_open
;
for
(
i
=
0
;
i
<
keys
;
i
++
,
keyinfo
++
)
{
keyinfo
->
table
=
outparam
;
if
(
new_frm_ver
>=
3
)
if
(
new_frm_ver
==
3
)
{
keyinfo
->
flags
=
(
uint
)
uint2korr
(
strpos
)
^
HA_NOSAME
;
keyinfo
->
key_length
=
(
uint
)
uint2korr
(
strpos
+
2
);
...
...
@@ -272,9 +254,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
keynames
=
(
char
*
)
key_part
;
strpos
+=
(
strmov
(
keynames
,
(
char
*
)
strpos
)
-
keynames
)
+
1
;
share
->
reclength
=
uint2korr
((
head
+
16
));
outparam
->
reclength
=
uint2korr
((
head
+
16
));
if
(
*
(
head
+
26
)
==
1
)
share
->
system
=
1
;
/* one-record-database */
outparam
->
system
=
1
;
/* one-record-database */
#ifdef HAVE_CRYPTED_FRM
else
if
(
*
(
head
+
26
)
==
2
)
{
...
...
@@ -286,97 +268,84 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
#endif
/* Allocate handler */
if
(
!
(
outparam
->
file
=
get_new_handler
(
outparam
,
share
->
db_type
)))
goto
err
;
if
(
!
(
outparam
->
file
=
get_new_handler
(
outparam
,
outparam
->
db_type
)))
goto
err
_not_open
;
error
=
4
;
outparam
->
reginfo
.
lock_type
=
TL_UNLOCK
;
outparam
->
current_lock
=
F_UNLCK
;
if
((
db_stat
&
HA_OPEN_KEYFILE
)
||
(
prgflag
&
DELAYED_OPEN
))
records
=
2
;
else
records
=
1
;
if
(
prgflag
&
(
READ_ALL
+
EXTRA_RECORD
))
records
++
;
if
((
db_stat
&
HA_OPEN_KEYFILE
)
||
(
prgflag
&
DELAYED_OPEN
))
records
=
2
;
else
records
=
1
;
if
(
prgflag
&
(
READ_ALL
+
EXTRA_RECORD
))
records
++
;
/* QQ: TODO, remove the +1 from below */
rec_buff_length
=
ALIGN_SIZE
(
share
->
reclength
+
1
+
rec_buff_length
=
ALIGN_SIZE
(
outparam
->
reclength
+
1
+
outparam
->
file
->
extra_rec_buf_length
());
share
->
rec_buff_length
=
rec_buff_length
;
if
(
!
(
record
=
(
char
*
)
alloc_root
(
&
outparam
->
mem_root
,
rec_buff_length
*
records
)))
goto
err
;
/* purecov: inspected */
share
->
default_values
=
(
byte
*
)
record
;
if
(
my_pread
(
file
,(
byte
*
)
record
,
(
uint
)
share
->
reclength
,
if
(
!
(
outparam
->
record
[
0
]
=
(
byte
*
)
(
record
=
(
char
*
)
alloc_root
(
&
outparam
->
mem_root
,
rec_buff_length
*
records
))))
goto
err_not_open
;
/* purecov: inspected */
record
[
outparam
->
reclength
]
=
0
;
// For purify and ->c_ptr()
outparam
->
rec_buff_length
=
rec_buff_length
;
if
(
my_pread
(
file
,(
byte
*
)
record
,(
uint
)
outparam
->
reclength
,
(
ulong
)
(
uint2korr
(
head
+
6
)
+
((
uint2korr
(
head
+
14
)
==
0xffff
?
uint4korr
(
head
+
47
)
:
uint2korr
(
head
+
14
)))),
MYF
(
MY_NABP
)))
goto
err
;
/* purecov: inspected */
if
(
records
==
1
)
goto
err
_not_open
;
/* purecov: inspected */
/* HACK: table->record[2] is used instead of table->default_values here */
for
(
i
=
0
;
i
<
records
;
i
++
,
record
+=
rec_buff_length
)
{
/* We are probably in hard repair, and the buffers should not be used */
outparam
->
record
[
0
]
=
outparam
->
record
[
1
]
=
share
->
default_values
;
}
else
{
outparam
->
record
[
0
]
=
(
byte
*
)
record
+
rec_buff_length
;
if
(
records
>
2
)
outparam
->
record
[
1
]
=
(
byte
*
)
record
+
rec_buff_length
*
2
;
else
outparam
->
record
[
1
]
=
outparam
->
record
[
0
];
// Safety
outparam
->
record
[
i
]
=
(
byte
*
)
record
;
if
(
i
)
memcpy
(
record
,
record
-
rec_buff_length
,(
uint
)
outparam
->
reclength
);
}
#ifdef HAVE_purify
/*
We need this because when we read var-length rows, we are not updating
bytes after end of varchar
*/
if
(
records
>
1
)
{
memcpy
(
outparam
->
record
[
0
],
share
->
default_values
,
rec_buff_length
);
if
(
records
>
2
)
memcpy
(
outparam
->
record
[
1
],
share
->
default_values
,
rec_buff_length
);
if
(
records
==
2
)
{
/* fix for select */
outparam
->
default_values
=
outparam
->
record
[
1
];
if
(
db_stat
&
HA_READ_ONLY
)
outparam
->
record
[
1
]
=
outparam
->
record
[
0
];
/* purecov: inspected */
}
#endif
outparam
->
insert_values
=
0
;
/* for INSERT ... UPDATE */
VOID
(
my_seek
(
file
,
pos
,
MY_SEEK_SET
,
MYF
(
0
)));
if
(
my_read
(
file
,(
byte
*
)
head
,
288
,
MYF
(
MY_NABP
)))
goto
err
;
if
(
my_read
(
file
,(
byte
*
)
head
,
288
,
MYF
(
MY_NABP
)))
goto
err_not_open
;
#ifdef HAVE_CRYPTED_FRM
if
(
crypted
)
{
crypted
->
decode
((
char
*
)
head
+
256
,
288
-
256
);
if
(
sint2korr
(
head
+
284
)
!=
0
)
// Should be 0
goto
err
;
// Wrong password
goto
err
_not_open
;
// Wrong password
}
#endif
share
->
fields
=
uint2korr
(
head
+
258
);
pos
=
uint2korr
(
head
+
260
);
/* Length of all screens */
n_length
=
uint2korr
(
head
+
268
);
interval_count
=
uint2korr
(
head
+
270
);
interval_parts
=
uint2korr
(
head
+
272
);
int_length
=
uint2korr
(
head
+
274
);
share
->
null_fields
=
uint2korr
(
head
+
282
);
com_length
=
uint2korr
(
head
+
284
);
share
->
comment
=
strdup_root
(
&
outparam
->
mem_root
,
(
char
*
)
head
+
47
);
outparam
->
fields
=
uint2korr
(
head
+
258
);
pos
=
uint2korr
(
head
+
260
);
/* Length of all screens */
n_length
=
uint2korr
(
head
+
268
);
interval_count
=
uint2korr
(
head
+
270
);
interval_parts
=
uint2korr
(
head
+
272
);
int_length
=
uint2korr
(
head
+
274
);
outparam
->
null_fields
=
uint2korr
(
head
+
282
);
com_length
=
uint2korr
(
head
+
284
);
outparam
->
comment
=
strdup_root
(
&
outparam
->
mem_root
,
(
char
*
)
head
+
47
);
DBUG_PRINT
(
"info"
,(
"i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d"
,
interval_count
,
interval_parts
,
share
->
keys
,
n_length
,
int_length
,
com_length
));
DBUG_PRINT
(
"info"
,(
"i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d"
,
interval_count
,
interval_parts
,
outparam
->
keys
,
n_length
,
int_length
,
com_length
));
if
(
!
(
field_ptr
=
(
Field
**
)
alloc_root
(
&
outparam
->
mem_root
,
(
uint
)
((
share
->
fields
+
1
)
*
sizeof
(
Field
*
)
+
(
uint
)
((
outparam
->
fields
+
1
)
*
sizeof
(
Field
*
)
+
interval_count
*
sizeof
(
TYPELIB
)
+
(
share
->
fields
+
interval_parts
+
(
outparam
->
fields
+
interval_parts
+
keys
+
3
)
*
sizeof
(
my_string
)
+
(
n_length
+
int_length
+
com_length
)))))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
outparam
->
field
=
field_ptr
;
read_length
=
(
uint
)
(
share
->
fields
*
field_pack_length
+
read_length
=
(
uint
)
(
outparam
->
fields
*
field_pack_length
+
pos
+
(
uint
)
(
n_length
+
int_length
+
com_length
));
if
(
read_string
(
file
,(
gptr
*
)
&
disk_buff
,
read_length
))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
#ifdef HAVE_CRYPTED_FRM
if
(
crypted
)
{
...
...
@@ -387,31 +356,31 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
#endif
strpos
=
disk_buff
+
pos
;
share
->
intervals
=
(
TYPELIB
*
)
(
field_ptr
+
share
->
fields
+
1
);
int_array
=
(
const
char
**
)
(
share
->
intervals
+
interval_count
);
names
=
(
char
*
)
(
int_array
+
share
->
fields
+
interval_parts
+
keys
+
3
);
outparam
->
intervals
=
(
TYPELIB
*
)
(
field_ptr
+
outparam
->
fields
+
1
);
int_array
=
(
const
char
**
)
(
outparam
->
intervals
+
interval_count
);
names
=
(
char
*
)
(
int_array
+
outparam
->
fields
+
interval_parts
+
keys
+
3
);
if
(
!
interval_count
)
share
->
intervals
=
0
;
// For better debugging
memcpy
((
char
*
)
names
,
strpos
+
(
share
->
fields
*
field_pack_length
),
outparam
->
intervals
=
0
;
// For better debugging
memcpy
((
char
*
)
names
,
strpos
+
(
outparam
->
fields
*
field_pack_length
),
(
uint
)
(
n_length
+
int_length
));
comment_pos
=
names
+
(
n_length
+
int_length
);
comment_pos
=
names
+
(
n_length
+
int_length
);
memcpy
(
comment_pos
,
disk_buff
+
read_length
-
com_length
,
com_length
);
fix_type_pointers
(
&
int_array
,
&
share
->
fieldnames
,
1
,
&
names
);
fix_type_pointers
(
&
int_array
,
share
->
intervals
,
interval_count
,
fix_type_pointers
(
&
int_array
,
&
outparam
->
fieldnames
,
1
,
&
names
);
fix_type_pointers
(
&
int_array
,
outparam
->
intervals
,
interval_count
,
&
names
);
{
/* Set ENUM and SET lengths */
TYPELIB
*
interval
;
for
(
interval
=
share
->
intervals
;
interval
<
share
->
intervals
+
interval_count
;
for
(
interval
=
outparam
->
intervals
;
interval
<
outparam
->
intervals
+
interval_count
;
interval
++
)
{
uint
count
=
(
uint
)
(
interval
->
count
+
1
)
*
sizeof
(
uint
);
if
(
!
(
interval
->
type_lengths
=
(
uint
*
)
alloc_root
(
&
outparam
->
mem_root
,
count
)))
goto
err
;
goto
err
_not_open
;
for
(
count
=
0
;
count
<
interval
->
count
;
count
++
)
interval
->
type_lengths
[
count
]
=
strlen
(
interval
->
type_names
[
count
]);
interval
->
type_lengths
[
count
]
=
0
;
...
...
@@ -419,33 +388,33 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
if
(
keynames
)
fix_type_pointers
(
&
int_array
,
&
share
->
keynames
,
1
,
&
keynames
);
fix_type_pointers
(
&
int_array
,
&
outparam
->
keynames
,
1
,
&
keynames
);
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
file
=
-
1
;
record
=
(
char
*
)
outparam
->
record
[
0
]
-
1
;
/* Fieldstart = 1 */
record
=
(
char
*
)
outparam
->
record
[
0
]
-
1
;
/* Fieldstart = 1 */
if
(
null_field_first
)
{
outparam
->
null_flags
=
null_pos
=
(
uchar
*
)
record
+
1
;
null_bit
_pos
=
(
db_create_options
&
HA_OPTION_PACK_RECORD
)
?
0
:
1
;
share
->
null_bytes
=
(
share
->
null_fields
+
null_bit_pos
+
7
)
/
8
;
null_bit
=
(
db_create_options
&
HA_OPTION_PACK_RECORD
)
?
1
:
2
;
outparam
->
null_bytes
=
(
outparam
->
null_fields
+
null_bit
+
6
)
/
8
;
}
else
{
share
->
null_bytes
=
(
share
->
null_fields
+
7
)
/
8
;
outparam
->
null_flags
=
null_pos
=
(
uchar
*
)
(
record
+
1
+
share
->
reclength
-
share
->
null_bytes
);
null_bit
_pos
=
0
;
outparam
->
null_bytes
=
(
outparam
->
null_fields
+
7
)
/
8
;
outparam
->
null_flags
=
null_pos
=
(
uchar
*
)
(
record
+
1
+
outparam
->
reclength
-
outparam
->
null_bytes
);
null_bit
=
1
;
}
use_hash
=
share
->
fields
>=
MAX_FIELDS_BEFORE_HASH
;
use_hash
=
outparam
->
fields
>=
MAX_FIELDS_BEFORE_HASH
;
if
(
use_hash
)
use_hash
=
!
hash_init
(
&
share
->
name_hash
,
use_hash
=
!
hash_init
(
&
outparam
->
name_hash
,
system_charset_info
,
share
->
fields
,
0
,
0
,
outparam
->
fields
,
0
,
0
,
(
hash_get_key
)
get_field_name
,
0
,
0
);
for
(
i
=
0
;
i
<
share
->
fields
;
i
++
,
strpos
+=
field_pack_length
,
field_ptr
++
)
for
(
i
=
0
;
i
<
outparam
->
fields
;
i
++
,
strpos
+=
field_pack_length
,
field_ptr
++
)
{
uint
pack_flag
,
interval_nr
,
unireg_type
,
recpos
,
field_length
;
enum_field_types
field_type
;
...
...
@@ -453,7 +422,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
Field
::
geometry_type
geom_type
=
Field
::
GEOM_GEOMETRY
;
LEX_STRING
comment
;
if
(
new_frm_ver
>
=
3
)
if
(
new_frm_ver
=
=
3
)
{
/* new frm file in 4.1 */
field_length
=
uint2korr
(
strpos
+
3
);
...
...
@@ -461,10 +430,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
pack_flag
=
uint2korr
(
strpos
+
8
);
unireg_type
=
(
uint
)
strpos
[
10
];
interval_nr
=
(
uint
)
strpos
[
12
];
uint
comment_length
=
uint2korr
(
strpos
+
15
);
field_type
=
(
enum_field_types
)
(
uint
)
strpos
[
13
];
/
* charset and geometry_type share the same byte in frm */
/
/ charset and geometry_type share the same byte in frm
if
(
field_type
==
FIELD_TYPE_GEOMETRY
)
{
#ifdef HAVE_SPATIAL
...
...
@@ -472,7 +442,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
charset
=
&
my_charset_bin
;
#else
error
=
4
;
// unsupported field type
goto
err
;
goto
err
_not_open
;
#endif
}
else
...
...
@@ -483,7 +453,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
{
error
=
5
;
// Unknown or unavailable charset
errarg
=
(
int
)
strpos
[
14
];
goto
err
;
goto
err
_not_open
;
}
}
if
(
!
comment_length
)
...
...
@@ -503,7 +473,6 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
field_length
=
(
uint
)
strpos
[
3
];
recpos
=
uint2korr
(
strpos
+
4
),
pack_flag
=
uint2korr
(
strpos
+
6
);
pack_flag
&=
~
FIELDFLAG_NO_DEFAULT
;
// Safety for old files
unireg_type
=
(
uint
)
strpos
[
8
];
interval_nr
=
(
uint
)
strpos
[
10
];
...
...
@@ -520,7 +489,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if
(
!
f_is_blob
(
pack_flag
))
{
// 3.23 or 4.0 string
if
(
!
(
charset
=
get_charset_by_csname
(
share
->
table_charset
->
csname
,
if
(
!
(
charset
=
get_charset_by_csname
(
outparam
->
table_charset
->
csname
,
MY_CS_BINSORT
,
MYF
(
0
))))
charset
=
&
my_charset_bin
;
}
...
...
@@ -528,58 +497,51 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
charset
=
&
my_charset_bin
;
}
else
charset
=
share
->
table_charset
;
charset
=
outparam
->
table_charset
;
bzero
((
char
*
)
&
comment
,
sizeof
(
comment
));
}
if
(
interval_nr
&&
charset
->
mbminlen
>
1
)
{
/* Unescape UCS2 intervals from HEX notation */
TYPELIB
*
interval
=
share
->
intervals
+
interval_nr
-
1
;
TYPELIB
*
interval
=
outparam
->
intervals
+
interval_nr
-
1
;
unhex_type2
(
interval
);
}
*
field_ptr
=
reg_field
=
make_field
(
record
+
recpos
,
(
uint32
)
field_length
,
null_pos
,
null_bit_pos
,
null_pos
,
null_bit
,
pack_flag
,
field_type
,
charset
,
geom_type
,
(
Field
::
utype
)
MTYP_TYPENR
(
unireg_type
),
(
interval_nr
?
share
->
intervals
+
interval_nr
-
1
:
outparam
->
intervals
+
interval_nr
-
1
:
(
TYPELIB
*
)
0
),
share
->
fieldnames
.
type_names
[
i
],
outparam
->
fieldnames
.
type_names
[
i
],
outparam
);
if
(
!
reg_field
)
// Not supported field type
{
error
=
4
;
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
}
reg_field
->
comment
=
comment
;
if
(
field_type
==
FIELD_TYPE_BIT
)
if
(
!
(
reg_field
->
flags
&
NOT_NULL_FLAG
)
)
{
if
((
null_bit
_pos
+=
field_length
&
7
)
>
7
)
if
((
null_bit
<<=
1
)
==
256
)
{
null_pos
++
;
null_bit_pos
-=
8
;
}
null_bit
=
1
;
}
if
(
!
(
reg_field
->
flags
&
NOT_NULL_FLAG
))
{
if
(
!
(
null_bit_pos
=
(
null_bit_pos
+
1
)
&
7
))
null_pos
++
;
}
if
(
f_no_default
(
pack_flag
))
reg_field
->
flags
|=
NO_DEFAULT_VALUE_FLAG
;
if
(
reg_field
->
unireg_check
==
Field
::
NEXT_NUMBER
)
outparam
->
found_next_number_field
=
reg_field
;
if
(
outparam
->
timestamp_field
==
reg_field
)
share
->
timestamp_field_offset
=
i
;
outparam
->
timestamp_field_offset
=
i
;
if
(
use_hash
)
(
void
)
my_hash_insert
(
&
share
->
name_hash
,(
byte
*
)
field_ptr
);
//
never fail
(
void
)
my_hash_insert
(
&
outparam
->
name_hash
,(
byte
*
)
field_ptr
);
// Will
never fail
}
*
field_ptr
=
0
;
// End marker
...
...
@@ -587,15 +549,15 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if
(
key_parts
)
{
uint
primary_key
=
(
uint
)
(
find_type
((
char
*
)
primary_key_name
,
&
share
->
keynames
,
3
)
-
1
);
&
outparam
->
keynames
,
3
)
-
1
);
uint
ha_option
=
outparam
->
file
->
table_flags
();
keyinfo
=
outparam
->
key_info
;
key_part
=
keyinfo
->
key_part
;
for
(
uint
key
=
0
;
key
<
share
->
keys
;
key
++
,
keyinfo
++
)
for
(
uint
key
=
0
;
key
<
outparam
->
keys
;
key
++
,
keyinfo
++
)
{
uint
usable_parts
=
0
;
keyinfo
->
name
=
(
char
*
)
share
->
keynames
.
type_names
[
key
];
keyinfo
->
name
=
(
char
*
)
outparam
->
keynames
.
type_names
[
key
];
/* Fix fulltext keys for old .frm files */
if
(
outparam
->
key_info
[
key
].
flags
&
HA_FULLTEXT
)
outparam
->
key_info
[
key
].
algorithm
=
HA_KEY_ALG_FULLTEXT
;
...
...
@@ -628,8 +590,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
(
uint
)
key_part
->
offset
,
(
uint
)
key_part
->
length
);
#ifdef EXTRA_DEBUG
if
(
key_part
->
fieldnr
>
share
->
fields
)
goto
err
;
// sanity check
if
(
key_part
->
fieldnr
>
outparam
->
fields
)
goto
err
_not_open
;
// sanity check
#endif
if
(
key_part
->
fieldnr
)
{
// Should always be true !
...
...
@@ -645,12 +607,10 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
keyinfo
->
key_length
+=
HA_KEY_NULL_LENGTH
;
}
if
(
field
->
type
()
==
FIELD_TYPE_BLOB
||
field
->
real_type
()
==
MYSQL_TYPE_VARCHAR
)
field
->
real_type
()
==
FIELD_TYPE_VAR_STRING
)
{
if
(
field
->
type
()
==
FIELD_TYPE_BLOB
)
key_part
->
key_part_flag
|=
HA_BLOB_PART
;
else
key_part
->
key_part_flag
|=
HA_VAR_LENGTH_PART
;
keyinfo
->
extra_length
+=
HA_KEY_BLOB_LENGTH
;
key_part
->
store_length
+=
HA_KEY_BLOB_LENGTH
;
keyinfo
->
key_length
+=
HA_KEY_BLOB_LENGTH
;
...
...
@@ -661,10 +621,6 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if
(
!
(
field
->
flags
&
BINARY_FLAG
))
keyinfo
->
flags
|=
HA_END_SPACE_KEY
;
}
set_if_bigger
(
share
->
max_key_length
,
keyinfo
->
key_length
);
if
(
field
->
type
()
==
MYSQL_TYPE_BIT
)
key_part
->
key_part_flag
|=
HA_BIT_PART
;
if
(
i
==
0
&&
key
!=
primary_key
)
field
->
flags
|=
((
keyinfo
->
flags
&
HA_NOSAME
)
&&
...
...
@@ -677,7 +633,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
{
if
(
outparam
->
file
->
index_flags
(
key
,
i
,
0
)
&
HA_KEYREAD_ONLY
)
{
share
->
keys_for_keyread
.
set_bit
(
key
);
outparam
->
read_only_keys
.
clear_bit
(
key
);
outparam
->
keys_for_keyread
.
set_bit
(
key
);
field
->
part_of_key
.
set_bit
(
key
);
}
if
(
outparam
->
file
->
index_flags
(
key
,
i
,
1
)
&
HA_READ_ORDER
)
...
...
@@ -695,7 +652,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
the primary key, then we can use any key to find this column
*/
if
(
ha_option
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
field
->
part_of_key
=
share
->
keys_in_use
;
field
->
part_of_key
=
outparam
->
keys_in_use
;
}
if
(
field
->
key_length
()
!=
key_part
->
length
)
{
...
...
@@ -723,16 +680,16 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
keyinfo
->
usable_key_parts
=
usable_parts
;
// Filesort
set_if_bigger
(
share
->
max_key_length
,
keyinfo
->
key_length
+
set_if_bigger
(
outparam
->
max_key_length
,
keyinfo
->
key_length
+
keyinfo
->
key_parts
);
share
->
total_key_length
+=
keyinfo
->
key_length
;
outparam
->
total_key_length
+=
keyinfo
->
key_length
;
if
(
keyinfo
->
flags
&
HA_NOSAME
)
set_if_bigger
(
share
->
max_unique_length
,
keyinfo
->
key_length
);
set_if_bigger
(
outparam
->
max_unique_length
,
keyinfo
->
key_length
);
}
if
(
primary_key
<
MAX_KEY
&&
(
share
->
keys_in_use
.
is_set
(
primary_key
)))
(
outparam
->
keys_in_use
.
is_set
(
primary_key
)))
{
share
->
primary_key
=
primary_key
;
outparam
->
primary_key
=
primary_key
;
/*
If we are using an integer as the primary key then allow the user to
refer to it as '_rowid'
...
...
@@ -745,25 +702,27 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
}
else
share
->
primary_key
=
MAX_KEY
;
// we do not have a primary key
outparam
->
primary_key
=
MAX_KEY
;
// we do not have a primary key
}
else
share
->
primary_key
=
MAX_KEY
;
outparam
->
primary_key
=
MAX_KEY
;
x_free
((
gptr
)
disk_buff
);
disk_buff
=
0
;
if
(
new_field_pack_flag
<=
1
)
{
/* Old file format with default as not null */
uint
null_length
=
(
share
->
null_fields
+
7
)
/
8
;
bfill
(
share
->
default_values
+
(
outparam
->
null_flags
-
(
uchar
*
)
record
),
null_length
,
255
);
{
/* Old file format with default null */
uint
null_length
=
(
outparam
->
null_fields
+
7
)
/
8
;
bfill
(
outparam
->
null_flags
,
null_length
,
255
);
bfill
(
outparam
->
null_flags
+
outparam
->
rec_buff_length
,
null_length
,
255
);
if
(
records
>
2
)
bfill
(
outparam
->
null_flags
+
outparam
->
rec_buff_length
*
2
,
null_length
,
255
);
}
if
((
reg_field
=
outparam
->
found_next_number_field
))
{
if
((
int
)
(
share
->
next_number_index
=
(
uint
)
if
((
int
)
(
outparam
->
next_number_index
=
(
uint
)
find_ref_key
(
outparam
,
reg_field
,
&
share
->
next_number_key_offset
))
<
0
)
&
outparam
->
next_number_key_offset
))
<
0
)
{
reg_field
->
unireg_check
=
Field
::
NONE
;
/* purecov: inspected */
outparam
->
found_next_number_field
=
0
;
...
...
@@ -772,30 +731,34 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
reg_field
->
flags
|=
AUTO_INCREMENT_FLAG
;
}
if
(
share
->
blob_fields
)
if
(
outparam
->
blob_fields
)
{
Field
**
ptr
;
uint
i
,
*
save
;
Field_blob
*
*
save
;
/* Store offsets to blob fields to find them fast */
if
(
!
(
share
->
blob_field
=
save
=
(
uint
*
)
alloc_root
(
&
outparam
->
mem_root
,
(
uint
)
(
share
->
blob_fields
*
sizeof
(
uint
)
))))
goto
err
;
for
(
i
=
0
,
ptr
=
outparam
->
field
;
*
ptr
;
ptr
++
,
i
++
)
if
(
!
(
outparam
->
blob_field
=
save
=
(
Field_blob
**
)
alloc_root
(
&
outparam
->
mem_root
,
(
uint
)
(
outparam
->
blob_fields
+
1
)
*
sizeof
(
Field_blob
*
))))
goto
err
_not_open
;
for
(
ptr
=
outparam
->
field
;
*
ptr
;
ptr
++
)
{
if
((
*
ptr
)
->
flags
&
BLOB_FLAG
)
(
*
save
++
)
=
i
;
(
*
save
++
)
=
(
Field_blob
*
)
*
ptr
;
}
*
save
=
0
;
// End marker
}
else
outparam
->
blob_field
=
(
Field_blob
**
)
(
outparam
->
field
+
outparam
->
fields
);
// Point at null ptr
/* The table struct is now initial
i
zed; Open the table */
/* The table struct is now initialzed; Open the table */
error
=
2
;
if
(
db_stat
)
{
int
ha_
err
;
int
err
;
unpack_filename
(
index_file
,
index_file
);
if
((
ha_err
=
(
outparam
->
file
->
if
((
err
=
(
outparam
->
file
->
ha_open
(
index_file
,
(
db_stat
&
HA_READ_ONLY
?
O_RDONLY
:
O_RDWR
),
(
db_stat
&
HA_OPEN_TEMPORARY
?
HA_OPEN_TMP_TABLE
:
...
...
@@ -807,50 +770,45 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
HA_OPEN_IGNORE_IF_LOCKED
)
|
ha_open_flags
))))
{
/* Set a flag if the table is crashed and it can be auto. repaired */
share
->
crashed
=
((
ha_
err
==
HA_ERR_CRASHED_ON_USAGE
)
&&
outparam
->
crashed
=
((
err
==
HA_ERR_CRASHED_ON_USAGE
)
&&
outparam
->
file
->
auto_repair
()
&&
!
(
ha_open_flags
&
HA_OPEN_FOR_REPAIR
));
if
(
ha_err
==
HA_ERR_NO_SUCH_TABLE
)
if
(
err
==
HA_ERR_NO_SUCH_TABLE
)
{
/* The table did not exists in storage engine, use same error message
as if the .frm file didn't exist */
error
=
1
;
my_errno
=
ENOENT
;
}
else
{
outparam
->
file
->
print_error
(
ha_err
,
MYF
(
0
));
error_reported
=
TRUE
;
}
goto
err
;
/* purecov: inspected */
goto
err_not_open
;
/* purecov: inspected */
}
}
share
->
db_low_byte_first
=
outparam
->
file
->
low_byte_first
();
outparam
->
db_low_byte_first
=
outparam
->
file
->
low_byte_first
();
*
root_ptr
=
old_root
;
thd
->
status_var
.
opened_tables
++
;
opened_tables
++
;
#ifndef DBUG_OFF
if
(
use_hash
)
(
void
)
hash_check
(
&
share
->
name_hash
);
(
void
)
hash_check
(
&
outparam
->
name_hash
);
#endif
DBUG_RETURN
(
0
);
err:
err
_not_open
:
x_free
((
gptr
)
disk_buff
);
if
(
file
>
0
)
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
err_end:
/* Here when no file */
delete
crypted
;
*
root_ptr
=
old_root
;
if
(
!
error_reported
)
frm_error
(
error
,
outparam
,
name
,
ME_ERROR
+
ME_WAITTANG
,
errarg
);
frm_error
(
error
,
outparam
,
name
,
ME_ERROR
+
ME_WAITTANG
,
errarg
);
delete
outparam
->
file
;
outparam
->
file
=
0
;
// For eas
i
er errorchecking
outparam
->
file
=
0
;
// For eas
y
er errorchecking
outparam
->
db_stat
=
0
;
hash_free
(
&
share
->
name_hash
);
free_root
(
&
outparam
->
mem_root
,
MYF
(
0
));
// Safe to call on bzero'd root
my_free
(
(
char
*
)
outparam
->
alias
,
MYF
(
MY_ALLOW_ZERO_PTR
));
hash_free
(
&
outparam
->
name_hash
);
free_root
(
&
outparam
->
mem_root
,
MYF
(
0
));
my_free
(
outparam
->
table_name
,
MYF
(
MY_ALLOW_ZERO_PTR
));
DBUG_RETURN
(
error
);
}
/* openfrm */
...
...
@@ -863,18 +821,21 @@ int closefrm(register TABLE *table)
DBUG_ENTER
(
"closefrm"
);
if
(
table
->
db_stat
)
error
=
table
->
file
->
close
();
my_free
((
char
*
)
table
->
alias
,
MYF
(
MY_ALLOW_ZERO_PTR
));
table
->
alias
=
0
;
if
(
table
->
field
)
if
(
table
->
table_name
)
{
my_free
(
table
->
table_name
,
MYF
(
0
));
table
->
table_name
=
0
;
}
if
(
table
->
fields
)
{
for
(
Field
**
ptr
=
table
->
field
;
*
ptr
;
ptr
++
)
delete
*
ptr
;
table
->
field
=
0
;
table
->
field
s
=
0
;
}
delete
table
->
file
;
table
->
file
=
0
;
/* For easi
er errorchecking */
hash_free
(
&
table
->
s
->
name_hash
);
free_root
(
&
table
->
mem_root
,
MYF
(
0
));
table
->
file
=
0
;
/* For easy
er errorchecking */
hash_free
(
&
table
->
name_hash
);
free_root
(
&
table
->
mem_root
,
MYF
(
0
));
DBUG_RETURN
(
error
);
}
...
...
@@ -883,11 +844,8 @@ int closefrm(register TABLE *table)
void
free_blobs
(
register
TABLE
*
table
)
{
uint
*
ptr
,
*
end
;
for
(
ptr
=
table
->
s
->
blob_field
,
end
=
ptr
+
table
->
s
->
blob_fields
;
ptr
!=
end
;
ptr
++
)
((
Field_blob
*
)
table
->
field
[
*
ptr
])
->
free
();
for
(
Field_blob
**
ptr
=
table
->
blob_field
;
*
ptr
;
ptr
++
)
(
*
ptr
)
->
free
();
}
...
...
@@ -1035,7 +993,6 @@ static void frm_error(int error, TABLE *form, const char *name,
int
err_no
;
char
buff
[
FN_REFLEN
];
const
char
*
form_dev
=
""
,
*
datext
;
const
char
*
real_name
=
(
char
*
)
name
+
dirname_length
(
name
);
DBUG_ENTER
(
"frm_error"
);
switch
(
error
)
{
...
...
@@ -1046,11 +1003,11 @@ static void frm_error(int error, TABLE *form, const char *name,
uint
length
=
dirname_part
(
buff
,
name
);
buff
[
length
-
1
]
=
0
;
db
=
buff
+
dirname_length
(
buff
);
my_error
(
ER_NO_SUCH_TABLE
,
MYF
(
0
),
db
,
real_name
);
my_error
(
ER_NO_SUCH_TABLE
,
MYF
(
0
),
db
,
form
->
real_name
);
}
else
my_error
(
ER_FILE_NOT_FOUND
,
errortype
,
fn_format
(
buff
,
name
,
form_dev
,
reg_ext
,
0
),
my_errno
);
my_error
(
ER_FILE_NOT_FOUND
,
errortype
,
fn_format
(
buff
,
name
,
form_dev
,
reg_ext
,
0
),
my_errno
);
break
;
case
2
:
{
...
...
@@ -1059,7 +1016,7 @@ static void frm_error(int error, TABLE *form, const char *name,
err_no
=
(
my_errno
==
ENOENT
)
?
ER_FILE_NOT_FOUND
:
(
my_errno
==
EAGAIN
)
?
ER_FILE_USED
:
ER_CANT_OPEN_FILE
;
my_error
(
err_no
,
errortype
,
fn_format
(
buff
,
real_name
,
form_dev
,
datext
,
2
),
my_errno
);
fn_format
(
buff
,
form
->
real_name
,
form_dev
,
datext
,
2
),
my_errno
);
break
;
}
case
5
:
...
...
@@ -1073,13 +1030,13 @@ static void frm_error(int error, TABLE *form, const char *name,
}
my_printf_error
(
ER_UNKNOWN_COLLATION
,
"Unknown collation '%s' in table '%-.64s' definition"
,
MYF
(
0
),
csname
,
real_name
);
MYF
(
0
),
csname
,
form
->
real_name
);
break
;
}
default:
/* Better wrong error than none */
case
4
:
my_error
(
ER_NOT_FORM_FILE
,
errortype
,
fn_format
(
buff
,
name
,
form_dev
,
reg_ext
,
0
));
my_error
(
ER_NOT_FORM_FILE
,
errortype
,
fn_format
(
buff
,
name
,
form_dev
,
reg_ext
,
0
));
break
;
}
DBUG_VOID_RETURN
;
...
...
@@ -1088,7 +1045,7 @@ static void frm_error(int error, TABLE *form, const char *name,
/*
** fix a str_type to a array type
** typeparts separated with some char. differents types are separated
** typeparts sep
e
arated with some char. differents types are separated
** with a '\0'
*/
...
...
@@ -1150,27 +1107,22 @@ TYPELIB *typelib(List<String> &strings)
}
/*
Search after a field with given start & length
If an exact field isn't found, return longest field with starts
at right position.
NOTES
This is needed because in some .frm fields 'fieldnr' was saved wrong
RETURN
0 error
# field number +1
*/
/*
** Search after a field with given start & length
** If an exact field isn't found, return longest field with starts
** at right position.
** Return 0 on error, else field number+1
** This is needed because in some .frm fields 'fieldnr' was saved wrong
*/
static
uint
find_field
(
TABLE
*
form
,
uint
start
,
uint
length
)
{
Field
**
field
;
uint
i
,
pos
,
field
s
;
uint
i
,
po
s
;
pos
=
0
;
fields
=
form
->
s
->
fields
;
for
(
field
=
form
->
field
,
i
=
1
;
i
<=
fields
;
i
++
,
field
++
)
for
(
field
=
form
->
field
,
i
=
1
;
i
<=
f
orm
->
f
ields
;
i
++
,
field
++
)
{
if
((
*
field
)
->
offset
()
==
start
)
{
...
...
@@ -1185,7 +1137,7 @@ static uint find_field(TABLE *form,uint start,uint length)
}
/* Check that the integer is in the intern
a
l */
/* Check that the integer is in the intern
val
l */
int
set_zone
(
register
int
nr
,
int
min_zone
,
int
max_zone
)
{
...
...
@@ -1249,7 +1201,7 @@ void append_unescaped(String *res, const char *pos, uint length)
res
->
append
(
'n'
);
break
;
case
'\r'
:
res
->
append
(
'\\'
);
/* This gives better read
a
bility */
res
->
append
(
'\\'
);
/* This gives better readbility */
res
->
append
(
'r'
);
break
;
case
'\\'
:
...
...
@@ -1294,11 +1246,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
if
((
file
=
my_create
(
name
,
CREATE_MODE
,
O_RDWR
|
O_TRUNC
,
MYF
(
MY_WME
)))
>=
0
)
{
bzero
((
char
*
)
fileinfo
,
64
);
/* header */
fileinfo
[
0
]
=
(
uchar
)
254
;
fileinfo
[
1
]
=
1
;
fileinfo
[
2
]
=
FRM_VER
+
3
+
test
(
create_info
->
varchar
);
fileinfo
[
0
]
=
(
uchar
)
254
;
fileinfo
[
1
]
=
1
;
fileinfo
[
2
]
=
FRM_VER
+
3
;
// Header
fileinfo
[
3
]
=
(
uchar
)
ha_checktype
(
create_info
->
db_type
);
fileinfo
[
4
]
=
1
;
int2store
(
fileinfo
+
6
,
IO_SIZE
);
/* Next block starts here */
...
...
@@ -1338,20 +1286,17 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
void
update_create_info_from_table
(
HA_CREATE_INFO
*
create_info
,
TABLE
*
table
)
{
TABLE_SHARE
*
share
=
table
->
s
;
DBUG_ENTER
(
"update_create_info_from_table"
);
create_info
->
max_rows
=
share
->
max_rows
;
create_info
->
min_rows
=
share
->
min_rows
;
create_info
->
table_options
=
share
->
db_create_options
;
create_info
->
avg_row_length
=
share
->
avg_row_length
;
create_info
->
row_type
=
share
->
row_type
;
create_info
->
raid_type
=
share
->
raid_type
;
create_info
->
raid_chunks
=
share
->
raid_chunks
;
create_info
->
raid_chunksize
=
share
->
raid_chunksize
;
create_info
->
default_table_charset
=
share
->
table_charset
;
create_info
->
max_rows
=
table
->
max_rows
;
create_info
->
min_rows
=
table
->
min_rows
;
create_info
->
table_options
=
table
->
db_create_options
;
create_info
->
avg_row_length
=
table
->
avg_row_length
;
create_info
->
row_type
=
table
->
row_type
;
create_info
->
raid_type
=
table
->
raid_type
;
create_info
->
raid_chunks
=
table
->
raid_chunks
;
create_info
->
raid_chunksize
=
table
->
raid_chunksize
;
create_info
->
default_table_charset
=
table
->
table_charset
;
create_info
->
table_charset
=
0
;
DBUG_VOID_RETURN
;
}
...
...
@@ -1566,522 +1511,12 @@ db_type get_table_type(const char *name)
error
=
my_read
(
file
,(
byte
*
)
head
,
4
,
MYF
(
MY_NABP
));
my_close
(
file
,
MYF
(
0
));
if
(
error
||
head
[
0
]
!=
(
uchar
)
254
||
head
[
1
]
!=
1
||
(
head
[
2
]
!=
FRM_VER
&&
head
[
2
]
!=
FRM_VER
+
1
&&
(
head
[
2
]
<
FRM_VER
+
3
||
head
[
2
]
>
FRM_VER
+
4
)))
(
head
[
2
]
!=
FRM_VER
&&
head
[
2
]
!=
FRM_VER
+
1
&&
head
[
2
]
!=
FRM_VER
+
3
))
DBUG_RETURN
(
DB_TYPE_UNKNOWN
);
DBUG_RETURN
(
ha_checktype
((
enum
db_type
)
(
uint
)
*
(
head
+
3
)));
}
/*
calculate md5 of query
SYNOPSIS
st_table_list::calc_md5()
buffer buffer for md5 writing
*/
void
st_table_list
::
calc_md5
(
char
*
buffer
)
{
my_MD5_CTX
context
;
uchar
digest
[
16
];
my_MD5Init
(
&
context
);
my_MD5Update
(
&
context
,(
uchar
*
)
query
.
str
,
query
.
length
);
my_MD5Final
(
digest
,
&
context
);
sprintf
((
char
*
)
buffer
,
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
,
digest
[
0
],
digest
[
1
],
digest
[
2
],
digest
[
3
],
digest
[
4
],
digest
[
5
],
digest
[
6
],
digest
[
7
],
digest
[
8
],
digest
[
9
],
digest
[
10
],
digest
[
11
],
digest
[
12
],
digest
[
13
],
digest
[
14
],
digest
[
15
]);
}
/*
set ancestor TABLE for table place holder of VIEW
SYNOPSIS
st_table_list::set_ancestor()
*/
void
st_table_list
::
set_ancestor
()
{
/* process all tables of view */
for
(
TABLE_LIST
*
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
ancestor
)
ancestor
->
set_ancestor
();
tbl
->
table
->
grant
=
grant
;
}
/* if view contain only one table, substitute TABLE of it */
if
(
!
ancestor
->
next_local
)
{
table
=
ancestor
->
table
;
schema_table
=
ancestor
->
schema_table
;
}
}
/*
Save old want_privilege and clear want_privilege
SYNOPSIS
save_and_clear_want_privilege()
*/
void
st_table_list
::
save_and_clear_want_privilege
()
{
for
(
TABLE_LIST
*
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
table
)
{
privilege_backup
=
tbl
->
table
->
grant
.
want_privilege
;
tbl
->
table
->
grant
.
want_privilege
=
0
;
}
else
{
DBUG_ASSERT
(
tbl
->
view
&&
tbl
->
ancestor
&&
tbl
->
ancestor
->
next_local
);
tbl
->
save_and_clear_want_privilege
();
}
}
}
/*
restore want_privilege saved by save_and_clear_want_privilege
SYNOPSIS
restore_want_privilege()
*/
void
st_table_list
::
restore_want_privilege
()
{
for
(
TABLE_LIST
*
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
table
)
tbl
->
table
->
grant
.
want_privilege
=
privilege_backup
;
else
{
DBUG_ASSERT
(
tbl
->
view
&&
tbl
->
ancestor
&&
tbl
->
ancestor
->
next_local
);
tbl
->
restore_want_privilege
();
}
}
}
/*
setup fields of placeholder of merged VIEW
SYNOPSIS
st_table_list::setup_ancestor()
thd - thread handler
conds - condition of this JOIN
check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
DESCRIPTION
It is:
- preparing translation table for view columns (fix_fields() for every
call and creation for first call)
- preparing WHERE, ON and CHECK OPTION condition (fix_fields() for every
call and merging for first call).
If there are underlying view(s) procedure first will be called for them.
RETURN
0 - OK
1 - error
*/
bool
st_table_list
::
setup_ancestor
(
THD
*
thd
,
Item
**
conds
,
uint8
check_opt_type
)
{
Field_translator
*
transl
;
SELECT_LEX
*
select
=
&
view
->
select_lex
;
SELECT_LEX
*
current_select_save
=
thd
->
lex
->
current_select
;
Item
*
item
;
TABLE_LIST
*
tbl
;
List_iterator_fast
<
Item
>
it
(
select
->
item_list
);
uint
i
=
0
;
bool
save_set_query_id
=
thd
->
set_query_id
;
bool
save_wrapper
=
thd
->
lex
->
select_lex
.
no_wrap_view_item
;
bool
save_allow_sum_func
=
thd
->
allow_sum_func
;
DBUG_ENTER
(
"st_table_list::setup_ancestor"
);
for
(
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
ancestor
&&
tbl
->
setup_ancestor
(
thd
,
conds
,
(
check_opt_type
==
VIEW_CHECK_CASCADED
?
VIEW_CHECK_CASCADED
:
VIEW_CHECK_NONE
)))
DBUG_RETURN
(
1
);
}
if
(
field_translation
)
{
DBUG_PRINT
(
"info"
,
(
"there are already translation table"
));
/* prevent look up in SELECTs tree */
thd
->
lex
->
current_select
=
&
thd
->
lex
->
select_lex
;
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
1
;
thd
->
set_query_id
=
1
;
/* this view was prepared already on previous PS/SP execution */
Field_translator
*
end
=
field_translation
+
select
->
item_list
.
elements
;
/* real rights will be checked in VIEW field */
save_and_clear_want_privilege
();
/* aggregate function are allowed */
thd
->
allow_sum_func
=
1
;
for
(
transl
=
field_translation
;
transl
<
end
;
transl
++
)
{
if
(
!
transl
->
item
->
fixed
&&
transl
->
item
->
fix_fields
(
thd
,
ancestor
,
&
transl
->
item
))
goto
err
;
}
for
(
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
on_expr
&&
!
tbl
->
on_expr
->
fixed
&&
tbl
->
on_expr
->
fix_fields
(
thd
,
ancestor
,
&
tbl
->
on_expr
))
goto
err
;
}
if
(
where
&&
!
where
->
fixed
&&
where
->
fix_fields
(
thd
,
ancestor
,
&
where
))
goto
err
;
if
(
check_option
&&
!
check_option
->
fixed
&&
check_option
->
fix_fields
(
thd
,
ancestor
,
&
check_option
))
goto
err
;
restore_want_privilege
();
/* WHERE/ON resolved => we can rename fields */
for
(
transl
=
field_translation
;
transl
<
end
;
transl
++
)
{
transl
->
item
->
rename
((
char
*
)
transl
->
name
);
}
goto
ok
;
}
/* view fields translation table */
if
(
!
(
transl
=
(
Field_translator
*
)(
thd
->
current_arena
->
alloc
(
select
->
item_list
.
elements
*
sizeof
(
Field_translator
)))))
{
DBUG_RETURN
(
1
);
}
/* prevent look up in SELECTs tree */
thd
->
lex
->
current_select
=
&
thd
->
lex
->
select_lex
;
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
1
;
/*
Resolve all view items against ancestor table.
TODO: do it only for real used fields "on demand" to mark really
used fields correctly.
*/
thd
->
set_query_id
=
1
;
/* real rights will be checked in VIEW field */
save_and_clear_want_privilege
();
/* aggregate function are allowed */
thd
->
allow_sum_func
=
1
;
while
((
item
=
it
++
))
{
/* save original name of view column */
char
*
name
=
item
->
name
;
transl
[
i
].
item
=
item
;
if
(
!
item
->
fixed
&&
item
->
fix_fields
(
thd
,
ancestor
,
&
transl
[
i
].
item
))
goto
err
;
/* set new item get in fix fields and original column name */
transl
[
i
++
].
name
=
name
;
}
field_translation
=
transl
;
/* TODO: sort this list? Use hash for big number of fields */
for
(
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
on_expr
&&
!
tbl
->
on_expr
->
fixed
&&
tbl
->
on_expr
->
fix_fields
(
thd
,
ancestor
,
&
tbl
->
on_expr
))
goto
err
;
}
if
(
where
||
(
check_opt_type
==
VIEW_CHECK_CASCADED
&&
ancestor
->
check_option
))
{
Item_arena
*
arena
=
thd
->
current_arena
,
backup
;
TABLE_LIST
*
tbl
=
this
;
if
(
arena
->
is_conventional
())
arena
=
0
;
// For easier test
if
(
where
&&
!
where
->
fixed
&&
where
->
fix_fields
(
thd
,
ancestor
,
&
where
))
goto
err
;
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
check_opt_type
)
{
if
(
where
)
check_option
=
where
->
copy_andor_structure
(
thd
);
if
(
check_opt_type
==
VIEW_CHECK_CASCADED
)
{
check_option
=
and_conds
(
check_option
,
ancestor
->
check_option
);
}
}
/*
check that it is not VIEW in which we insert with INSERT SELECT
(in this case we can't add view WHERE condition to main SELECT_LEX)
*/
if
(
where
&&
!
no_where_clause
)
{
/* Go up to join tree and try to find left join */
for
(;
tbl
;
tbl
=
tbl
->
embedding
)
{
if
(
tbl
->
outer_join
)
{
/*
Store WHERE condition to ON expression for outer join, because
we can't use WHERE to correctly execute left joins on VIEWs and
this expression will not be moved to WHERE condition (i.e. will
be clean correctly for PS/SP)
*/
tbl
->
on_expr
=
and_conds
(
tbl
->
on_expr
,
where
);
break
;
}
}
if
(
tbl
==
0
)
{
if
(
outer_join
)
{
/*
Store WHERE condition to ON expression for outer join, because
we can't use WHERE to correctly execute left joins on VIEWs and
this expression will not be moved to WHERE condition (i.e. will
be clean correctly for PS/SP)
*/
on_expr
=
and_conds
(
on_expr
,
where
);
}
else
{
/*
It is conds of JOIN, but it will be stored in
st_select_lex::prep_where for next reexecution
*/
*
conds
=
and_conds
(
*
conds
,
where
);
}
}
}
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
}
restore_want_privilege
();
/*
fix_fields do not need tables, because new are only AND operation and we
just need recollect statistics
*/
if
(
check_option
&&
!
check_option
->
fixed
&&
check_option
->
fix_fields
(
thd
,
0
,
&
check_option
))
goto
err
;
/* WHERE/ON resolved => we can rename fields */
{
Field_translator
*
end
=
field_translation
+
select
->
item_list
.
elements
;
for
(
transl
=
field_translation
;
transl
<
end
;
transl
++
)
{
transl
->
item
->
rename
((
char
*
)
transl
->
name
);
}
}
/* full text function moving to current select */
if
(
view
->
select_lex
.
ftfunc_list
->
elements
)
{
Item_arena
*
arena
=
thd
->
current_arena
,
backup
;
if
(
arena
->
is_conventional
())
arena
=
0
;
// For easier test
else
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
Item_func_match
*
ifm
;
List_iterator_fast
<
Item_func_match
>
li
(
*
(
view
->
select_lex
.
ftfunc_list
));
while
((
ifm
=
li
++
))
current_select_save
->
ftfunc_list
->
push_front
(
ifm
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
}
ok:
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
save_wrapper
;
thd
->
lex
->
current_select
=
current_select_save
;
thd
->
set_query_id
=
save_set_query_id
;
thd
->
allow_sum_func
=
save_allow_sum_func
;
DBUG_RETURN
(
0
);
err:
/* Hide "Unknown column" or "Unknown function" error */
if
(
thd
->
net
.
last_errno
==
ER_BAD_FIELD_ERROR
||
thd
->
net
.
last_errno
==
ER_SP_DOES_NOT_EXIST
)
{
thd
->
clear_error
();
my_error
(
ER_VIEW_INVALID
,
MYF
(
0
),
view_db
.
str
,
view_name
.
str
);
}
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
save_wrapper
;
thd
->
lex
->
current_select
=
current_select_save
;
thd
->
set_query_id
=
save_set_query_id
;
thd
->
allow_sum_func
=
save_allow_sum_func
;
DBUG_RETURN
(
1
);
}
/*
cleunup items belonged to view fields translation table
SYNOPSIS
st_table_list::cleanup_items()
*/
void
st_table_list
::
cleanup_items
()
{
if
(
!
field_translation
)
return
;
Field_translator
*
end
=
(
field_translation
+
view
->
select_lex
.
item_list
.
elements
);
for
(
Field_translator
*
transl
=
field_translation
;
transl
<
end
;
transl
++
)
transl
->
item
->
walk
(
&
Item
::
cleanup_processor
,
0
);
}
/*
check CHECK OPTION condition
SYNOPSIS
check_option()
ignore_failure ignore check option fail
RETURN
VIEW_CHECK_OK OK
VIEW_CHECK_ERROR FAILED
VIEW_CHECK_SKIP FAILED, but continue
*/
int
st_table_list
::
view_check_option
(
THD
*
thd
,
bool
ignore_failure
)
{
if
(
check_option
&&
check_option
->
val_int
()
==
0
)
{
if
(
ignore_failure
)
{
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_VIEW_CHECK_FAILED
,
ER
(
ER_VIEW_CHECK_FAILED
),
view_db
.
str
,
view_name
.
str
);
return
(
VIEW_CHECK_SKIP
);
}
else
{
my_error
(
ER_VIEW_CHECK_FAILED
,
MYF
(
0
),
view_db
.
str
,
view_name
.
str
);
return
(
VIEW_CHECK_ERROR
);
}
}
return
(
VIEW_CHECK_OK
);
}
/*
Find table in underlying tables by mask and check that only this
table belong to given mask
SYNOPSIS
st_table_list::check_single_table()
table reference on variable where to store found table
(should be 0 on call, to find table, or point to table for
unique test)
map bit mask of tables
RETURN
FALSE table not found or found only one
TRUE found several tables
*/
bool
st_table_list
::
check_single_table
(
st_table_list
**
table
,
table_map
map
)
{
for
(
TABLE_LIST
*
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
{
if
(
tbl
->
table
)
{
if
(
tbl
->
table
->
map
&
map
)
{
if
(
*
table
)
return
TRUE
;
else
*
table
=
tbl
;
}
}
else
if
(
tbl
->
check_single_table
(
table
,
map
))
return
TRUE
;
}
return
FALSE
;
}
/*
Set insert_values buffer
SYNOPSIS
set_insert_values()
mem_root memory pool for allocating
RETURN
FALSE - OK
TRUE - out of memory
*/
bool
st_table_list
::
set_insert_values
(
MEM_ROOT
*
mem_root
)
{
if
(
table
)
{
if
(
!
table
->
insert_values
&&
!
(
table
->
insert_values
=
(
byte
*
)
alloc_root
(
mem_root
,
table
->
s
->
rec_buff_length
)))
return
TRUE
;
}
else
{
DBUG_ASSERT
(
view
&&
ancestor
&&
ancestor
->
next_local
);
for
(
TABLE_LIST
*
tbl
=
ancestor
;
tbl
;
tbl
=
tbl
->
next_local
)
if
(
tbl
->
set_insert_values
(
mem_root
))
return
TRUE
;
}
return
FALSE
;
}
void
Field_iterator_view
::
set
(
TABLE_LIST
*
table
)
{
ptr
=
table
->
field_translation
;
array_end
=
ptr
+
table
->
view
->
select_lex
.
item_list
.
elements
;
}
const
char
*
Field_iterator_table
::
name
()
{
return
(
*
ptr
)
->
field_name
;
}
Item
*
Field_iterator_table
::
item
(
THD
*
thd
)
{
return
new
Item_field
(
thd
,
*
ptr
);
}
const
char
*
Field_iterator_view
::
name
()
{
return
ptr
->
name
;
}
/*****************************************************************************
** Instansiate templates
*****************************************************************************/
...
...
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