Skip to content
28 changes: 28 additions & 0 deletions src/38query.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,34 @@ function queryfn3(query) {
query.data = arrayIntersectDeep(query.data, ud);
}

// Populate order keys for UNION/INTERSECT/EXCEPT before ordering
if (
query.orderfn &&
query.orderColumns &&
(query.unionallfn || query.unionfn || query.exceptfn || query.intersectfn)
) {
for (i = 0, ilen = query.data.length; i < ilen; i++) {
for (var idx = 0; idx < query.orderColumns.length; idx++) {
var v = query.orderColumns[idx];
var key = '$$$' + idx;
var r = query.data[i];
if (v instanceof yy.Column && r[v.columnid] !== undefined) {
r[key] = r[v.columnid];
} else if (v instanceof yy.Column) {
// Column not found in row, set to null or undefined
r[key] = undefined;
} else {
// For expressions, we'd need to evaluate them, but for now just skip
r[key] = undefined;
}
// Add to removeKeys if not already there
if (i === 0 && query.removeKeys.indexOf(key) === -1) {
query.removeKeys.push(key);
}
}
}
}

// Ordering
if (query.orderfn) {
if (query.explain) var ms = Date.now();
Expand Down
22 changes: 18 additions & 4 deletions src/40select.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ yy.Select = class Select {
// 8. Compile ORDER BY clause
if (this.order) {
query.orderfn = this.compileOrder(query, params);
// Copy orderColumns to query for union handling
query.orderColumns = this.orderColumns;
}

if (this.group || query.selectGroup.length > 0) {
Expand Down Expand Up @@ -254,16 +256,28 @@ yy.Select = class Select {
query.corresponding = this.corresponding; // If CORRESPONDING flag exists
if (this.union) {
query.unionfn = this.union.compile(databaseid);
query.orderfn = this.union.order ? this.union.compileOrder(query, params) : null;
// ORDER BY is now at the top level, not in the union clause
if (!query.orderfn && this.union.order) {
query.orderfn = this.union.compileOrder(query, params);
}
} else if (this.unionall) {
query.unionallfn = this.unionall.compile(databaseid);
query.orderfn = this.unionall.order ? this.unionall.compileOrder(query, params) : null;
// ORDER BY is now at the top level, not in the unionall clause
if (!query.orderfn && this.unionall.order) {
query.orderfn = this.unionall.compileOrder(query, params);
}
} else if (this.except) {
query.exceptfn = this.except.compile(databaseid);
query.orderfn = this.except.order ? this.except.compileOrder(query, params) : null;
// ORDER BY is now at the top level, not in the except clause
if (!query.orderfn && this.except.order) {
query.orderfn = this.except.compileOrder(query, params);
}
} else if (this.intersect) {
query.intersectfn = this.intersect.compile(databaseid);
query.orderfn = this.intersect.order ? this.intersect.compileOrder(query, params) : null;
// ORDER BY is now at the top level, not in the intersect clause
if (!query.orderfn && this.intersect.order) {
query.orderfn = this.intersect.compileOrder(query, params);
}
}

// SELECT INTO
Expand Down
20 changes: 18 additions & 2 deletions src/424select.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,15 @@ yy.Select.prototype.compileSelect1 = function (query, params) {
};
yy.Select.prototype.compileSelect2 = function (query, params) {
var s = query.selectfns;
if (this.orderColumns && this.orderColumns.length > 0) {
// Only add order keys if there's no union operation (otherwise they'll be added later)
if (
this.orderColumns &&
this.orderColumns.length > 0 &&
!this.union &&
!this.unionall &&
!this.except &&
!this.intersect
) {
this.orderColumns.forEach(function (v, idx) {
var key = '$$$' + idx;
// Handle positional column reference (for SELECT * with ORDER BY numeric)
Expand Down Expand Up @@ -527,7 +535,15 @@ yy.Select.prototype.compileSelectGroup2 = function (query) {
}
});

if (this.orderColumns && this.orderColumns.length > 0) {
// Only add order keys if there's no union operation (otherwise they'll be added later)
if (
this.orderColumns &&
this.orderColumns.length > 0 &&
!this.union &&
!this.unionall &&
!this.except &&
!this.intersect
) {
this.orderColumns.forEach(function (v, idx) {
// console.log(411,v);
var key = '$$$' + idx;
Expand Down
28 changes: 19 additions & 9 deletions src/alasqlparser.jison
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ WithTable
/* SELECT */

Select
: SelectClause RemoveClause? IntoClause FromClause PivotClause? WhereClause GroupClause OrderClause LimitClause UnionClause
: SelectClause RemoveClause? IntoClause FromClause PivotClause? 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);
Expand All @@ -524,6 +524,16 @@ Select
}
;

SelectWithoutOrderOrLimit
: SelectClause RemoveClause? IntoClause FromClause PivotClause? 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);
$$ = $1;
if(yy.exists) $$.exists = yy.exists.slice();
}
;

PivotClause
: PIVOT LPAR Expression FOR Literal PivotClause2? RPAR AsLiteral?
{ $$ = {pivot:{expr:$3, columnid:$5, inlist:$6, as:$8}}; }
Expand Down Expand Up @@ -1074,21 +1084,21 @@ HavingClause

UnionClause
: { $$ = undefined; }
| UNION Select
| UNION SelectWithoutOrderOrLimit
{ $$ = {union: $2} ; }
| UNION ALL Select
| UNION ALL SelectWithoutOrderOrLimit
{ $$ = {unionall: $3} ; }
| EXCEPT Select
| EXCEPT SelectWithoutOrderOrLimit
{ $$ = {except: $2} ; }
| INTERSECT Select
| INTERSECT SelectWithoutOrderOrLimit
{ $$ = {intersect: $2} ; }
| UNION CORRESPONDING Select
| UNION CORRESPONDING SelectWithoutOrderOrLimit
{ $$ = {union: $3, corresponding:true} ; }
| UNION ALL CORRESPONDING Select
| UNION ALL CORRESPONDING SelectWithoutOrderOrLimit
{ $$ = {unionall: $4, corresponding:true} ; }
| EXCEPT CORRESPONDING Select
| EXCEPT CORRESPONDING SelectWithoutOrderOrLimit
{ $$ = {except: $3, corresponding:true} ; }
| INTERSECT CORRESPONDING Select
| INTERSECT CORRESPONDING SelectWithoutOrderOrLimit
{ $$ = {intersect: $3, corresponding:true} ; }
;

Expand Down
Loading
Loading