Re: :PgSQL: More Queestions - Mailing list pgsql-interfaces
From | David Wheeler |
---|---|
Subject | Re: :PgSQL: More Queestions |
Date | |
Msg-id | 289E1136-FC56-11D6-8F04-0003931A964A@wheeler.net Whole thread Raw |
Responses |
Re: :PgSQL: More Queestions
Re: :PgSQL: More Queestions Re: :PgSQL: More Queestions |
List | pgsql-interfaces |
On Tuesday, November 19, 2002, at 03:42 PM, Jeff Urlwin wrote: > You probably only need dTHR to support older, pre-threading perls. I > don't > believe you need the #ifdef, but it can't hurt (except visually in your > code). Okay. What is it? >> >> * In dbd_st_prepare(), is there a way to determine NUM_OF_FIELDS, >> NAME, >> etc. -- that is, before executing the statement? > > Only if you want to fully parse the SQL :) Okay, that makes sense. Thanks. > DBD::ODBC, specifically doesn't handle comments. Reasoning: comments > are > (typically) DB vendor specific and I do not believe that ODBC itself > declares a comment capability. Therefore, it's really not safe for > something like DBD::ODBC to look for them. It may be for you. I do > not see > *much* benefit in adding comments to the queries themselves, within > perl, > but then again, if you had perl read a file of SQL Statements and have > it > generically prepare() and execute() them, then, there's probably value > there. Yeah. We have a Bricolage script that does that, but, as it happens, we were parsing out comments in Perl before passing them to DBD:Pg's prepare(). I didn't notice that there were any tests in DBD::Pg's test suite for comments, either. And it's not documented. So the way I look at it, if I leave the current parser, I'll leave the comment parsing part. But if I change it (as I'm seriously considering, in light of PostgreSQL 7.3's support for prepared statements), I'll probably do no parsing for comments. > In the preparse(), we're looking for placeholders to notify DBI that > we need > specific parameters to execute the query and, in the case of DBD::ODBC, > later notify the ODBC Driver that we are binding parameters (and what > type > they are, VARCHAR, etc). Then the Driver does the binding in whatever > DBMS > specific way it needs to. You may have to do more, as you *are* the > driver. > Note that there is also a way in DBD::ODBC to ignore :foo style > parameters > because some databases use that for syntax in stored procedures or > triggers. > For example, with Oracle a trigger can access :old.column_name or > :new.column_name and DBD::ODBC allows you to turn off treating > :anything as > a bind variable to support that. You may not need that... I understand that the goal is to convert the placeholders from '?' or ':nn' to the PostgreSQL internal version (':pn'). What I'm referring to specifically, however, is this snippet from DBD::Pg: if (in_literal) { /* Check if literal ends but keep quotes in literal */ if (*src == in_literal){ int bs = 0; char *str; str = src-1; /* Back a character. */ while (*(str - bs) == '\\') bs++; if (!(bs & 1)) /* bs isan even number? */ in_literal = 0; } *dest++ = *src++; continue; } in_literal is set when the last character wasn't a placeholder character ('?' or ':') and is either a single or a double quotation mark. So while I understand that one might want to ignore placeholder characters, I don't really understand what the above code is doing. Probably'll be easier for me after I've been looking a C for a while... Maybe it's just too complex, because, looking at DBD::ODBC's dbd_preparse(), the handling of literals in the query seems a good deal more straight-forward (though it doesn't appear to handle '\'' or "\"" -- am I reading that right? > It's going to depend upon what you need to handle. For the most part, > it > shouldn't change after the prepare, but in DBD::ODBC, for example, > it's more > complex because some statements can return multiple result sets. Ah, that makes sense. Not sure if it's an issue for PostgreSQL, but I doesn't appear to be much of an overhead to set it on a per-execute basis... > svp is a temporary reference to obtain a pointer to a scalar value > (scalar > value pointer). You are then casting it to a pointer to a phs_t, which > holds your parameter information. You'll "create" the phs_t instances > when > you preparse the query. In DBD::ODBC, the ftype is queried from the > driver > itself (may go back to the database for information) to determine if > it's > numeric, varchar, etc. The phs_t instance can hold whatever you need > to > track the parameter (type, scale, etc). Some drivers assume > everything is a > varchar and the database itself performs the conversion. > > So: all_params_hv is in your statement handle and you actually put the > information in the all_params_hv hash when you preparse the statement > (and > update it during execute/bind_param). Each "phs_t" represents a > parameter > in the query. The information contained in the phs_t instance comes > from > your parsing the query and, possibly querying the database to > determine the > type of the parameter. > > Also, the all_params_hv is handy in handling the relatively new DBI > attribute ParamValues... Yes, thank you. I'm spending a lot of time right now just studying the code in dbd_preparse() and dbd_st_execute() in both DBD::Pg and DBD::ODBC. I think I'll keep at it until I feel I understand it as well as I can, and then post my thoughts on what to do next. Thanks, David -- David Wheeler AIM: dwTheory david@wheeler.net ICQ: 15726394 http://david.wheeler.net/ Yahoo!: dew7e Jabber: Theory@jabber.org
pgsql-interfaces by date: