Skip to content

Commit ce51eb6

Browse files
committed
Merge pull request brianc#168 from twg/add_postgres_array_operators
Add Postgres array operators `<@`, `@>`, `&&`.
2 parents f825d75 + 063cda0 commit ce51eb6

3 files changed

Lines changed: 66 additions & 0 deletions

File tree

lib/dialect/postgres.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,24 @@ Postgres.prototype.visitSlice = function(slice) {
482482
return [text];
483483
};
484484

485+
Postgres.prototype.visitContains = function(contains) {
486+
var text = this.visit(contains.value);
487+
text += ' @> ' + this.visit(contains.set);
488+
return [text];
489+
};
490+
491+
Postgres.prototype.visitContainedBy = function(containedBy) {
492+
var text = this.visit(containedBy.value);
493+
text += ' <@ ' + this.visit(containedBy.set);
494+
return [text];
495+
};
496+
497+
Postgres.prototype.visitOverlap = function(overlap) {
498+
var text = this.visit(overlap.value);
499+
text += ' && ' + this.visit(overlap.set);
500+
return [text];
501+
};
502+
485503
Postgres.prototype.visitQuery = function(queryNode) {
486504
this._queryNode = queryNode;
487505
// need to sort the top level query nodes on visitation priority

lib/node/valueExpression.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ var ValueExpressionMixin = function() {
7777
return new SliceNode(this.toNode(), processParams(start), processParams(end));
7878
};
7979

80+
var containsMethod = function(set) {
81+
return new ContainsNode(this.toNode(), processParams(set));
82+
};
83+
84+
var containedByMethod = function(set) {
85+
return new ContainedByNode(this.toNode(), processParams(set));
86+
};
87+
88+
var overlapMethod = function(set) {
89+
return new OverlapNode(this.toNode(), processParams(set));
90+
};
91+
8092
var castMethod = function(dataType) {
8193
return new CastNode(this.toNode(), dataType);
8294
};
@@ -138,6 +150,9 @@ var ValueExpressionMixin = function() {
138150
notIn : notInMethod,
139151
between : ternaryMethod('BETWEEN', 'AND'),
140152
at : atMethod,
153+
contains : binaryMethod('@>'),
154+
containedBy : binaryMethod('<@'),
155+
overlap : binaryMethod('&&'),
141156
slice : sliceMethod,
142157
cast : castMethod,
143158
descending : orderMethod('DESC'),

test/dialects/array-tests.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,39 @@ Harness.test({
1616
params: ['nodejs']
1717
});
1818

19+
Harness.test({
20+
query: post.select(
21+
post.tags.contains(Sql.array('nodejs', 'js'))
22+
),
23+
pg: {
24+
text : 'SELECT ("post"."tags" @> ARRAY[$1, $2]) FROM "post"',
25+
string: 'SELECT ("post"."tags" @> ARRAY[\'nodejs\', \'js\']) FROM "post"'
26+
},
27+
params: ['nodejs', 'js']
28+
});
29+
30+
Harness.test({
31+
query: post.select(
32+
post.tags.containedBy(Sql.array('nodejs', 'js'))
33+
),
34+
pg: {
35+
text : 'SELECT ("post"."tags" <@ ARRAY[$1, $2]) FROM "post"',
36+
string: 'SELECT ("post"."tags" <@ ARRAY[\'nodejs\', \'js\']) FROM "post"'
37+
},
38+
params: ['nodejs', 'js']
39+
});
40+
41+
Harness.test({
42+
query: post.select(
43+
post.tags.overlap(Sql.array('nodejs', 'js'))
44+
),
45+
pg: {
46+
text : 'SELECT ("post"."tags" && ARRAY[$1, $2]) FROM "post"',
47+
string: 'SELECT ("post"."tags" && ARRAY[\'nodejs\', \'js\']) FROM "post"'
48+
},
49+
params: ['nodejs', 'js']
50+
});
51+
1952
Harness.test({
2053
query: post.select(post.tags.slice(2,3)),
2154
pg: {

0 commit comments

Comments
 (0)