>>>>> "barries" == barries <barries@stripped> writes:
barries> On Sun, Apr 01, 2001 at 12:10:18PM +0300, Michael Widenius wrote:
>> Yes this should work ok as long as you don't do that in a loop!
>> The reason is that each new_field allocates space which will not be
>> freed until the SQL statement is completed.
barries> I was planning on deleting them after each row or after each query,
barries> depending on how constant table->field's pointers are. I want to
barries> minimize the scanning of table->field and the creation of old_fields.
barries> I'd prefer to cache pointers to fields and to cache the old_fields.
If you use ->new_fields, these are automaticly deleted after each
query; You could also create a new 'MEM_ROOT' object to be able to free
these at once, but it's probably much more efficient to let the
automatic delete handle this.
barries> When do the Fields pointed to table->field get exchanged for new fields?
barries> In other words, when is it safe, if ever, to cache pointers to those
barries> fields in List<Field> containers so the triggers don't need to rescan
barries> that list each row or each query?
You can't cache the field pointers as there may be many TABLE
instances that points to the same MyISAM table; If for example 2
threads are running at once, each of these has its own TABLE object
which has unique field pointers.
Currently the easyest way to cache this is to have a array of
index to the fields you are interested in. You should fix your
function to automaticly recalculate these on first usage.
You would also need to add a couple of lines of code to invalidate
the old cached values when a table is altered, renamed or dropped.
The easyest way to do this is to add a call to the invalidate
function in 'sql_base.cc::remove_table_from_cache'
You also want to invalidate the function when table->version has
changed. In other words the code should look something like this:
if table->version != trigger->table_version or trigger->table_version == 0
calculate index to fields in local array
table->version changes when someone has done a 'flush tables'
barries> The reason I ask about the constancy of table->field is that is seems to
barries> be pointing at one set of Field objects when attach_triggers() is called
barries> from open_table():
barries> DBUG_PRINT("info", ("inserting table %p into the cache", table));
barries> VOID(hash_insert(&open_cache,(byte*) table));
barries> and a different set when the triggers fire in mysql_update(). I've
barries> started walking through it in gdb, but does the table->field array
barries> ever become stable for the lifetime of the table?
No. It's just stable for the duration of the query.
barries> As a side question: how does mysqld pack variable length columns into
barries> record and record such that move_field() works?
All VARCHAR are stored as space padded strings
(In 4.0 it will be stored as 2 byte length + string)
BLOB and TEXT are a bit different. They are stored as a 1-4 byte
length + a pointer where in memory the blob actually is.
>> I could put this in our
>> Patches section on the web page to make it easily accessible.
barries> That would be just fine. I'm also thinking that it'd be nice to combine
barries> it with the embedded perl work going on and see if we can get Perl
barries> language triggers.
That would be nice...