Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question on 'SQL' tracing

2 views
Skip to first unread message

Martin Evans

unread,
May 12, 2008, 11:57:29 AM5/12/08
to dbi...@perl.org
After seeing the recent posting by Greg Sabino Mullane in subject "Log
DBI query and values with placeholders" I realised there was something
else DBD::ODBC was out of date with - tracing.

DBD::ODBC does not implement its own trace flags but neither does it
react to 'SQL' tracing. If I set trace('SQL') I can see the TraceLevel
is set to 256 and I can find:

sub parse_trace_flag {
my ($h, $name) = @_;
# 0xddDDDDrL (driver, DBI, reserved, Level)
return 0x00000100 if $name eq 'SQL';
return;
}

in DBI. So to test if 'SQL' is enabled we:

if *DBIc_TRACE_LEVEL(imp_xxh) & 256) {blah;}

Is that correct? No constant I am missing?

Martin
--
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Martin Evans

unread,
May 12, 2008, 12:15:34 PM5/12/08
to dbi...@perl.org

and also, how do I set this in Perl:

$dbh->{TraceLevel} = 'SQL|3';

DBI::db=HASH(0x82ba9d4) trace level set to 0x100/3 (DBI @ 0x0/0) in
DBI 1.601-ithread (pid 4574)

$dbh->prepare(xxxx)
here when I examine DBIc_TRACE_LEVEL(imp_dbh) it is 3!

Similarly if I use:

$h->trace($h->parse_trace_flags('SQL'))

What am I doing wrong? I'm a little confused by this since DBD::Pg seems
to expect 'SQL' to work.

Tim Bunce

unread,
May 12, 2008, 6:11:44 PM5/12/08
to Martin Evans, dbi...@perl.org
On Mon, May 12, 2008 at 05:15:34PM +0100, Martin Evans wrote:
> Martin Evans wrote:
>> After seeing the recent posting by Greg Sabino Mullane in subject "Log DBI
>> query and values with placeholders" I realised there was something else
>> DBD::ODBC was out of date with - tracing.
>>
>> DBD::ODBC does not implement its own trace flags but neither does it react
>> to 'SQL' tracing. If I set trace('SQL') I can see the TraceLevel is set to
>> 256 and I can find:
>>
>> sub parse_trace_flag {
>> my ($h, $name) = @_;
>> # 0xddDDDDrL (driver, DBI, reserved, Level)
>> return 0x00000100 if $name eq 'SQL';
>> return;
>> }
>>
>> in DBI. So to test if 'SQL' is enabled we:
>>
>> if *DBIc_TRACE_LEVEL(imp_xxh) & 256) {blah;}
>
> and also, how do I set this in Perl:
>
> $dbh->{TraceLevel} = 'SQL|3';
>
> DBI::db=HASH(0x82ba9d4) trace level set to 0x100/3 (DBI @ 0x0/0) in DBI
> 1.601-ithread (pid 4574)
>
> $dbh->prepare(xxxx)
> here when I examine DBIc_TRACE_LEVEL(imp_dbh) it is 3!
>
> Similarly if I use:
>
> $h->trace($h->parse_trace_flags('SQL'))
>
> What am I doing wrong? I'm a little confused by this since DBD::Pg seems to
> expect 'SQL' to work.

I presume you've read http://search.cpan.org/~timb/DBI/DBI.pm#TRACING

What's missing is an equivalent section in the DBI::DBD docs.
At the moment there's just a passing mention at the end of an unrelated section:
http://search.cpan.org/~timb/DBI/lib/DBI/DBD.pm#The_dbd_drv_error_method

The short answer is that DBIc_TRACE_LEVEL only gives you the 'trace
level' not the 'trace flags' (which you can get via DBIc_TRACE_FLAGS).

You probably want to use the fancy DBIc_TRACE macros though...

Hopefully this chunk of DBIXS.h with help:

#define DBIc_TRACE_LEVEL_MASK 0x0000000F
#define DBIc_TRACE_FLAGS_MASK 0xFFFFFF00
#define DBIc_TRACE_SETTINGS(imp) (DBIc_DBISTATE(imp)->debug)
#define DBIc_TRACE_LEVEL(imp) (DBIc_TRACE_SETTINGS(imp) & DBIc_TRACE_LEVEL_MASK)
#define DBIc_TRACE_FLAGS(imp) (DBIc_TRACE_SETTINGS(imp) & DBIc_TRACE_FLAGS_MASK)
/* DBIc_TRACE_MATCHES(this, crnt): true if this 'matches' (is within) crnt
DBIc_TRACE_MATCHES(foo, DBIc_TRACE_SETTINGS(imp))
*/
#define DBIc_TRACE_MATCHES(this, crnt) \
( ((crnt & DBIc_TRACE_LEVEL_MASK) >= (this & DBIc_TRACE_LEVEL_MASK)) \
|| ((crnt & DBIc_TRACE_FLAGS_MASK) & (this & DBIc_TRACE_FLAGS_MASK)) )
/* DBIc_TRACE: true if flags match & DBI level>=flaglevel, or if DBI level>level
This is the main trace testing macro to be used by drivers.
(Drivers should define their own DBDtf_* macros for the top 8 bits: 0xFF000000)
DBIc_TRACE(imp, 0, 0, 4) = if level >= 4
DBIc_TRACE(imp, DBDtf_FOO, 2, 4) = if tracing DBDtf_FOO & level>=2 or level>=4
DBIc_TRACE(imp, DBDtf_FOO, 2, 0) = as above but never trace just due to level
*/
#define DBIc_TRACE(imp, flags, flaglevel, level) \
( (flags && (DBIc_TRACE_FLAGS(imp) & flags) && (DBIc_TRACE_LEVEL(imp) >= flaglevel)) \
|| (level && DBIc_TRACE_LEVEL(imp) >= level) )

Patches to DBI::DBD very welcome.

Tim.

Martin Evans

unread,
May 13, 2008, 7:05:31 AM5/13/08
to dbi...@perl.org

Thanks Tim,

I've got the gist of that now and implemented in DBD::ODBC.
Patch for DBI::DBD on its way in the next few days.

0 new messages