Skip to content

Commit dd08758

Browse files
akhaneevmathiasrw
authored andcommitted
Fix for issue with a chain of OUTER JOINs (#1105)
* Added test for OUTER JOIN with missing ids * Outer Join doesn't replace ids with undefined for not matching rows * Refactored a little bit * Fixed issue with multiple tables OUTER JOINER
1 parent ac380c9 commit dd08758

File tree

9 files changed

+181
-129
lines changed

9 files changed

+181
-129
lines changed

.github/CONTRIBUTING.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ Inputs to improvement? [Open an issue](https://github.com/agershun/alasql/issues
99

1010
**All contributions are much welcome and greatly appreciated(!)**
1111

12-
1. Fork the repo here on Github
13-
0. Clone your forked repo and install dependencies `git clone https://github.com/MYUSERNAME/alasql/ && cd alasql && npm install`
14-
0. Please work with the code from the develop branch `git checkout develop`
15-
0. Add a test for the issue: Copy `test/test000.js` and replace `000` with a new number.
16-
0. Impelement a test that reflects the issue.
17-
0. Run `npm test` to verify only the new test fails
18-
0. Implement your contributions in `src/`
19-
0. Run `npm test` and verify all tests are OK
20-
0. Commit changes to git and push to your forked repo
21-
0. Click "Create Pull-request" when looking at your forked repo on Github
12+
- Fork the repo here on Github
13+
- Clone your forked repo and install dependencies `git clone https://github.com/MYUSERNAME/alasql/ && cd alasql && npm install`
14+
- Please work with the code from the develop branch `git checkout develop`
15+
- Add a test for the issue: Copy `test/test000.js` and replace `000` with a new number.
16+
- Impelement a test that reflects the issue.
17+
- Run `npm test` to verify only the new test fails
18+
- Implement your contributions in `src/`
19+
- Run `npm test` and verify all tests are OK
20+
- Commit changes to git and push to your forked repo
21+
- Click "Create Pull-request" when looking at your forked repo on Github
2222

2323
_Please note that `npm test` will compile from `src/` before running tests_
2424

dist/alasql-worker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//! AlaSQL v0.4.11-develop-d00d3b02undefined | © 2014-2018 Andrey Gershun & Mathias Rangel Wulff | License: MIT
1+
//! AlaSQL v0.4.11-develop-df603f27undefined | © 2014-2018 Andrey Gershun & Mathias Rangel Wulff | License: MIT
22
/*
33
@module alasql
4-
@version 0.4.11-develop-d00d3b02undefined
4+
@version 0.4.11-develop-df603f27undefined
55
66
AlaSQL - JavaScript SQL database
77
© 2014-2016 Andrey Gershun & Mathias Rangel Wulff

dist/alasql-worker.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/alasql.fs.js

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//! AlaSQL v0.4.11-develop-d00d3b02undefined | © 2014-2018 Andrey Gershun & Mathias Rangel Wulff | License: MIT
1+
//! AlaSQL v0.4.11-develop-df603f27undefined | © 2014-2018 Andrey Gershun & Mathias Rangel Wulff | License: MIT
22
/*
33
@module alasql
4-
@version 0.4.11-develop-d00d3b02undefined
4+
@version 0.4.11-develop-df603f27undefined
55

66
AlaSQL - JavaScript SQL database
77
© 2014-2016 Andrey Gershun & Mathias Rangel Wulff
@@ -142,7 +142,7 @@ var alasql = function(sql, params, cb, scope) {
142142
Current version of alasql
143143
@constant {string}
144144
*/
145-
alasql.version = '0.4.11-develop-d00d3b02undefined';
145+
alasql.version = '0.4.11-develop-df603f27undefined';
146146

147147
/**
148148
Debug flag
@@ -7576,49 +7576,45 @@ function doJoin(query, scope, h) {
75767576

75777577
// STEP 2
75787578

7579-
if (h + 1 < query.sources.length) {
7580-
if (
7581-
nextsource.joinmode == 'OUTER' ||
7582-
nextsource.joinmode == 'RIGHT' ||
7583-
nextsource.joinmode == 'ANTI'
7584-
) {
7585-
scope[source.alias] = {};
7586-
7587-
var j = 0;
7588-
var jlen = nextsource.data.length;
7589-
var dataw;
7590-
7591-
while (
7592-
(dataw = nextsource.data[j]) ||
7593-
(nextsource.getfn && (dataw = nextsource.getfn(j))) ||
7594-
j < jlen
7579+
if (h == 0) {
7580+
for (var nh = h + 1; nh < query.sources.length; nh++) {
7581+
if (
7582+
nextsource.joinmode == 'OUTER' ||
7583+
nextsource.joinmode == 'RIGHT' ||
7584+
nextsource.joinmode == 'ANTI'
75957585
) {
7596-
if (nextsource.getfn && !nextsource.dontcache) {
7597-
nextsource.data[j] = dataw;
7598-
}
7586+
scope[source.alias] = {};
75997587

7600-
if (dataw._rightjoin) {
7601-
delete dataw._rightjoin;
7602-
} else {
7603-
// delete dataw._rightjoin;
7588+
var j = 0;
7589+
var jlen = nextsource.data.length;
7590+
var dataw;
76047591

7605-
if (h == 0) {
7606-
scope[nextsource.alias] = dataw;
7607-
doJoin(query, scope, h + 2);
7592+
while (
7593+
(dataw = nextsource.data[j]) ||
7594+
(nextsource.getfn && (dataw = nextsource.getfn(j))) ||
7595+
j < jlen
7596+
) {
7597+
if (nextsource.getfn && !nextsource.dontcache) {
7598+
nextsource.data[j] = dataw;
7599+
}
7600+
7601+
if (dataw._rightjoin) {
7602+
delete dataw._rightjoin;
76087603
} else {
7609-
//scope[nextsource.alias] = dataw;
7610-
//doJoin(query, scope, h+2);
7604+
// delete dataw._rightjoin;
76117605

7606+
scope[nextsource.alias] = dataw;
7607+
doJoin(query, scope, nh + 1);
76127608
}
7609+
j++;
76137610
}
7614-
j++;
7615-
}
7616-
// debugger;
7617-
} else {
7611+
// debugger;
7612+
} else {
76187613

7614+
}
7615+
source = query.sources[nh];
7616+
nextsource = query.sources[nh + 1];
76197617
}
7620-
} else {
7621-
76227618
}
76237619

76247620
scope[tableid] = undefined;

dist/alasql.js

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//! AlaSQL v0.4.11-develop-d00d3b02undefined | © 2014-2018 Andrey Gershun & Mathias Rangel Wulff | License: MIT
1+
//! AlaSQL v0.4.11-develop-df603f27undefined | © 2014-2018 Andrey Gershun & Mathias Rangel Wulff | License: MIT
22
/*
33
@module alasql
4-
@version 0.4.11-develop-d00d3b02undefined
4+
@version 0.4.11-develop-df603f27undefined
55

66
AlaSQL - JavaScript SQL database
77
© 2014-2016 Andrey Gershun & Mathias Rangel Wulff
@@ -142,7 +142,7 @@ var alasql = function(sql, params, cb, scope) {
142142
Current version of alasql
143143
@constant {string}
144144
*/
145-
alasql.version = '0.4.11-develop-d00d3b02undefined';
145+
alasql.version = '0.4.11-develop-df603f27undefined';
146146

147147
/**
148148
Debug flag
@@ -7571,49 +7571,45 @@ function doJoin(query, scope, h) {
75717571

75727572
// STEP 2
75737573

7574-
if (h + 1 < query.sources.length) {
7575-
if (
7576-
nextsource.joinmode == 'OUTER' ||
7577-
nextsource.joinmode == 'RIGHT' ||
7578-
nextsource.joinmode == 'ANTI'
7579-
) {
7580-
scope[source.alias] = {};
7581-
7582-
var j = 0;
7583-
var jlen = nextsource.data.length;
7584-
var dataw;
7585-
7586-
while (
7587-
(dataw = nextsource.data[j]) ||
7588-
(nextsource.getfn && (dataw = nextsource.getfn(j))) ||
7589-
j < jlen
7574+
if (h == 0) {
7575+
for (var nh = h + 1; nh < query.sources.length; nh++) {
7576+
if (
7577+
nextsource.joinmode == 'OUTER' ||
7578+
nextsource.joinmode == 'RIGHT' ||
7579+
nextsource.joinmode == 'ANTI'
75907580
) {
7591-
if (nextsource.getfn && !nextsource.dontcache) {
7592-
nextsource.data[j] = dataw;
7593-
}
7581+
scope[source.alias] = {};
75947582

7595-
if (dataw._rightjoin) {
7596-
delete dataw._rightjoin;
7597-
} else {
7598-
// delete dataw._rightjoin;
7583+
var j = 0;
7584+
var jlen = nextsource.data.length;
7585+
var dataw;
75997586

7600-
if (h == 0) {
7601-
scope[nextsource.alias] = dataw;
7602-
doJoin(query, scope, h + 2);
7587+
while (
7588+
(dataw = nextsource.data[j]) ||
7589+
(nextsource.getfn && (dataw = nextsource.getfn(j))) ||
7590+
j < jlen
7591+
) {
7592+
if (nextsource.getfn && !nextsource.dontcache) {
7593+
nextsource.data[j] = dataw;
7594+
}
7595+
7596+
if (dataw._rightjoin) {
7597+
delete dataw._rightjoin;
76037598
} else {
7604-
//scope[nextsource.alias] = dataw;
7605-
//doJoin(query, scope, h+2);
7599+
// delete dataw._rightjoin;
76067600

7601+
scope[nextsource.alias] = dataw;
7602+
doJoin(query, scope, nh + 1);
76077603
}
7604+
j++;
76087605
}
7609-
j++;
7610-
}
7611-
// debugger;
7612-
} else {
7606+
// debugger;
7607+
} else {
76137608

7609+
}
7610+
source = query.sources[nh];
7611+
nextsource = query.sources[nh + 1];
76147612
}
7615-
} else {
7616-
76177613
}
76187614

76197615
scope[tableid] = undefined;

dist/alasql.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/39dojoin.js

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -158,50 +158,46 @@ function doJoin(query, scope, h) {
158158

159159
// STEP 2
160160

161-
if (h + 1 < query.sources.length) {
162-
if (
163-
nextsource.joinmode == 'OUTER' ||
164-
nextsource.joinmode == 'RIGHT' ||
165-
nextsource.joinmode == 'ANTI'
166-
) {
167-
scope[source.alias] = {};
168-
169-
var j = 0;
170-
var jlen = nextsource.data.length;
171-
var dataw;
172-
173-
while (
174-
(dataw = nextsource.data[j]) ||
175-
(nextsource.getfn && (dataw = nextsource.getfn(j))) ||
176-
j < jlen
161+
if (h == 0) {
162+
for (var nh = h + 1; nh < query.sources.length; nh++) {
163+
if (
164+
nextsource.joinmode == 'OUTER' ||
165+
nextsource.joinmode == 'RIGHT' ||
166+
nextsource.joinmode == 'ANTI'
177167
) {
178-
if (nextsource.getfn && !nextsource.dontcache) {
179-
nextsource.data[j] = dataw;
180-
}
168+
scope[source.alias] = {};
169+
170+
var j = 0;
171+
var jlen = nextsource.data.length;
172+
var dataw;
173+
174+
while (
175+
(dataw = nextsource.data[j]) ||
176+
(nextsource.getfn && (dataw = nextsource.getfn(j))) ||
177+
j < jlen
178+
) {
179+
if (nextsource.getfn && !nextsource.dontcache) {
180+
nextsource.data[j] = dataw;
181+
}
181182

182-
// console.log(169,dataw._rightjoin,scope);
183-
if (dataw._rightjoin) {
184-
delete dataw._rightjoin;
185-
} else {
186-
// delete dataw._rightjoin;
187-
// console.log(163,h,scope);
188-
if (h == 0) {
189-
scope[nextsource.alias] = dataw;
190-
doJoin(query, scope, h + 2);
183+
// console.log(169,dataw._rightjoin,scope);
184+
if (dataw._rightjoin) {
185+
delete dataw._rightjoin;
191186
} else {
192-
//scope[nextsource.alias] = dataw;
193-
//doJoin(query, scope, h+2);
194-
// console.log(169,scope);
187+
// delete dataw._rightjoin;
188+
// console.log(163,h,scope);
189+
scope[nextsource.alias] = dataw;
190+
doJoin(query, scope, nh + 1);
195191
}
192+
j++;
196193
}
197-
j++;
194+
// debugger;
195+
} else {
196+
//console.log(180,scope);
198197
}
199-
// debugger;
200-
} else {
201-
//console.log(180,scope);
198+
source = query.sources[nh];
199+
nextsource = query.sources[nh + 1];
202200
}
203-
} else {
204-
// console.log(179,scope);
205201
}
206202

207203
scope[tableid] = undefined;
@@ -210,7 +206,7 @@ function doJoin(query, scope, h) {
210206
if(h+1 < query.sources.length) {
211207
var nextsource = query.sources[h+1];
212208
213-
if(nextsource.joinmode == "OUTER" || nextsource.joinmode == "RIGHT"
209+
if(nextsource.joinmode == "OUTER" || nextsource.joinmode == "RIGHT"
214210
|| nextsource.joinmode == "ANTI") {
215211
216212
@@ -224,7 +220,7 @@ function doJoin(query, scope, h) {
224220
//debugger;
225221
// var source = query.sources[h];
226222
227-
// var tableid = source.alias || source.tableid;
223+
// var tableid = source.alias || source.tableid;
228224
// var data = source.data;
229225
230226
// Reduce data for looping if there is optimization hint
@@ -254,7 +250,7 @@ function doJoin(query, scope, h) {
254250
// scope[tableid] = {};
255251
// console.log(scope);
256252
doJoin(query,scope,h+2);
257-
}
253+
}
258254
};
259255
260256
// Additional join for LEFT JOINS

test/test800.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ if (typeof exports === 'object') {
66
}
77

88
describe('Test 800 - OUTER JOIN missing ids', function() {
9+
before(function() {
10+
alasql('CREATE DATABASE test800;USE test800');
11+
});
12+
13+
after(function() {
14+
alasql.options.modifier = undefined;
15+
alasql('DROP DATABASE test800');
16+
});
17+
918
it('1. ARRAY()', function(done) {
1019
var t1 = [
1120
{id: '1', a: 'one'},

0 commit comments

Comments
 (0)