Subject: | FW: Class::Storage::Oracle::Generic.pm |
Date: | Thu, 5 May 2011 16:45:07 +0100 |
To: | "bug-DBIx-Class [...] rt.cpan.org" <bug-DBIx-Class [...] rt.cpan.org> |
From: | Duncan Garland <Duncan.Garland [...] motortrak.com> |
From: Duncan Garland
Sent: 05 May 2011 16:40
To: 'bug-DBIx-Class@rt.cpan.org.'
Subject: Class::Storage::Oracle::Generic.pm
Hi,
I think there's a bug in this module.
We've set up our system so that there are two users, each with their own schema, on the same Oracle instance. One is motrak and one is mbfl2_training.
The config file tells it which user to log in as:
mbfl2.conf:
<Model::DB>
schema_class MBFL2SCHEMA
<connect_info>
dsn dbi:Oracle:ORCL
user motrak
password XXXXXXXXXXX
on_connect_do ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
on_connect_do ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
LongReadLen 2000000
</connect_info>
</Model::DB>
mbfl2_training.conf:
<Model::DB>
schema_class MBFL2SCHEMA
<connect_info>
dsn dbi:Oracle:ORCL
user mbfl2_training
password XXXXXXXXXXXXXXX
on_connect_do ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
on_connect_do ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'
LongReadLen 2000000
</connect_info>
</Model::DB>
This has been working quite well, but we've suddenly started getting insert errors on one table in particular:
[05/May/2011:15:27:22 +0100] WARN:www.mbfl2-training.com:[FCGI: /usr/local/etc/httpd/fcgi/catalyst/mbfl2/script/mbfl2_training_fastcgi.pl]: [error] DBIx::Class::ResultSet::create(): DBI Exception: DBD::Oracle::db selectrow_array failed: ORA-00942: table or view does not exist (DBD ERROR: error possibly near <*> indicator at char 14 in 'SELECT MOTRAK.<*>s_mbfl2_dealer_package_models.currval FROM DUAL') [for Statement "SELECT MOTRAK.s_mbfl2_dealer_package_models.currval FROM DUAL"] at /usr/local/etc/httpd/fcgi/catalyst/mbfl2/script/../lib/mbfl2/Controller/DealerAdmin.pm line 675
This is bizarre because the user should be logged in as mbfl2_training and, as far as I can tell, is logged in as mbfl2_training. MOTRAK.s_mbfl2_dealer_package_models exists but the user does not have access to it. He should be accessing MBFL2_TRAINING.s_mbfl2_dealer_package_models or just s_mbfl2_dealer_package_models.
The problem seems to be in Generic:: _dbh_get_autoinc_seq(). It derives the schema name by selecting the trigger name and the owner name from all_triggers. All_triggers returns triggers which belong to both MOTRAK and MBFL2_TRAINING and which contain the sequence s_mbfl2_dealer_package_models.
The MOTRAK trigger is returned first, so the schema is set incorrectly. When I change the statement to use USER_TRIGGER is works.
MBFL2_TRAINING has select access on some of MOTRAK's tables (and thus their triggers) because I copied some data across a couple of month ago. If I revoke the select access, I think the original code (using ALL_TRIGGERS) will work.
However, I have worked on systems in the past where the user genuinely needs access to two tables with the same name. For example, on development systems it is common to read from a central set of tables and create a local copy of any tables which need to be written to. Oracle will correctly select the table in the current schema in preference to one in another schema, but your code might not.
I hope this feedback is useful.
All the best.
Duncan