Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
37 changes: 36 additions & 1 deletion src/40select.js
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,42 @@ function modify(query, res) {

var modifier = query.modifier || alasql.options.modifier;
var columns = query.columns;
if (typeof columns === 'undefined' || columns.length == 0) {

// If dirtyColumns is true, we need to merge columns from data with existing columns
// This happens when SELECT * is used with dynamic data sources (like parameters)
if (query.dirtyColumns && res.length > 0) {
var allcol = {};
// First, scan the data to find all column names
for (var i = Math.min(res.length, alasql.options.columnlookup || 10) - 1; 0 <= i; i--) {
for (var key in res[i]) {
allcol[key] = true;
}
}

// Create columns from data
var dataColumns = Object.keys(allcol).map(function (columnid) {
return {columnid: columnid};
});

// If we don't have any columns yet, just use the data columns
if (!columns || columns.length === 0) {
columns = dataColumns;
} else {
// We have some columns (e.g., from explicit column expressions),
// merge them with data columns, avoiding duplicates
var existingColumnIds = {};
columns.forEach(function (col) {
existingColumnIds[col.columnid] = true;
});

// Add data columns that aren't already in the list
dataColumns.forEach(function (col) {
if (!existingColumnIds[col.columnid]) {
columns.push(col);
}
});
}
} else if (typeof columns === 'undefined' || columns.length === 0) {
// Try to create columns
if (res.length > 0) {
var allcol = {};
Expand Down
114 changes: 114 additions & 0 deletions test/test2201.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
if (typeof exports === 'object') {
var assert = require('assert');
var alasql = require('..');
}

describe('Test 2201 - RECORDSET OF with wildcard and additional columns', function () {
it('1. RECORDSET OF SELECT t.*, additional_column returns all columns', function (done) {
var data = [
{a: 1, b: 10},
{a: 2, b: 20},
{a: 1, b: 30},
];
var res = alasql('RECORDSET OF SELECT t.*, 1 as rn FROM ? t', [data]);

// Check that all columns are present in the columns array
assert.equal(res.columns.length, 3, 'Should have 3 columns');

var columnIds = res.columns.map(function (col) {
return col.columnid;
});
assert(columnIds.includes('a'), 'Should include column a');
assert(columnIds.includes('b'), 'Should include column b');
assert(columnIds.includes('rn'), 'Should include column rn');

// Check data integrity
assert.equal(res.data.length, 3, 'Should have 3 rows');
assert.deepEqual(res.data[0], {rn: 1, a: 1, b: 10});
assert.deepEqual(res.data[1], {rn: 1, a: 2, b: 20});
assert.deepEqual(res.data[2], {rn: 1, a: 1, b: 30});

done();
});

it('2. RECORDSET OF SELECT *, additional_column returns all columns', function (done) {
var data = [
{a: 1, b: 10},
{a: 2, b: 20},
];
var res = alasql('RECORDSET OF SELECT *, 1 as rn FROM ? t', [data]);

// Check that all columns are present
assert.equal(res.columns.length, 3, 'Should have 3 columns');

var columnIds = res.columns.map(function (col) {
return col.columnid;
});
assert(columnIds.includes('a'), 'Should include column a');
assert(columnIds.includes('b'), 'Should include column b');
assert(columnIds.includes('rn'), 'Should include column rn');

done();
});

it('3. RECORDSET OF SELECT t.* still works correctly', function (done) {
var data = [
{a: 1, b: 10},
{a: 2, b: 20},
];
var res = alasql('RECORDSET OF SELECT t.* FROM ? t', [data]);

// Check that all columns are present
assert.equal(res.columns.length, 2, 'Should have 2 columns');

var columnIds = res.columns.map(function (col) {
return col.columnid;
});
assert(columnIds.includes('a'), 'Should include column a');
assert(columnIds.includes('b'), 'Should include column b');

done();
});

it('4. RECORDSET OF SELECT explicit columns works correctly', function (done) {
var data = [
{a: 1, b: 10},
{a: 2, b: 20},
];
var res = alasql('RECORDSET OF SELECT a, b, 1 as rn FROM ? t', [data]);

// Check that all columns are present
assert.equal(res.columns.length, 3, 'Should have 3 columns');

var columnIds = res.columns.map(function (col) {
return col.columnid;
});
assert.deepEqual(columnIds, ['a', 'b', 'rn'], 'Should have columns in order');

done();
});

it('5. RECORDSET OF SELECT with multiple additional columns', function (done) {
var data = [
{a: 1, b: 10},
{a: 2, b: 20},
];
var res = alasql('RECORDSET OF SELECT t.*, 1 as rn, 2 as seq FROM ? t', [data]);

// Check that all columns are present
assert.equal(res.columns.length, 4, 'Should have 4 columns');

var columnIds = res.columns.map(function (col) {
return col.columnid;
});
assert(columnIds.includes('a'), 'Should include column a');
assert(columnIds.includes('b'), 'Should include column b');
assert(columnIds.includes('rn'), 'Should include column rn');
assert(columnIds.includes('seq'), 'Should include column seq');

// Check data
assert.deepEqual(res.data[0], {rn: 1, seq: 2, a: 1, b: 10});

done();
});
});
Loading