Skip to content

Commit 5566e04

Browse files
author
Dorian Johnson
committed
Add support for accessing PG composite types (UDT)
As per http://www.postgresql.org/docs/9.4/static/rowtypes.html#AEN7836 No attempt at supporting these in UPDATE is attempted here.
1 parent 2987e13 commit 5566e04

5 files changed

Lines changed: 75 additions & 1 deletion

File tree

lib/dialect/postgres.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ Postgres.prototype.visitColumn = function(columnNode) {
654654
txt.push('DISTINCT(');
655655
}
656656
}
657-
if(!inInsertUpdateClause && !this.visitingReturning && !this._visitingCreate && !this._visitingAlter) {
657+
if(!inInsertUpdateClause && !this.visitingReturning && !this._visitingCreate && !this._visitingAlter && !columnNode.subfieldContainer) {
658658
if(table.alias) {
659659
txt.push(this.quote(table.alias));
660660
} else {
@@ -686,6 +686,9 @@ Postgres.prototype.visitColumn = function(columnNode) {
686686
}
687687
}
688688
else {
689+
if (columnNode.subfieldContainer) {
690+
txt.push('(' + this.visitColumn(columnNode.subfieldContainer) + ').');
691+
}
689692
txt.push(this.quote(columnNode.name));
690693
}
691694
if(closeParen) {

lib/node/column.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ module.exports = Node.define({
1919
this.primaryKey = config.primaryKey;
2020
this.notNull = config.notNull;
2121
this.references = config.references;
22+
// If subfieldContainer is present, this is a subfield and subfieldContainer
23+
// is the parent Column
24+
this.subfieldContainer = config.subfieldContainer;
25+
this.subfields = config.subfields;
2226
this.autoGenerated = !!config.autoGenerated;
2327
},
2428
as: function(alias) {

lib/table.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ Table.prototype.createColumn = function(col) {
6767

6868
col.table = this;
6969
col = new Column(col);
70+
71+
// Load subfields from array into an object of form name: Column
72+
if(util.isArray(col.subfields)) {
73+
col.subfields = lodash.chain(col.subfields)
74+
.map(lodash.bind(function (subfield) {
75+
return [subfield, new Column({
76+
table: this,
77+
subfieldContainer: col,
78+
name: subfield
79+
})]
80+
}, this))
81+
.object()
82+
.value()
83+
}
7084
}
7185

7286
return col;

test/dialects/subfield-tests.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
var Harness = require('./support');
4+
var customer = Harness.defineCustomerCompositeTable();
5+
var Sql = require('../../lib').setDialect('postgres');
6+
7+
Harness.test({
8+
query: customer.select(customer.info.subfields.age),
9+
pg: {
10+
text : 'SELECT ("customer"."info")."age" FROM "customer"',
11+
string: 'SELECT ("customer"."info")."age" FROM "customer"'
12+
},
13+
params: []
14+
});
15+
16+
17+
Harness.test({
18+
query: customer.select(customer.info.subfields.age.as('years')),
19+
pg: {
20+
text : 'SELECT ("customer"."info")."age" AS "years" FROM "customer"',
21+
string: 'SELECT ("customer"."info")."age" AS "years" FROM "customer"'
22+
},
23+
params: []
24+
});
25+
26+
Harness.test({
27+
query: customer.select(customer.id).where(customer.info.subfields.salary.equals(10)),
28+
pg: {
29+
text : 'SELECT "customer"."id" FROM "customer" WHERE (("customer"."info")."salary" = $1)',
30+
string: 'SELECT "customer"."id" FROM "customer" WHERE (("customer"."info")."salary" = 10)'
31+
},
32+
params: [10]
33+
});
34+
35+
Harness.test({
36+
query: customer.select(customer.info.subfields.name.distinct()),
37+
pg: {
38+
text : 'SELECT DISTINCT(("customer"."info")."name") FROM "customer"',
39+
string: 'SELECT DISTINCT(("customer"."info")."name") FROM "customer"'
40+
},
41+
params: []
42+
});

test/dialects/support.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ module.exports = {
9393
});
9494
},
9595

96+
// This table defines the customer attributes as a composite field
97+
defineCustomerCompositeTable: function() {
98+
return Table.define({
99+
name: 'customer',
100+
columns: {
101+
id: {},
102+
info: {subfields: ['name', 'age', 'salary']}
103+
}
104+
});
105+
},
106+
96107
defineCustomerAliasTable: function() {
97108
return Table.define({
98109
name: 'customer',

0 commit comments

Comments
 (0)