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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
f031de4f
Commit
f031de4f
authored
Jul 06, 2006
by
ingo@chilla.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge chilla.local:/home/mydev/mysql-5.0-bug16218
into chilla.local:/home/mydev/mysql-5.0-ateam
parents
518fcc8f
591d461d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
91 additions
and
37 deletions
+91
-37
sql/field.cc
sql/field.cc
+13
-18
sql/field.h
sql/field.h
+4
-3
sql/sql_insert.cc
sql/sql_insert.cc
+67
-12
sql/sql_select.cc
sql/sql_select.cc
+3
-2
sql/sql_trigger.cc
sql/sql_trigger.cc
+2
-1
sql/table.cc
sql/table.cc
+2
-1
No files found.
sql/field.cc
View file @
f031de4f
...
...
@@ -1515,7 +1515,8 @@ bool Field::optimize_range(uint idx, uint part)
}
Field
*
Field
::
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
)
Field
*
Field
::
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
bool
keep_type
__attribute__
((
unused
)))
{
Field
*
tmp
;
if
(
!
(
tmp
=
(
Field
*
)
memdup_root
(
root
,(
char
*
)
this
,
size_of
())))
...
...
@@ -1540,7 +1541,7 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
uint
new_null_bit
)
{
Field
*
tmp
;
if
((
tmp
=
new_field
(
root
,
new_table
)))
if
((
tmp
=
new_field
(
root
,
new_table
,
table
==
new_table
)))
{
tmp
->
ptr
=
new_ptr
;
tmp
->
null_ptr
=
new_null_ptr
;
...
...
@@ -6227,29 +6228,21 @@ uint Field_string::max_packed_col_length(uint max_length)
}
Field
*
Field_string
::
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
)
Field
*
Field_string
::
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
bool
keep_type
)
{
Field
*
new_field
;
if
(
type
()
!=
MYSQL_TYPE_VAR_STRING
||
table
==
new_tabl
e
)
return
Field
::
new_field
(
root
,
new_table
);
if
(
type
()
!=
MYSQL_TYPE_VAR_STRING
||
keep_typ
e
)
return
Field
::
new_field
(
root
,
new_table
,
keep_type
);
/*
Old VARCHAR field which should be modified to a VARCHAR on copy
This is done to ensure that ALTER TABLE will convert old VARCHAR fields
to now VARCHAR fields.
*/
if
((
new_field
=
new
Field_varstring
(
field_length
,
maybe_null
(),
field_name
,
new_table
,
charset
())))
{
/*
delayed_insert::get_local_table() needs a ptr copied from old table.
This is what other new_field() methods do too. The above method of
Field_varstring sets ptr to NULL.
*/
new_field
->
ptr
=
ptr
;
}
return
new_field
;
return
new
Field_varstring
(
field_length
,
maybe_null
(),
field_name
,
new_table
,
charset
());
}
/****************************************************************************
...
...
@@ -6741,9 +6734,11 @@ int Field_varstring::cmp_binary(const char *a_ptr, const char *b_ptr,
}
Field
*
Field_varstring
::
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
)
Field
*
Field_varstring
::
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
bool
keep_type
)
{
Field_varstring
*
res
=
(
Field_varstring
*
)
Field
::
new_field
(
root
,
new_table
);
Field_varstring
*
res
=
(
Field_varstring
*
)
Field
::
new_field
(
root
,
new_table
,
keep_type
);
if
(
res
)
res
->
length_bytes
=
length_bytes
;
return
res
;
...
...
sql/field.h
View file @
f031de4f
...
...
@@ -211,7 +211,8 @@ public:
*/
virtual
bool
can_be_compared_as_longlong
()
const
{
return
FALSE
;
}
virtual
void
free
()
{}
virtual
Field
*
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
);
virtual
Field
*
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
bool
keep_type
);
virtual
Field
*
new_key_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
char
*
new_ptr
,
uchar
*
new_null_ptr
,
uint
new_null_bit
);
...
...
@@ -1033,7 +1034,7 @@ public:
enum_field_types
real_type
()
const
{
return
FIELD_TYPE_STRING
;
}
bool
has_charset
(
void
)
const
{
return
charset
()
==
&
my_charset_bin
?
FALSE
:
TRUE
;
}
Field
*
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
);
Field
*
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
bool
keep_type
);
};
...
...
@@ -1105,7 +1106,7 @@ public:
enum_field_types
real_type
()
const
{
return
MYSQL_TYPE_VARCHAR
;
}
bool
has_charset
(
void
)
const
{
return
charset
()
==
&
my_charset_bin
?
FALSE
:
TRUE
;
}
Field
*
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
);
Field
*
new_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
bool
keep_type
);
Field
*
new_key_field
(
MEM_ROOT
*
root
,
struct
st_table
*
new_table
,
char
*
new_ptr
,
uchar
*
new_null_ptr
,
uint
new_null_bit
);
...
...
sql/sql_insert.cc
View file @
f031de4f
...
...
@@ -17,6 +17,44 @@
/* Insert of records */
/*
INSERT DELAYED
Insert delayed is distinguished from a normal insert by lock_type ==
TL_WRITE_DELAYED instead of TL_WRITE. It first tries to open a
"delayed" table (delayed_get_table()), but falls back to
open_and_lock_tables() on error and proceeds as normal insert then.
Opening a "delayed" table means to find a delayed insert thread that
has the table open already. If this fails, a new thread is created and
waited for to open and lock the table.
If accessing the thread succeeded, in
delayed_insert::get_local_table() the table of the thread is copied
for local use. A copy is required because the normal insert logic
works on a target table, but the other threads table object must not
be used. The insert logic uses the record buffer to create a record.
And the delayed insert thread uses the record buffer to pass the
record to the table handler. So there must be different objects. Also
the copied table is not included in the lock, so that the statement
can proceed even if the real table cannot be accessed at this moment.
Copying a table object is not a trivial operation. Besides the TABLE
object there are the field pointer array, the field objects and the
record buffer. After copying the field objects, their pointers into
the record must be "moved" to point to the new record buffer.
After this setup the normal insert logic is used. Only that for
delayed inserts write_delayed() is called instead of write_record().
It inserts the rows into a queue and signals the delayed insert thread
instead of writing directly to the table.
The delayed insert thread awakes from the signal. It locks the table,
inserts the rows from the queue, unlocks the table, and waits for the
next signal. It does normally live until a FLUSH TABLES or SHUTDOWN.
*/
#include "mysql_priv.h"
#include "sp_head.h"
#include "sql_trigger.h"
...
...
@@ -1441,6 +1479,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
my_ptrdiff_t
adjust_ptrs
;
Field
**
field
,
**
org_field
,
*
found_next_number_field
;
TABLE
*
copy
;
DBUG_ENTER
(
"delayed_insert::get_local_table"
);
/* First request insert thread to get a lock */
status
=
1
;
...
...
@@ -1464,31 +1503,47 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
}
}
/*
Allocate memory for the TABLE object, the field pointers array, and
one record buffer of reclength size. Normally a table has three
record buffers of rec_buff_length size, which includes alignment
bytes. Since the table copy is used for creating one record only,
the other record buffers and alignment are unnecessary.
*/
client_thd
->
proc_info
=
"allocating local table"
;
copy
=
(
TABLE
*
)
client_thd
->
alloc
(
sizeof
(
*
copy
)
+
(
table
->
s
->
fields
+
1
)
*
sizeof
(
Field
**
)
+
table
->
s
->
reclength
);
if
(
!
copy
)
goto
error
;
/* Copy the TABLE object. */
*
copy
=
*
table
;
copy
->
s
=
&
copy
->
share_not_to_be_used
;
// No name hashing
bzero
((
char
*
)
&
copy
->
s
->
name_hash
,
sizeof
(
copy
->
s
->
name_hash
));
/* We don't need to change the file handler here */
field
=
copy
->
field
=
(
Field
**
)
(
copy
+
1
);
copy
->
record
[
0
]
=
(
byte
*
)
(
field
+
table
->
s
->
fields
+
1
);
memcpy
((
char
*
)
copy
->
record
[
0
],(
char
*
)
table
->
record
[
0
],
table
->
s
->
reclength
);
/* Assign the pointers for the field pointers array and the record. */
field
=
copy
->
field
=
(
Field
**
)
(
copy
+
1
);
copy
->
record
[
0
]
=
(
byte
*
)
(
field
+
table
->
s
->
fields
+
1
);
memcpy
((
char
*
)
copy
->
record
[
0
],
(
char
*
)
table
->
record
[
0
],
table
->
s
->
reclength
);
/* Make a copy of all fields */
adjust_ptrs
=
PTR_BYTE_DIFF
(
copy
->
record
[
0
],
table
->
record
[
0
]);
/*
Make a copy of all fields.
The copied fields need to point into the copied record. This is done
by copying the field objects with their old pointer values and then
"move" the pointers by the distance between the original and copied
records. That way we preserve the relative positions in the records.
*/
adjust_ptrs
=
PTR_BYTE_DIFF
(
copy
->
record
[
0
],
table
->
record
[
0
]);
found_next_number_field
=
table
->
found_next_number_field
;
for
(
org_field
=
table
->
field
;
*
org_field
;
org_field
++
,
field
++
)
found_next_number_field
=
table
->
found_next_number_field
;
for
(
org_field
=
table
->
field
;
*
org_field
;
org_field
++
,
field
++
)
{
if
(
!
(
*
field
=
(
*
org_field
)
->
new_field
(
client_thd
->
mem_root
,
copy
)))
return
0
;
if
(
!
(
*
field
=
(
*
org_field
)
->
new_field
(
client_thd
->
mem_root
,
copy
,
1
)))
DBUG_RETURN
(
0
)
;
(
*
field
)
->
orig_table
=
copy
;
// Remove connection
(
*
field
)
->
move_field
(
adjust_ptrs
);
// Point at copy->record[0]
if
(
*
org_field
==
found_next_number_field
)
...
...
@@ -1515,14 +1570,14 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
/* Adjust lock_count. This table object is not part of a lock. */
copy
->
lock_count
=
0
;
return
copy
;
DBUG_RETURN
(
copy
)
;
/* Got fatal error */
error:
tables_in_use
--
;
status
=
1
;
pthread_cond_signal
(
&
cond
);
// Inform thread about abort
return
0
;
DBUG_RETURN
(
0
)
;
}
...
...
sql/sql_select.cc
View file @
f031de4f
...
...
@@ -8017,7 +8017,8 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
org_field
->
field_name
,
table
,
org_field
->
charset
());
else
new_field
=
org_field
->
new_field
(
thd
->
mem_root
,
table
);
new_field
=
org_field
->
new_field
(
thd
->
mem_root
,
table
,
table
==
org_field
->
table
);
if
(
new_field
)
{
if
(
item
)
...
...
@@ -13062,7 +13063,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
saved value
*/
Field
*
field
=
item
->
field
;
item
->
result_field
=
field
->
new_field
(
thd
->
mem_root
,
field
->
table
);
item
->
result_field
=
field
->
new_field
(
thd
->
mem_root
,
field
->
table
,
1
);
char
*
tmp
=
(
char
*
)
sql_alloc
(
field
->
pack_length
()
+
1
);
if
(
!
tmp
)
goto
err
;
...
...
sql/sql_trigger.cc
View file @
f031de4f
...
...
@@ -747,7 +747,8 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
QQ: it is supposed that it is ok to use this function for field
cloning...
*/
if
(
!
(
*
old_fld
=
(
*
fld
)
->
new_field
(
&
table
->
mem_root
,
table
)))
if
(
!
(
*
old_fld
=
(
*
fld
)
->
new_field
(
&
table
->
mem_root
,
table
,
table
==
(
*
fld
)
->
table
)))
return
1
;
(
*
old_fld
)
->
move_field
((
my_ptrdiff_t
)(
table
->
record
[
1
]
-
table
->
record
[
0
]));
...
...
sql/table.cc
View file @
f031de4f
...
...
@@ -804,7 +804,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if
(
!
(
field
->
flags
&
BLOB_FLAG
))
{
// Create a new field
field
=
key_part
->
field
=
field
->
new_field
(
&
outparam
->
mem_root
,
outparam
);
outparam
,
outparam
==
field
->
table
);
field
->
field_length
=
key_part
->
length
;
}
}
...
...
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