Skip to content

Commit 4816906

Browse files
Copilotmathiasrw
andauthored
Fix trigger CALL for row data parameters (#2377)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]> Co-authored-by: M. Wulff <[email protected]>
1 parent 5d5bce7 commit 4816906

File tree

4 files changed

+48
-48
lines changed

4 files changed

+48
-48
lines changed

src/60createtable.js

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,8 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
332332
for (var tr in table.beforeinsert) {
333333
var trigger = table.beforeinsert[tr];
334334
if (trigger) {
335-
if (trigger.funcid) {
336-
if (alasql.fn[trigger.funcid](r) === false) prevent = prevent || true;
337-
} else if (trigger.statement) {
338-
if (trigger.statement.execute(databaseid) === false) prevent = prevent || true;
335+
if (alasql.executeTrigger(trigger, databaseid, r) === false) {
336+
prevent = prevent || true;
339337
}
340338
}
341339
}
@@ -347,11 +345,7 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
347345
escape = true;
348346
trigger = table.insteadofinsert[tr];
349347
if (trigger) {
350-
if (trigger.funcid) {
351-
alasql.fn[trigger.funcid](r);
352-
} else if (trigger.statement) {
353-
trigger.statement.execute(databaseid);
354-
}
348+
alasql.executeTrigger(trigger, databaseid, r);
355349
}
356350
}
357351
if (escape) return;
@@ -488,11 +482,7 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
488482
for (var tr in table.afterinsert) {
489483
var trigger = table.afterinsert[tr];
490484
if (trigger) {
491-
if (trigger.funcid) {
492-
alasql.fn[trigger.funcid](r);
493-
} else if (trigger.statement) {
494-
trigger.statement.execute(databaseid);
495-
}
485+
alasql.executeTrigger(trigger, databaseid, r);
496486
}
497487
}
498488
alasql.inserted = oldinserted;
@@ -507,10 +497,8 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
507497
for (var tr in table.beforedelete) {
508498
var trigger = table.beforedelete[tr];
509499
if (trigger) {
510-
if (trigger.funcid) {
511-
if (alasql.fn[trigger.funcid](r) === false) prevent = prevent || true;
512-
} else if (trigger.statement) {
513-
if (trigger.statement.execute(databaseid) === false) prevent = prevent || true;
500+
if (alasql.executeTrigger(trigger, databaseid, r) === false) {
501+
prevent = prevent || true;
514502
}
515503
}
516504
}
@@ -522,11 +510,7 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
522510
escape = true;
523511
var trigger = table.insteadofdelete[tr];
524512
if (trigger) {
525-
if (trigger.funcid) {
526-
alasql.fn[trigger.funcid](r);
527-
} else if (trigger.statement) {
528-
trigger.statement.execute(databaseid);
529-
}
513+
alasql.executeTrigger(trigger, databaseid, r);
530514
}
531515
}
532516
if (escape) return;
@@ -613,10 +597,8 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
613597
for (var tr in table.beforeupdate) {
614598
var trigger = table.beforeupdate[tr];
615599
if (trigger) {
616-
if (trigger.funcid) {
617-
if (alasql.fn[trigger.funcid](this.data[i], r) === false) prevent = prevent || true;
618-
} else if (trigger.statement) {
619-
if (trigger.statement.execute(databaseid) === false) prevent = prevent || true;
600+
if (alasql.executeTrigger(trigger, databaseid, this.data[i], r) === false) {
601+
prevent = prevent || true;
620602
}
621603
}
622604
}
@@ -628,11 +610,7 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
628610
escape = true;
629611
var trigger = table.insteadofupdate[tr];
630612
if (trigger) {
631-
if (trigger.funcid) {
632-
alasql.fn[trigger.funcid](this.data[i], r);
633-
} else if (trigger.statement) {
634-
trigger.statement.execute(databaseid);
635-
}
613+
alasql.executeTrigger(trigger, databaseid, this.data[i], r);
636614
}
637615
}
638616
if (escape) return;
@@ -685,11 +663,7 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
685663
for (var tr in table.afterupdate) {
686664
var trigger = table.afterupdate[tr];
687665
if (trigger) {
688-
if (trigger.funcid) {
689-
alasql.fn[trigger.funcid](this.data[i], r);
690-
} else if (trigger.statement) {
691-
trigger.statement.execute(databaseid);
692-
}
666+
alasql.executeTrigger(trigger, databaseid, this.data[i], r);
693667
}
694668
}
695669
};

