Skip to content

Commit

Permalink
Don't emit "FOR UPDATE .." On SQLite
Browse files Browse the repository at this point in the history
Rather than just ignore it like it does for other things it doesn't
implement, SQLite throws an error with 'FOR UPDATE' on a select
statement.

This just over-rides with an implementation that doesn't emit anything
if there is a '.for'.

The test just checks it doesn't explode with .skip-update, I've
confirmed the SQL generated for both Pg and SQLite visually.
  • Loading branch information
jonathanstowe authored and FCO committed Apr 15, 2024
1 parent 715ae29 commit 20afb07
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
24 changes: 15 additions & 9 deletions lib/Red/Driver/CommonSQL.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -514,18 +514,24 @@ multi method translate(Red::AST::Select $ast, $context?, :$gambi) {
"\nOFFSET $_" with $offset
}{
do with $ast.for // $*red-subselect-for {
"\nFOR {
when UPDATE {
"UPDATE"
}
when SKIP_LOCKED {
"UPDATE SKIP LOCKED"
}
}"
self.translate($_);
}
}" => @bind
}

multi method translate(Red::LockType $lock-type --> Str ) {
given $lock-type {
"\nFOR {
when UPDATE {
"UPDATE"
}
when SKIP_LOCKED {
"UPDATE SKIP LOCKED"
}
}"
}
}

multi method translate(Red::AST::StringFunction $_, $context?) {
self.translate: .default-implementation, $context
}
Expand Down Expand Up @@ -805,7 +811,7 @@ multi method translate(Red::Column $_, "column-default") {
my ($str, @bind);
:(:key($str), :value(@bind)) := self.translate: do given .default.($_) {
do if $_ !~~ Red::AST {
.&ast-value
.&ast-value
} else {
$_
}
Expand Down
4 changes: 4 additions & 0 deletions lib/Red/Driver/SQLite.rakumod
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ multi method translate(Red::AST::Value $_ where { .type ~~ Pair and .value.key ~

multi method translate(Red::AST::Minus $ast, "multi-select-op") { "EXCEPT" => [] }

multi method translate(Red::LockType $lock-type --> Str ) {
''
}

method comment-on-same-statement { True }

#multi method default-type-for(Red::Column $ where .attr.type ~~ Mu --> Str:D) {"varchar(255)"}
Expand Down
25 changes: 25 additions & 0 deletions t/81-resultset-skip-locked.rakutest
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use Test;
use Red;

model Foo {
has Int $.bar is serial;
has Str $.foo is column;
}

my $*RED-DEBUG = $_ with %*ENV<RED_DEBUG>;
my $*RED-DEBUG-RESPONSE = $_ with %*ENV<RED_DEBUG_RESPONSE>;
my @conf = (%*ENV<RED_DATABASE> // "SQLite").split(" ");
my $driver = @conf.shift;
my $*RED-DB = database $driver, |%( @conf.map: { do given .split: "=" { .[0] => val .[1] } } );

schema(Foo).drop;
Foo.^create-table;

Foo.^create: foo => "babaa";

my @rows;
lives-ok { @rows = Foo.^rs.skip-locked.all }, 'with skip-locked';

is @rows.elems, 1, "got the right number of rows";

done-testing

0 comments on commit 20afb07

Please sign in to comment.