Skip to content

Commit 9b30298

Browse files
Copilotmathiasrw
andauthored
Fix SELECT for columns from JOINed inline data to close #1985 (#2339)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]> Co-authored-by: M. Wulff <[email protected]>
1 parent c69ff4f commit 9b30298

File tree

2 files changed

+123
-9
lines changed

2 files changed

+123
-9
lines changed

src/424select.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,15 +244,33 @@ yy.Select.prototype.compileSelect1 = function (query, params) {
244244
"']).length;i++)" +
245245
' for(var k=0;k<cols.length;k++){if (!r.hasOwnProperty(i)) r[i]={}; r[i][colas[k]]=w[i][cols[k]];}';
246246
} else {
247-
ss.push(
248-
"'" +
249-
escapeq(col.as || col.columnid) +
250-
"':p['" +
251-
tbid +
252-
"']['" +
253-
col.columnid +
254-
"']"
255-
);
247+
// For JOINs with inline data where column table is unknown, search all tables
248+
var needsRuntimeResolution =
249+
!col.tableid &&
250+
query.sources.length > 1 &&
251+
(!query.defcols[col.columnid] || query.defcols[col.columnid] === '-');
252+
253+
if (needsRuntimeResolution) {
254+
// Try each table until column is found
255+
var aliases = Object.keys(query.aliases);
256+
var searchExpr = aliases
257+
.map(function (alias) {
258+
return "p['" + alias + "']['" + col.columnid + "']";
259+
})
260+
.join(' ?? ');
261+
262+
ss.push("'" + escapeq(col.as || col.columnid) + "':(" + searchExpr + ')');
263+
} else {
264+
ss.push(
265+
"'" +
266+
escapeq(col.as || col.columnid) +
267+
"':p['" +
268+
tbid +
269+
"']['" +
270+
col.columnid +
271+
"']"
272+
);
273+
}
256274
}
257275
}
258276
} else {

test/test1985.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
if (typeof exports === 'object') {
2+
var assert = require('assert');
3+
var alasql = require('..');
4+
}
5+
6+
describe('Test 1985 - SELECT field on joined tables gives unexpected undefined', function () {
7+
const test = '1985';
8+
9+
it('A) SELECT * works correctly', function () {
10+
const users = [{UserId: '1', UserName: 'User'}];
11+
const orders = [{UserId: '1', Text: 'Order text'}];
12+
13+
const expected = alasql(
14+
`
15+
SELECT *
16+
FROM ? u
17+
JOIN ? o
18+
ON u.UserId = o.UserId`,
19+
[users, orders]
20+
);
21+
22+
// Should have all fields
23+
assert.deepEqual(expected, [
24+
{
25+
UserId: '1',
26+
UserName: 'User',
27+
Text: 'Order text',
28+
},
29+
]);
30+
});
31+
32+
it('B) SELECT specific fields should not return undefined', function () {
33+
const users = [{UserId: '1', UserName: 'User'}];
34+
const orders = [{UserId: '1', Text: 'Order text'}];
35+
36+
const result = alasql(
37+
`
38+
SELECT UserName, Text
39+
FROM ? u
40+
JOIN ? o
41+
ON u.UserId = o.UserId`,
42+
[users, orders]
43+
);
44+
45+
// Both fields should be defined
46+
assert.deepEqual(result, [
47+
{
48+
UserName: 'User',
49+
Text: 'Order text',
50+
},
51+
]);
52+
});
53+
54+
it('C) SELECT single field from second table', function () {
55+
const users = [{UserId: '1', UserName: 'User'}];
56+
const orders = [{UserId: '1', Text: 'Order text'}];
57+
58+
const result = alasql(
59+
`
60+
SELECT Text
61+
FROM ? u
62+
JOIN ? o
63+
ON u.UserId = o.UserId`,
64+
[users, orders]
65+
);
66+
67+
// Text field should be defined
68+
assert.deepEqual(result, [
69+
{
70+
Text: 'Order text',
71+
},
72+
]);
73+
});
74+
75+
it('D) SELECT with table aliases', function () {
76+
const users = [{UserId: '1', UserName: 'User'}];
77+
const orders = [{UserId: '1', Text: 'Order text'}];
78+
79+
const result = alasql(
80+
`
81+
SELECT u.UserName, o.Text
82+
FROM ? u
83+
JOIN ? o
84+
ON u.UserId = o.UserId`,
85+
[users, orders]
86+
);
87+
88+
// Both fields should be defined
89+
assert.deepEqual(result, [
90+
{
91+
UserName: 'User',
92+
Text: 'Order text',
93+
},
94+
]);
95+
});
96+
});

0 commit comments

Comments
 (0)