Skip to content

Commit 3b8d554

Browse files
Copilotmathiasrw
andauthored
Fix key properties for column objects on table-level constraints to close #1643 (#2388)
Fixed issue where foreign key and primary key constraints defined at the table level were not marking columns with `primarykey` or `foreignkey` properties. Columns can now be introspected to determine if they are part of a primary key or have foreign key relationships. Changes: - Primary key columns are now marked with `primarykey: true` - Foreign key columns are now marked with a `foreignkey` object containing `tableid`, `columnid`, and `constraintid` (when available) - Fixed NULL/NaN handling in both table-level and inline foreign key constraints to properly allow NULL values - Inline foreign keys now use the same NULL/NaN checking logic as table-level foreign keys for consistency --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]> Co-authored-by: M. Wulff <[email protected]>
1 parent b3d2410 commit 3b8d554

File tree

10 files changed

+434
-32
lines changed

10 files changed

+434
-32
lines changed

src/60createtable.js

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -166,21 +166,21 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
166166
throw new Error('FOREIGN KEY allowed only to tables with PRIMARY KEYs');
167167
}
168168
}
169+
// Store foreignkey property in column for later access
170+
newcol.foreignkey = {
171+
tableid: fk.tableid,
172+
columnid: fk.columnid,
173+
};
169174
var fkfn = function (r) {
170175
var rr = {};
171-
// Allow NULL values in foreign keys (check for undefined, null, and NaN)
172176
var val = r[col.columnid];
173-
if (
174-
typeof val === 'undefined' ||
175-
val === null ||
176-
(typeof val === 'number' && isNaN(val))
177-
) {
178-
return true;
179-
}
180-
rr[fk.columnid] = val;
181-
var addr = fktable.pk.onrightfn(rr);
182-
if (!fktable.uniqs[fktable.pk.hh][addr]) {
183-
throw new Error('Foreign key "' + val + '" not found in table "' + fk.tableid + '"');
177+
// Only check foreign key if value is not null, undefined, or NaN
178+
if (val != null && !(typeof val === 'number' && isNaN(val))) {
179+
rr[fk.columnid] = val;
180+
var addr = fktable.pk.onrightfn(rr);
181+
if (!fktable.uniqs[fktable.pk.hh][addr]) {
182+
throw new Error('Foreign key "' + val + '" not found in table "' + fk.tableid + '"');
183+
}
184184
}
185185
return true;
186186
};
@@ -215,6 +215,12 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
215215
pk.onrightfn = new Function('r', 'var y;return ' + pk.onrightfns);
216216
pk.hh = hash(pk.onrightfns);
217217
table.uniqs[pk.hh] = {};
218+
// Mark columns with primarykey property
219+
pk.columns.forEach(function (columnid) {
220+
if (table.xcolumns[columnid]) {
221+
table.xcolumns[columnid].primarykey = true;
222+
}
223+
});
218224
} else if (con.type === 'CHECK') {
219225
checkfn = new Function('r,params,alasql', 'var y;return ' + con.expression.toJS('r', ''));
220226
} else if (con.type === 'UNIQUE') {
@@ -247,13 +253,26 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
247253
throw new Error('Invalid foreign key on table ' + table.tableid);
248254
}
249255

256+
// Mark columns with foreignkey property
257+
fk.columns.forEach(function (columnid, i) {
258+
if (table.xcolumns[columnid]) {
259+
table.xcolumns[columnid].foreignkey = {
260+
tableid: fk.tableid,
261+
columnid: fk.fkcolumns[i],
262+
constraintid: con.constraintid,
263+
};
264+
}
265+
});
266+
250267
checkfn = function (r) {
251268
var rr = {};
252269

253270
//Composite foreign keys
254271
fk.fkcolumns.forEach(function (colFk, i) {
255-
if (r[fk.columns[i]] != null) {
256-
rr[colFk] = r[fk.columns[i]];
272+
var val = r[fk.columns[i]];
273+
// Only include non-null, non-undefined, non-NaN values
274+
if (val != null && !(typeof val === 'number' && isNaN(val))) {
275+
rr[colFk] = val;
257276
}
258277
});
259278

test/test1409.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ if (typeof exports != 'object') {
1414
var count = 0;
1515
alasql.fn.onInsert = function (r) {
1616
count++;
17-
console.log('this never happens!');
17+
// console.log('this never happens!');
1818
};
1919

2020
return alasql

0 commit comments

Comments
 (0)