On 2014-08-24, 5:33 PM, Chris Travers wrote:
On Sun, Aug 24, 2014 at 4:38 PM, Darren Duncan <[email protected]> wrote: As I recall, DBD::Pg already supports Postgres arrays as Perl arrays, and similarly I would recommend supporting composite type values like you mention, which are structurally tuples, as Perl hash refs for the members.For a general form for named composite types, I suggest representing a foo like this: "['foo',{bar=>'what',baz=>'ev'__}]"; its the simplest form that keeps all the information; the 'foo' part could also be generalized to however fully-qualified entity names are, eg ['public','foo'] for example. I would love to see this in DBD::Pg. However there are some complexities here not present in arrays. Arrays are at least in theory self-contained. We don't have to ask the db how to parse them. Tuples are not (we need to do a catalog lookup to find the order of elements). Do we want that to be memoized? My inclination is maybe the developer should be in control there but that would also add some complexity there and possibly a (core) dependency. The dependency doesn't strike me as a problem but the design decisions do.
I think composite types should be treated in exactly the same manner as tuples in regular queries. Whenever we look up information to parse the outside-most tuples of query results, do inner tuples/types then too. If it isn't possible to do that at prepare() time, then do it at execute() time. Do not repeat for each row fetched from the result of an execute(), assuming data is homogeneous. This is the simplest way to know that the type definitions we're working with are still valid for the results.
We do not want to add any non-core dependencies. All that should be required to use DBD::Pg is Perl itself, DBI, and DBD::Pg. Any extra dependencies should be optional and user-defined, eg the user of DBD::Pg registers some sort of handler against DBI or DBD::Pg to eg override behavior to memoize for speed, but DBD::Pg has no knowledge of this other than to make the relevant parts possible to override using said generic API.
So I am thinking this way: First draft will probably be in my PGObject framework. Once this is working and stable, I will look at porting the core logic to DBD::Pg.
Sounds like a plan. Test things out externally and only port something simple to DBD::Pg if there's sufficient agreement and lack of opposition, because for example there might have been several ways to design something and we'd want to pick what is most flexible or sufficiently simple. Analogous to how the Perl core has gradually added minimal support for various object or role systems but most details have been kept out of the core.
I won't promise proper Moose handling of things like lazy attributes in this version, but it should be able to handle hashrefs. Does that sound like a reasonable plan?
I don't know what lazy attributes have to do with this, unless you're talking about only deserializing a composite-typed value if it is actually accessed. Either way, DBI/DBD::Pg itself should know nothing about Moose or any other non-core object systems and just represent things with what tools the core provides; your framework can do that as you see fit though.
I don't know if it does this (please tell me), but you know what would be an extremely useful feature in Postgres itself? It is there being a simple fast way to query the database if it had any schema changes (anything DDL does) since it was last asked the question. This could take the form of a LISTEN/NOTIFY of some system-defined channel. If we assume in practice that schema changes are infrequent, then we can safely memoize any schema knowledge we have and know it is still valid until we get such a message saying there was a change, and then we flush the cache and check what we need to know again.
The aforementioned would be widely useful and relatively simple to provide, so if it doesn't exist I think I'll formally propose it to hackers.
Maybe it can be connected to the in-development feature about DDL triggers, or be implemented in terms of such, eg a DDL trigger fires off a NOTIFY. But if it was provided by the system automatically, users won't have to explicitly define triggers / alter the schema in order to have the feature.
-- Darren Duncan
