Hi!
>>>>> "barries" == barries <barries@stripped> writes:
barries> On Sat, Mar 31, 2001 at 04:10:43PM +0300, Michael Widenius
barries> wrote:
>> Sorry for the delay in answering this..
barries> No probs, thanks for looking at it.
>> Instead of creating item for all columns, can't you instead let the
>> trigger test the columns it's interested in?
barries> Sure. New patch forthcoming.
>> If this is ok, you only have to pass the RowUpdated() function the
>> table in question.
barries> Luckily it's known to the trigger (passed in to constructor
barries> so it can pre-calculate things).
barries> <mysqld guts hints snipped; many thanks>
>> To access the new value, you can use the field class.
barries> s/field class/Field instance/ ?
Yes; I mean that you can use the functions that the field class provides
for the field instances to solve this nicely.
barries> Just checking to make sure I'm not missing something subtle
barries> about the Field class...
>> To access the old value, you can create a new field that points at
>> this as follows:
>>
>> Field old_field= *field;
>> old_field.move_field(table->rec_buff_length);
barries> I get this:
barries> trigger.cc: In method `int
barries> PostUpdateTrigger::WatchFieldsUpdated(TABLE *)':
barries> trigger.cc:87: cannot declare variable `old_field' to be of
barries> type `Field' trigger.cc:87: since the following virtual
barries> functions are abstract: field.h:108: void
barries> Field::sort_string(char *, unsigned int) field.h:107: void
barries> Field::make_field(Send_field *) field.h:96: uint
barries> Field::size_of() const field.h:91: void
barries> Field::sql_type(String &) const field.h:79: int
barries> Field::cmp(const char *, const char *) field.h:76: enum
barries> enum_field_types Field::type() const field.h:65: enum
barries> Item_result Field::result_type() const field.h:64: class
barries> String * Field::val_str(String *, String *) field.h:63:
barries> longlong Field::val_int() field.h:62: double
barries> Field::val_real() field.h:60: void Field::store(long long
barries> int) field.h:59: void Field::store(double) field.h:58: void
barries> Field::store(const char *, unsigned int) trigger.cc:87:
barries> cannot allocate an object of type `Field' trigger.cc:87:
barries> since type `Field' has abstract virtual functions
Sorry, I forgot about that :(
barries> When I try that.
barries> How's this instead:
barries> List_iterator<Field> i(extractFields); Field *f; List<Field>
barries> old_fields ; while (f=i++) { Field *old_field=
barries> f->new_field(table);
old_field-> move_field(table->rec_buff_length);
barries> old_fields.push_back(old_field); }
barries> return Handler(extractFields,old_fields);
barries> ?
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.
>> We are have been talking about hiring a new developer, Arnulf, to
>> add a foreign language API to MySQL. The current plan is to first
>> construct a good API and then create a Python interface for this.
>> (People keep telling us that Python is very suited for task like
>> this, so we decided to start with a Python interface).
barries> Sounds reasonable. I'd guess that many people (myself
barries> included, of course :-) would prefer Perl, possibly even a
barries> majority. 'course, I just look at the mod_perl memory
barries> consumption and threading issues (now that Apache 2.0 nears)
barries> to see why it's probably not as optimal as Python.
Perl would probably be the second language we would look at including,
after Python is done.
>> Arnulf has the last month done some research in how to most
>> efficiently implement this so and I hope to get some inputs from
>> him soon.
barries> Very cool. It'll give me the excuse I need to dig deeper
barries> into Python. 'course, it seems like only Perlers have
barries> responded to posts about this and that we're on the cusp of
barries> extending the embedded perls mentioned in another message.
I am a Perl user myself (never done Python before), so I have the same
excuse :)
>> Only the source.
barries> "Use the source, Luke." said Monty-wan Kenobi ;-).
barries> - Assuming that the above approach is tenable, what would be
barries> a good way of safely unpacking record[0] and record[1] into
barries> reasonable intermediary structures, or should it pass things
barries> as List<Field>& instead of List<Item>& for efficiency /
> ease?
>> This would work, but the above approach would be MUCH faster.
barries> Agreed. I'm now creating a stratified approach to let the
barries> coder choose the appropriate handler level. Basically, you
barries> can overload
barries> RowUpdated()
barries> and do it all yourself, or call AddWatchField( "column%name"
barries> ) a few times in the Trigger constructor and let RowUpdated()
barries> call your overloaded
barries> WatchedFieldsUpdated()
barries> only when an interesting ("watched") field changes, or you
barries> can also specify a list of fields to extract by calling
barries> AddExtractField( "foo" ) in the ctor and allow your
barries> overloaded
barries> Handler(const List<Field>& old_fields, const
barries> List<Field>&new_fields)
barries> called with already-mapped fields.
barries> This allows you to implement a trigger at a low, medium, or
barries> high level of abstraction (well, as high as Field gets,
barries> anyway).
barries> Does that seem reasonable to you? Current patch at
barries> http://slaysys.com/src/diff.txt
Yes, it sounds very good.
barries> . I'll gladly send the patch to the list, but I hesitate in
barries> case anyone's one a slow connection. Not sure what's good
barries> ettiquette on this list.
I think the above is good until you are satisfied with the patch.
After you are 'done', if you don't mind, I could put this in our
Patches section on the web page to make it easily accessible.
>> We at MySQL AB will of course help by answering any implementation
>> questions regarding this.
barries> Very helpful, and many thanks.
barries> - Barrie
Regards,
Monty