Skip to content

Commit 137fd5c

Browse files
authored
Merge pull request #19 from dchymko/master
Add ability to use SQL functions or operators in the `DO UPDATE` clause
2 parents a2da64b + 0d0bab3 commit 137fd5c

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

postgres-tests.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ describe('Postgres extension for SQLBricks', function() {
177177
"INSERT INTO \"user\" (name) VALUES ('Alex') ON CONFLICT DO UPDATE SET name = EXCLUDED.name")
178178
})
179179

180+
it('should make upsert with SQL function', function() {
181+
assert.equal(insert('user', {name: 'Alex'})
182+
.onConflict().doUpdate().set(sql('name = coalesce(EXCLUDED.name, $1)', "Alex")).toString(),
183+
"INSERT INTO \"user\" (name) VALUES ('Alex') ON CONFLICT DO UPDATE SET name = coalesce(EXCLUDED.name, 'Alex')")
184+
})
185+
180186
it('should filter update', function() {
181187
assert.equal(insert('user', {name: 'Alex'}).onConflict().doUpdate().where(sql('is_active')).toString(),
182188
"INSERT INTO \"user\" (name) VALUES ('Alex') ON CONFLICT DO UPDATE SET name = EXCLUDED.name WHERE is_active")

postgres.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@
121121
this.where = this.and = function () {
122122
return this._addExpression(arguments, '_doUpdateWhere');
123123
}
124+
this.set = this.and = function() {
125+
return this._addExpression(arguments, '_doUpdateSet');
126+
}
124127
return this;
125128
}
126129

@@ -133,8 +136,14 @@
133136
);
134137
Insert.defineClause('onConstraint', function(opts) { if (this._onConstraint) return `ON CONSTRAINT ${this._onConstraint}`; },
135138
{after: 'onConflict'});
139+
Insert.defineClause(
140+
'doUpdateSet',
141+
function (opts) { if (this._doUpdateSet) return `DO UPDATE SET ${sql._handleExpression(this._doUpdateSet, opts)}`; },
142+
{after: 'onConstraint'}
143+
);
136144
Insert.defineClause('doNothing', function(opts) { if (this._doNothing) return `DO NOTHING`; }, {after: 'onConstraint'});
137145
Insert.defineClause('doUpdate', function(opts) {
146+
if(this._doUpdateSet) return;
138147
if(!this._doUpdate) return;
139148

140149
var columns = this._doUpdate;
@@ -144,7 +153,7 @@
144153
var col = sql._handleColumn(col, opts);
145154
return col + ' = EXCLUDED.' + col;
146155
}).join(', ');
147-
}, {after: 'onConstraint'}
156+
}, {after: 'doUpdateSet'}
148157
);
149158
Insert.defineClause(
150159
'doUpdateWhere',

readme.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ sql.insert('user', {name: 'Alex', age: 34})
8181
// INSERT INTO "user" (name) VALUES ('Alex', 34)
8282
// ON CONFLICT (name)
8383
// DO UPDATE SET name = EXCLUDED.name, age = EXCLUDED.age
84+
85+
// manipulate the data in the `DO UPDATE`:
86+
sql.insert('user', {name: 'Alex', age: 34})
87+
.onConflict('name').doUpdate()
88+
.set(sql('name = coalesce(EXCLUDED.name, $1), age = $2 + 10', t1, t2))
89+
// INSERT INTO "user" (name) VALUES ('Alex', 34)
90+
// ON CONFLICT (name)
91+
// DO UPDATE SET name = coalesce(EXCLUDED.name, $3), age = $4 + 10
8492
```
8593

8694
Other clauses such as `DO NOTHING`, `ON CONSTRAINT` and `WHERE` are

0 commit comments

Comments
 (0)