Skip to content

Commit 8247c9e

Browse files
Copilotmathiasrw
andauthored
Improve error message of foreign key violation to fix #1009 (#2206)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]>
1 parent 3828af2 commit 8247c9e

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

src/60createtable.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
175175
var addr = fktable.pk.onrightfn(rr);
176176
if (!fktable.uniqs[fktable.pk.hh][addr]) {
177177
throw new Error(
178-
'Foreign key violation' //changed error message
178+
'Foreign key "' + r[col.columnid] + '" not found in table "' + fk.tableid + '"'
179179
);
180180
}
181181
return true;
@@ -265,8 +265,11 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
265265
var addr = fktable.pk.onrightfn(rr);
266266

267267
if (!fktable.uniqs[fktable.pk.hh][addr]) {
268+
var keyValues = fk.columns.map(function (col) {
269+
return r[col];
270+
});
268271
throw new Error(
269-
'Foreign key violation' //changed error message
272+
'Foreign key "' + keyValues.join(', ') + '" not found in table "' + fk.tableid + '"'
270273
);
271274
}
272275
return true;

test/test1009.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
if (typeof exports === 'object') {
2+
var assert = require('assert');
3+
var alasql = require('..');
4+
}
5+
6+
describe('Test 1009 - Foreign key error message with table name', function () {
7+
const test = '1009';
8+
9+
before(function () {
10+
alasql('create database test' + test);
11+
alasql('use test' + test);
12+
});
13+
14+
after(function () {
15+
alasql('drop database test' + test);
16+
});
17+
18+
it('A) Single column foreign key - error message should include table and key', function () {
19+
alasql(
20+
'CREATE TABLE tableA (id INT PRIMARY KEY);' +
21+
'CREATE TABLE tableB (id INT, a_id INT, FOREIGN KEY (a_id) REFERENCES tableA(id));' +
22+
'INSERT INTO tableA VALUES (1);' +
23+
'INSERT INTO tableA VALUES (2);' +
24+
'INSERT INTO tableB VALUES (1, 1);'
25+
);
26+
27+
// This should fail with a proper error message showing the table name and key
28+
try {
29+
alasql('INSERT INTO tableB VALUES (2, 20)');
30+
assert.fail('Should have thrown an error for foreign key violation');
31+
} catch (err) {
32+
console.log('Error message:', err.message);
33+
// The error message should include information about what key and table failed
34+
assert(err.message.includes('Foreign key'), 'Error should mention foreign key');
35+
assert(err.message.includes('20'), 'Error should include the key value');
36+
assert(err.message.includes('tableA'), 'Error should include the table name');
37+
// Check that it's not showing 'undefined' as the table name
38+
assert(!err.message.includes('undefined'), 'Error should not contain undefined');
39+
}
40+
});
41+
42+
it('B) Inline foreign key - error message should include table and key', function () {
43+
alasql(
44+
'DROP TABLE IF EXISTS tableC;' +
45+
'DROP TABLE IF EXISTS tableD;' +
46+
'CREATE TABLE tableC (id INT PRIMARY KEY);' +
47+
'CREATE TABLE tableD (id INT, c_id INT FOREIGN KEY REFERENCES tableC(id));' +
48+
'INSERT INTO tableC VALUES (10);' +
49+
'INSERT INTO tableC VALUES (20);' +
50+
'INSERT INTO tableD VALUES (1, 10);'
51+
);
52+
53+
// This should fail with a proper error message
54+
try {
55+
alasql('INSERT INTO tableD VALUES (2, 99)');
56+
assert.fail('Should have thrown an error for foreign key violation');
57+
} catch (err) {
58+
console.log('Error message:', err.message);
59+
assert(err.message.includes('Foreign key'), 'Error should mention foreign key');
60+
assert(err.message.includes('99'), 'Error should include the key value');
61+
assert(err.message.includes('tableC'), 'Error should include the table name');
62+
assert(!err.message.includes('undefined'), 'Error should not contain undefined');
63+
}
64+
});
65+
66+
it('C) Composite foreign key - error message should include table and keys', function () {
67+
alasql(
68+
'DROP TABLE IF EXISTS tableE;' +
69+
'DROP TABLE IF EXISTS tableF;' +
70+
'CREATE TABLE tableE (id1 INT, id2 INT, PRIMARY KEY (id1, id2));' +
71+
'CREATE TABLE tableF (id INT, e_id1 INT, e_id2 INT, FOREIGN KEY (e_id1, e_id2) REFERENCES tableE(id1, id2));' +
72+
'INSERT INTO tableE VALUES (1, 1);' +
73+
'INSERT INTO tableE VALUES (2, 2);' +
74+
'INSERT INTO tableF VALUES (1, 1, 1);'
75+
);
76+
77+
// This should fail with a proper error message
78+
try {
79+
alasql('INSERT INTO tableF VALUES (2, 99, 99)');
80+
assert.fail('Should have thrown an error for foreign key violation');
81+
} catch (err) {
82+
console.log('Error message:', err.message);
83+
assert(err.message.includes('Foreign key'), 'Error should mention foreign key');
84+
assert(err.message.includes('99'), 'Error should include the key value');
85+
assert(err.message.includes('tableE'), 'Error should include the table name');
86+
assert(!err.message.includes('undefined'), 'Error should not contain undefined');
87+
}
88+
});
89+
});

0 commit comments

Comments
 (0)