Skip to content
This repository

Fixed problem with Postgres 9.1 Writeable CTE's #31

Merged
merged 1 commit into from almost 2 years ago

3 participants

jwkoelewijn Dan Kubb Dirkjan Bussink
jwkoelewijn

Problem solved by rewriting code that checked whether the
query should be executed using PreparedStatement#executeQuery() or
using PreparedStatement#executeUpdate().
Original code checked for the existence of the word 'RETURNING',
where this is perfectly possible in Postgres 9.1, where a writable
CTE can be created with the word RETURNING in it, while not actually
returning any values (i.e. #executeQuery() should have been called)

Fix is to use the PreparedStatement#execute(), which returns a
boolean that indicates whether a result was returned, or that
existing rows were affected. Based on the value of this boolean
either a ResultSet is requested or the number of affected rows
is retrieved.

jwkoelewijn Fixed problem with Postgres 9.1 Writeable CTE's
Problem solved by rewriting code that checked whether the
query should be executed using PreparedStatement#executeQuery() or
using PreparedStatement#executeUpdate().
Original code checked for the existence of the word 'RETURNING',
where this is perfectly possible in Postgres 9.1, where a writable
CTE can be created with the word RETURNING in it, while not actually
returning any values (i.e. #executeQuery() should have been called)

Fix is to use the PreparedStatement#execute(), which returns a
boolean that indicates whether a result was returned, or that
existing rows were affected. Based on the value of this boolean
either a ResultSet is requested or the number of affected rows
is retrieved.
1a974de
Dirkjan Bussink dbussink merged commit 246b665 into from May 10, 2012
Dirkjan Bussink dbussink closed this May 10, 2012
Dan Kubb
Owner
dkubb commented May 10, 2012

@dbussink looks like there's a spec failure for DO: http://travis-ci.org/#!/datamapper/do/jobs/1295368 .. not sure if it was caused by this commit, but I figured I'd mention it just in case.

jwkoelewijn

@dkubb This spec failure is unrelated, but I am checking it nonetheless :)

Dan Kubb
Owner
dkubb commented May 11, 2012

@jwkoelewijn thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

May 10, 2012
jwkoelewijn Fixed problem with Postgres 9.1 Writeable CTE's
Problem solved by rewriting code that checked whether the
query should be executed using PreparedStatement#executeQuery() or
using PreparedStatement#executeUpdate().
Original code checked for the existence of the word 'RETURNING',
where this is perfectly possible in Postgres 9.1, where a writable
CTE can be created with the word RETURNING in it, while not actually
returning any values (i.e. #executeQuery() should have been called)

Fix is to use the PreparedStatement#execute(), which returns a
boolean that indicates whether a result was returned, or that
existing rows were affected. Based on the value of this boolean
either a ResultSet is requested or the number of affected rows
is retrieved.
1a974de
This page is out of date. Refresh to see the latest.
7  do_jdbc/src/main/java/data_objects/Command.java
@@ -147,10 +147,11 @@ public IRubyObject execute_non_query(IRubyObject[] args) {
147 147
 
148 148
             long startTime = System.currentTimeMillis();
149 149
             if (usePS) {
150  
-                if (sqlText.contains("RETURNING") && !hasReturnParam) {
151  
-                    keys = sqlStatement.executeQuery();
  150
+                boolean hasResult = sqlStatement.execute();
  151
+                if (hasResult) {
  152
+                    keys = sqlStatement.getResultSet();
152 153
                 } else {
153  
-                    affectedCount = sqlStatement.executeUpdate();
  154
+                    affectedCount = sqlStatement.getUpdateCount();
154 155
                 }
155 156
             } else {
156 157
                 sqlSimpleStatement.execute(sqlText);
36  do_postgres/spec/command_spec.rb
@@ -6,4 +6,40 @@
6 6
 describe DataObjects::Postgres::Command do
7 7
   it_should_behave_like 'a Command'
8 8
   it_should_behave_like 'a Command with async'
  9
+
  10
+  describe 'query with RETURNING while not returning result' do
  11
+    before do
  12
+      @connection = DataObjects::Connection.new(CONFIG.uri)
  13
+      @select_command = @connection.create_command("SELECT name FROM users WHERE id = 900")
  14
+      @upsert_command = @connection.create_command("
  15
+          WITH upsert AS
  16
+            (UPDATE users SET name = ? WHERE id = 900 RETURNING id)
  17
+          INSERT INTO users (id, name)
  18
+          SELECT 900, 'dbussink' WHERE NOT EXISTS (SELECT 1 FROM upsert)")
  19
+    end
  20
+
  21
+    after do
  22
+      @connection.close
  23
+    end
  24
+
  25
+    it "should work with a writable CTE acting as an Upsert" do
  26
+      reader = @select_command.execute_reader
  27
+      reader.to_a.size.should == 0
  28
+      reader.close
  29
+
  30
+      @upsert_command.execute_non_query('jwkoelewijn')
  31
+
  32
+      reader = @select_command.execute_reader
  33
+      reader.next!
  34
+      reader.values[0].should == 'dbussink'
  35
+      reader.close
  36
+
  37
+      @upsert_command.execute_non_query('jwkoelewijn')
  38
+
  39
+      reader = @select_command.execute_reader
  40
+      reader.next!
  41
+      reader.values[0].should == 'jwkoelewijn'
  42
+      reader.close
  43
+    end
  44
+  end
9 45
 end
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.