Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 45 additions & 6 deletions src/39dojoin.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,51 @@ function doJoin(query, scope, h) {
if (h >= query.sources.length) {
// Todo: check if this runs once too many
// Then apply where and select
if (query.wherefn(scope, query.params, alasql)) {
// If there is a GROUP BY then pipe to grouping function
if (query.groupfn) {
query.groupfn(scope, query.params, alasql);
} else {
query.data.push(query.selectfn(scope, query.params, alasql));
var params = query.params;
var originalParams = params;
var restoreQueryParams = false;
var previousValues;
if (query.lets && query.lets.length > 0) {
if (!params || typeof params !== 'object') {
params = {};
query.params = params;
restoreQueryParams = true;
}
previousValues = new Array(query.lets.length);
for (var i = 0; i < query.lets.length; i++) {
var assignment = query.lets[i];
var target = assignment.method === '@' ? alasql.vars : params;
previousValues[i] = {
target: target,
variable: assignment.variable,
exists: Object.prototype.hasOwnProperty.call(target, assignment.variable),
value: target[assignment.variable],
};
target[assignment.variable] = assignment.valuefn(scope, params, alasql);
}
}
try {
if (query.wherefn(scope, params, alasql)) {
// If there is a GROUP BY then pipe to grouping function
if (query.groupfn) {
query.groupfn(scope, params, alasql);
} else {
query.data.push(query.selectfn(scope, params, alasql));
}
}
} finally {
if (previousValues) {
for (var j = previousValues.length - 1; j >= 0; j--) {
var previous = previousValues[j];
if (previous.exists) {
previous.target[previous.variable] = previous.value;
} else {
delete previous.target[previous.variable];
}
}
}
if (restoreQueryParams) {
query.params = originalParams;
}
}
} else if (query.sources[h].applyselect) {
Expand Down
23 changes: 23 additions & 0 deletions src/40select.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

/* global yy */

function formatLetExpression(assignment) {
return assignment.method + assignment.variable + ' = ' + assignment.expression.toString();
}

yy.Select = class Select {
constructor(params) {
Object.assign(this, params);
Expand Down Expand Up @@ -90,6 +94,9 @@ yy.Select = class Select {
})
.join('');
}
if (this.let && this.let.length > 0) {
s += ' LET ' + this.let.map(formatLetExpression).join(', ');
}
if (this.where) {
s += ' WHERE ' + this.where.toString();
}
Expand Down Expand Up @@ -183,6 +190,9 @@ yy.Select = class Select {
this.compileJoins(query);
}

// 2.5 Compile LET clause
this.compileLet(query);

// todo?: 3. Compile SELECT clause
// For ROWNUM()
query.rownums = [];
Expand Down Expand Up @@ -623,6 +633,19 @@ yy.Select = class Select {
}
});
}

compileLet(query) {
if (!this.let || this.let.length === 0) return;

query.lets = this.let.map(assignment => ({
method: assignment.method,
variable: assignment.variable,
valuefn: new Function(
'p,params,alasql',
'var y;return ' + assignment.expression.toJS('p', query.defaultTableid, query.defcols)
),
}));
}
};
Comment thread
mathiasrw marked this conversation as resolved.

/**
Expand Down
26 changes: 22 additions & 4 deletions src/alasqlparser.jison
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,11 @@ WithTable
/* SELECT */

Select
: SelectClause RemoveClause? IntoClause FromClause PivotClause? WhereClause GroupClause UnionClause OrderClause LimitClause
: SelectClause RemoveClause? IntoClause FromClause PivotClause? LetClause WhereClause GroupClause UnionClause OrderClause LimitClause
{
yy.extend($$,$1); yy.extend($$,$2); yy.extend($$,$3); yy.extend($$,$4);
yy.extend($$,$5); yy.extend($$,$6);yy.extend($$,$7);
yy.extend($$,$8); yy.extend($$,$9); yy.extend($$,$10);
yy.extend($$,$8); yy.extend($$,$9); yy.extend($$,$10); yy.extend($$,$11);
$$ = $1;
if(yy.exists) $$.exists = yy.exists.slice();
/* if(yy.queries) $$.queries = yy.queries;
Expand Down Expand Up @@ -572,10 +572,10 @@ ParenthesizedSelect
;

SelectWithoutOrderOrLimit
: SelectClause RemoveClause? IntoClause FromClause PivotClause? WhereClause GroupClause UnionClause
: SelectClause RemoveClause? IntoClause FromClause PivotClause? LetClause WhereClause GroupClause UnionClause
{
yy.extend($$,$1); yy.extend($$,$2); yy.extend($$,$3); yy.extend($$,$4);
yy.extend($$,$5); yy.extend($$,$6);yy.extend($$,$7);yy.extend($$,$8);
yy.extend($$,$5); yy.extend($$,$6);yy.extend($$,$7);yy.extend($$,$8);yy.extend($$,$9);
$$ = $1;
if(yy.exists) $$.exists = yy.exists.slice();
}
Expand Down Expand Up @@ -1096,6 +1096,24 @@ WhereClause
{ $$ = {where: new yy.Expression({expression:$2})}; }
;

LetClause
: { $$ = undefined; }
| LET LetExpressionsList
{ $$ = {let: $2}; }
;

LetExpressionsList
: LetExpression
{ $$ = [$1]; }
| LetExpressionsList COMMA LetExpression
{ $1.push($3); $$ = $1; }
;

LetExpression
: AtDollar Literal EQ Expression
{ $$ = new yy.SetVariable({variable:$2, expression:$4, method:$1});}
;

GroupClause
: { $$ = undefined; }
| GROUP BY GroupExpressionsList HavingClause
Expand Down
Loading