Hi Brian,
On May 22, 2010, at 2:41 AM, Brian Aker wrote:
On May 21, 2010, at 2:31 AM, Paul McCullagh wrote:
My problem is that the val_ methods are hard-coded to reference
record[0].
My plan is to add a second set of Field that will correspond to the
second row (got any handy names!). That way we won't need a hack in
order to access them.
The cost of generating those for user generated Tables is very
small, so there is no reason not too. For "internal" tables it is a
bit different, but then the pattern of access there is really much
more confined.
As I said in previous e-mails. I think you should to the record[]
array into an array of Row objects.
The we would simply access table->record[1]->val_....()
PBXT uses the MySQL record format internally if the record has a
fixed length (similar to how MyISAM).
Are you though? MyISAM doesn't strictly use the format. It rereads
for the format and packs in for cases where blobs, varchar, etc
exist. Most of the time, assuming that most tables are dynamic, you
have to cycle through it so you are reading each bit. The only
unaltered use is when you have a row that is entirely made up of
constants (aka... numbers, etc).
Yes, this is true. And this is the only time that PBXT actually uses
the row exactly as is, unaltered.
Actually, PBXT also uses this "fixed length" format, when VARCHAR,
CHAR and other variable types are included (but not BLOBs), as long as
the fields maximum size is not too large.
PBXT uses a different, variable length, format in all other cases.
Which format PBXT uses depends on the estimated average row length
(which can be set explicitly using AVG_ROW_LENGTH attribute of the
table). If the fixed length of a row is smaller than the estimated
average row length, then it uses the fixed length format.
It MySQL the "byte" type is even more confusing since it is encoded
differently in the raw format.
Instead, I suggest a "Row" object, into which I can plug the start
of the row buffer. Then we would have:
doInsertRecord(Row *row_object)
The Row object knows everything about the row and can be used to
access the fields.
This sounds fine, and essentially what we have at the moment (but no
knowledge of row2).
I hate calling them row1 and row2 though. Any ideas on that? Do you
want them handed to you? Should we encapsulate so that you can't
access them unless they are passed in?
Basically I think, yes. The engine should not know, and should not
care whether record[0] or record[1] has been passed to doInsertRecord().
One thing I would disagree on though is the setBuffer(), that
removes all encapsulation on the fields (which is bad, since over
time those do change). We have one format for Decimal right now, if
we change that and have no version information we take the chance we
might push data back and forth which would not be compatible.
I am OK with this. But, it means we have to create a Row object for
every row buffer we want to use.
This may be OK for the front end, which just needs to create record[0]
and record[1] for each handler. But, would not like to have to do this
inside the engine for every row I instantiate.
Best regards,
Paul
Cheers,
-Brian
So the Row object is a "per thread" object. You call row_object-
>setBuffer(u_char *buf) to set the row buffer and then you use an
array of fields to get and set the data in the buffer.
So then the record[] array would become an array of Row objects.
And an engine could create Row object to manipulate row buffers
internally (which is exactly what I am doing with the internal
Table object - or TableShare object).
The record[0] object would be passed to doInsertRecord(buf), as it
is today.
But now, the engine will not have to know that: buf == record[0]!
(Which is a correspondence that is far from obvious, but is almost
essential to know if you are implementing a storage engine today!)
Stewart: would something like this also work for your
implementation of the Embedded InnoDB?
On May 20, 2010, at 8:16 PM, Brian Aker wrote:
Hi!
I'd unpack the row by using the Field object and not go with the
offset (longterm we won't support touching the record[] directly
since it creates a big problem for abstraction). Via val_ methods
you can request the individual members. The offset was originally
added so that two sets of field objects would be needed (aka one
for recored[0] and one for record[1]). Our cost for building this
stuff is pretty low so we can just give folks a set of fields for
both images so that you aren't stuck trying to figure out the
underlying contents.
Cheers,
-Brian
On May 20, 2010, at 1:04 AM, Paul McCullagh wrote:
Hi Brian,
Just one problem maybe you have a quick suggestion:
How do I get the offset of a field into the row buffer?
When using the Table object I did this as follows:
field->offset(field->table->record[0])
But this does not work with TableShare.
On May 17, 2010, at 6:07 PM, Brian Aker wrote:
Hi!
On May 17, 2010, at 4:21 AM, Paul McCullagh wrote:
Are you suggesting I create a TableShare on the stack whenever
I need it?
I don't think this would work because AFAIK I have to call
open_table_def(), which loads the table definition. So calling
this each time I want to copy data in and out of the row would
be too slow.
What may work is to use a TableShare object instead of a Table
object.
That is what I was suggesting, just create an object and use it.
Question is, can I do something like:
share = new TableShare();
share->init(db_name, 0, name, path);
error = open_table_def(&thd, *ident, share);
Yes you can do this, hell, we can probably make it simpler then
this as well.
and then later simply:
delete share;
to remove.
Yep. If you look in createTable() you can even see how we do
this during that operation.
Cheers,
-Brian
On May 14, 2010, at 9:03 PM, Brian Aker wrote:
Hi!
On May 14, 2010, at 9:37 AM, Paul McCullagh wrote:
Here the engine will follow the "table" pointer to the
"field" array, where it uses the offsets of the data in a
record, in order to copy data in and out of the record.
So what you need is the Field** that is in share (aka, you
don't even need Table, you just need TableShare).
You could just do this:
TableShare my_share(<share_key>,....);
That way you have your own object and you never pass through
any of the locking system/dealing with any of the object
counting.
Cheers,
-Brian
--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreaming.org
pbxt.blogspot.com
--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreaming.org
pbxt.blogspot.com
--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreaming.org
pbxt.blogspot.com
--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreaming.org
pbxt.blogspot.com
_______________________________________________
Mailing list: https://launchpad.net/~pbxt-discuss
Post to : [email protected]
Unsubscribe : https://launchpad.net/~pbxt-discuss
More help : https://help.launchpad.net/ListHelp