src/71trigger.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,27 @@ yy.DropTrigger.prototype.execute = function (databaseid, params, cb) {
108108
if (cb) res = cb(res);
109109
return res;
110110
};
111+
112+
/**
113+
* Helper function to execute a trigger with proper parameter passing
114+
* @param {object} trigger - The trigger object
115+
* @param {string} databaseid - Database ID for statement execution
116+
* @param {...any} args - Arguments to pass to the trigger function
117+
* @return {*} Result from trigger execution (typically boolean or undefined)
118+
*/
119+
alasql.executeTrigger = function (trigger, databaseid, ...args) {
120+
if (!trigger) return;
121+
122+
if (trigger.funcid) {
123+
// Direct function ID (older syntax: CREATE TRIGGER ... tablename funcname)
124+
return alasql.fn[trigger.funcid](...args);
125+
} else if (trigger.statement) {
126+
// CALL syntax: CREATE TRIGGER ... CALL funcname()
127+
if (trigger.statement.expression && trigger.statement.expression.funcid) {
128+
return alasql.fn[trigger.statement.expression.funcid](...args);
129+
} else {
130+
// Fallback: execute statement without parameters (for non-CALL statements)
131+
return trigger.statement.execute(databaseid);
132+
}
133+
}
134+
};

src/72delete.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ yy.Delete.prototype.compile = function (databaseid) {
8888
var deletedRows = [];
8989
for (var i = 0, ilen = table.data.length; i < ilen; i++) {
9090
if (wherefn(table.data[i], params, alasql)) {
91-
// Track deleted row for OUTPUT clause
92-
if (self.output) {
91+
// Track deleted row for OUTPUT clause and AFTER DELETE trigger
92+
if (self.output || table.afterdelete) {
9393
deletedRows.push(cloneDeep(table.data[i]));
9494
}
9595
// Check for transaction - if it is not possible then return all back
@@ -104,14 +104,16 @@ yy.Delete.prototype.compile = function (databaseid) {
104104
}
105105
table.data = newtable;
106106

107-
// Trigger prevent functionality
108-
for (var tr in table.afterdelete) {
109-
var trigger = table.afterdelete[tr];
110-
if (trigger) {
111-
if (trigger.funcid) {
112-
alasql.fn[trigger.funcid]();
113-
} else if (trigger.statement) {
114-
trigger.statement.execute(databaseid);
107+
// AFTER DELETE triggers - call for each deleted row
108+
// Note: Triggers are called once per row per trigger (row-level triggers)
109+
// For N deleted rows and M triggers, this results in N×M trigger calls
110+
if (table.afterdelete) {
111+
for (var i = 0; i < deletedRows.length; i++) {
112+
for (var tr in table.afterdelete) {
113+
var trigger = table.afterdelete[tr];
114+
if (trigger) {
115+
alasql.executeTrigger(trigger, databaseid, deletedRows[i]);
116+
}
115117
}
116118
}
117119
}

test/test1119.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ if (typeof exports === 'object') {
33
var alasql = require('..'); // You might need to adjust the path depending on where you save the test file
44
}
55

6-
describe.skip('Test 1119 - Trigger callback parameter', function () {
6+
describe('Test 1119 - Trigger callback parameter', function () {
77
const test = '1119'; // Test file number
88

99
before(function () {

0 commit comments

Comments
 (0)