Skip to content

Commit

Permalink
Revert prematurely merged default insert support for Oracle (see below)
Browse files Browse the repository at this point in the history
Note: the incorrect implementation is not the fault of the original submitter
(who can not be expected to know the vagaries of the execution path) nor is
the fault of the original reviewer (who can not be expected to remember said
vagaries for a storage they do not even use). I do not have recommendations
on how to avoid this situation in the future.

It is correct that the particular problem can not be solved on the level of
SQLMaker::Oracle like it was solved for MySQL. However the current fix applies
the default-on-empty way too early in the call stack - there is a lot of stuff
happening between where we would ideally be applying the workaround and the
current application site. With an Oracle storage the call-stack is roughly the
following:

  ( ... non-storage code )
    -> ::Storage::DBI::insert
X     -> ::Storage::DBI::_prefetch_autovalues
X       -> (loop over) ::Storage::DBI::Oracle::Generic::_sequence_fetch
X     -> determine if autoincs are accounted for
?     -> assemble INSERT RETURNING container
      -> ::Storage::DBI::_execute
        -> ::Storage::DBI::Oracle::Generic::_prep_for_execute
        -> ::Storage::DBI::_prep_for_execute
          -> ::Storage::DBI::_gen_sql_bind
            -> ::SQLMaker::Oracle::insert(...)

Setting up the "missing" default so early definitely affects the points marked
with X and possibly affects the code marked with ?. The issues that would come
out of this range from obvious failure modes to "this will be easily broken by
a future reshuffle" gut feeling.

The patch therefore needs reworking adding the extra pieces of logic either in
a new _gen_sql_bind hook, or at the very least in the already existing
conditional at the start of ::Storage::DBI::Oracle::Generic::_prep_for_execute
(though a hook of _gen_sql_bind is preferable).

Additionally the test needs to be expanded to exercise the case of pre-existing
test cases that trigger _prefetch_autovalue (the tests involving the source
SequenceTest in t/73oracle.t)

And lastly an explicit exception should be added to SQLMaker::Oracle::insert
to catch future changes to any code higher up, so that a refactor will not
silently end up calling SQLMaker::Oracle::insert with an empty insert-list,
throwing everything back to square one.

This commit reverts the following two patches, with the intention to merge a
fixed-up version shortly:

- 236b59c
- 1af6b96
  • Loading branch information
ribasushi committed Oct 22, 2014
1 parent cf52a9a commit f813551
Show file tree
Hide file tree
Showing 5 changed files with 0 additions and 27 deletions.
1 change: 0 additions & 1 deletion AUTHORS
Expand Up @@ -105,7 +105,6 @@ jshirley: J. Shirley <jshirley@gmail.com>
kaare: Kaare Rasmussen
kd: Kieren Diment <diment@gmail.com>
konobi: Scott McWhirter <konobi@cpan.org>
Lasse Makholm <lasse@unity3d.com>
lejeunerenard: Sean Zellmer <sean@lejeunerenard.com>
littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
lukes: Luke Saunders <luke.saunders@gmail.com>
Expand Down
1 change: 0 additions & 1 deletion Changes
@@ -1,7 +1,6 @@
Revision history for DBIx::Class

* Fixes
- Fix $rs->create() with no values on Oracle
- Silence with_deferred_fk_checks() warning on PostgreSQL 9.4

* Misc
Expand Down
15 changes: 0 additions & 15 deletions lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
Expand Up @@ -115,21 +115,6 @@ sub deployment_statements {
$self->next::method($schema, $type, $version, $dir, $sqltargs, @rest);
}

sub insert {
my ($self, $source, $to_insert) = @_;

# Oracle does not understand INSERT INTO ... DEFAULT VALUES syntax
# Furthermore it does not have any way to insert without specifying any columns
# We can't fix this in SQLMaker::Oracle because it doesn't know which column to add to the statement
unless (%$to_insert)
{
my ($col) = $source->columns;
$to_insert = { $col => \'DEFAULT' };
}

return $self->next::method($source, $to_insert);
}

sub _dbh_last_insert_id {
my ($self, $dbh, $source, @columns) = @_;
my @ids = ();
Expand Down
3 changes: 0 additions & 3 deletions t/60core.t
Expand Up @@ -576,9 +576,6 @@ lives_ok (sub { my $newlink = $newbook->link}, "stringify to false value doesn't
{
my $new_artist = $schema->resultset('Artist')->new({});
isa_ok( $new_artist, 'DBIx::Class::Row', '$rs->new gives a row object' );
lives_ok { $new_artist->insert() } 'inserting without specifying any columns works';
$new_artist->discard_changes;
$new_artist->delete;
}

# make sure we got rid of the compat shims
Expand Down
7 changes: 0 additions & 7 deletions t/73oracle.t
Expand Up @@ -201,13 +201,6 @@ sub _run_tests {
like ($seq, qr/\.${q}artist_pk_seq${q}$/, 'Correct PK sequence selected for sqlt-like trigger');
}

lives_ok {
$new = $schema->resultset('Artist')->create({});
$new->discard_changes;
ok $new->artistid, 'Created row has id'
} 'Create with empty hashref works';


# test LIMIT support
for (1..6) {
$schema->resultset('Artist')->create({ name => 'Artist ' . $_ });
Expand Down

0 comments on commit f813551

Please sign in to comment.