I just wanted to demonstrate that DBI can't connect with DBI->connect('DBD:MariaDB:...',...), but it can and does, if environment variables are set. I think that should not happen.


DBI's connect method is pure perl. It contains some legacy stuff, but I don't really want to analyse every single line of it. So I just cleared the environment and ran a test:

/tmp>env - perl -MDBI -e 'DBI->connect("DBD:MariaDB","","",{PrintError +=>1})' Can't connect to data source 'DBD:MariaDB' because I can't work out wh +at driver to use (it doesn't seem to contain a 'dbi:driver:' prefix a +nd the DBI_DRIVER env var is not set) at -e line 1.

There is a hint hiding in the error message. The relevant part of the connect() documentation is this, at the very end:

For compatibility with old DBI scripts, the driver can be specified by passing its name as the fourth argument to connect (instead of \%attr):

$dbh = DBI->connect($data_source, $user, $pass, $driver);

In this "old-style" form of connect, the $data_source should not start with "dbi:driver_name:". (If it does, the embedded driver_name will be ignored). Also note that in this older form of connect, the $dbh->{AutoCommit} attribute is undefined, the $dbh->{PrintError} attribute is off, and the old DBI_DBNAME environment variable is checked if DBI_DSN is not defined. Beware that this "old-style" connect will soon be withdrawn in a future version of DBI.

connect() assumes an old-style call, despite being called with an unblessed hash reference as fourth argument, not a string. The old-style call should have a driver name as fourth argument. This smells like a bug.

What happens if $ENV{'DBI_DRIVER'} is set?

/tmp>env - DBI_DRIVER=NON::SENSE perl -MDBI -e 'DBI->connect("DBD:Mari +aDB","","",{PrintError=>1})' install_driver(NON::SENSE) failed: Can't locate DBD/NON/SENSE.pm in @I +NC (you may need to install the DBD::NON::SENSE module) (@INC contain +s: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/ven +dor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/per +l5 .) at (eval 5) line 3. Perhaps a module that DBD::NON::SENSE requires hasn't been fully insta +lled at -e line 1.

Again, DBI->connect() treats a new-style call with \%attr, but an invalid $data_source, as an old-style call.

What happens to the attributes?

/tmp>env - perl -MDBI -e 'print DBI->connect("dbi:SQLite:foo","","",{P +rintError=>1})->{PrintError}' 1 /tmp>env - DBI_DRIVER=SQLite perl -MDBI -e 'print DBI->connect("DBD:Ma +riaDB:foo","","",{PrintError=>1})->{PrintError}' 1 /tmp>env - DBI_DRIVER=SQLite perl -MDBI -e 'print DBI->connect("DBD:Ma +riaDB:foo","","",{})->{PrintError}' 1

PrintError is on, even by default. For "old-style" connects, it should be off. See the quoted documentation above.

What happens for a real old-style call?

/tmp>env - perl -MDBI -e 'print DBI->connect("DBD:MariaDB:foo","",""," +SQLite")->{PrintError}' DBI->connect using 'old-style' syntax is deprecated and will be an err +or in future versions at -e line 1. /tmp>env - perl -MDBI -e 'print defined DBI->connect("DBD:MariaDB:foo" +,"","","SQLite")->{PrintError}' DBI->connect using 'old-style' syntax is deprecated and will be an err +or in future versions at -e line 1. 1 /tmp>env - perl -MDBI -e 'print DBI->connect("DBD:MariaDB:foo","",""," +SQLite")->{PrintError}+0' DBI->connect using 'old-style' syntax is deprecated and will be an err +or in future versions at -e line 1. 0

We get the expected deprecation warning, and PrintError is off (defined and empty).

What happens without \%attr? This:

/tmp>env - perl -MDBI -e 'print DBI->connect("DBD:MariaDB:foo","","")' Can't connect to data source 'DBD:MariaDB:foo' because I can't work ou +t what driver to use (it doesn't seem to contain a 'dbi:driver:' pref +ix and the DBI_DRIVER env var is not set) at -e line 1.

This is acceptable, as there is no fourth argument containing either a driver name or \%attr. So this could be an old-style call. The first argument lacks a "dbi:" prefix, so it must be an old-style call. (Or a confused coder.)


So, an invalid modern-style $data_source confuses connect() to use the fall-back to old-style driver name handling, but at the same time to respect the \%attr parameter and to omit the deprecation warning. I think this is a bug.

Bod's system obviously behaves the same, and someone must have set up DBI environment variables that hide the problem.

My DBI version:

/tmp>perl -MDBI -e 'print $DBI::VERSION' 1.636

I'm a little bit behind (CPAN currently has 1.643), but the relevant parts in DBI.pm are connect() and installl_driver(). The former has some changes related to the password, and keeps a copy of the original $data_source for an error message, but has no other changes. The latter is unchanged. So I think this bug still exists. Unfortunately, I don't have a spare system at hand to test the current version of DBI.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to Re^8: DBI placeholders for spatial data by afoken
in thread DBI placeholders for spatial data by Bod

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.