Skip to content

Commit a6373df

Browse files
Copilotmathiasrw
andauthored
Add support for INSERT IGNORE syntax to close #143 (#2333)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]> Co-authored-by: M. Wulff <[email protected]>
1 parent 90c91a3 commit a6373df

File tree

5 files changed

+608
-415
lines changed

5 files changed

+608
-415
lines changed

src/60createtable.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,17 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
306306
);
307307
}
308308

309-
table.insert = function (r, orreplace) {
309+
table.insert = function (r, orreplace, ignore) {
310310
var oldinserted = alasql.inserted;
311311
alasql.inserted = [r];
312312

313313
var table = this;
314314

315+
// orreplace and ignore are mutually exclusive - orreplace takes precedence
316+
if (orreplace && ignore) {
317+
ignore = false;
318+
}
319+
315320
var toreplace = false; // For INSERT OR REPLACE
316321

317322
/*
@@ -386,21 +391,31 @@ yy.CreateTable.prototype.execute = function (databaseid, params, cb) {
386391
//console.log(pk,addr,pk.onrightfn({ono:1}));
387392
//console.log(r, pk.onrightfn(r), pk.onrightfns);
388393
if (orreplace) toreplace = table.uniqs[pk.hh][addr];
389-
else
394+
else if (ignore) {
395+
alasql.inserted = oldinserted;
396+
return false; // Silently skip insertion and indicate it was skipped
397+
} else
390398
throw new Error('Cannot insert record, because it already exists in primary key index');
391399
}
392400
// table.uniqs[pk.hh][addr]=r;
393401
}
394402

395403
if (table.uk && table.uk.length) {
396-
table.uk.forEach(function (uk) {
404+
for (var i = 0; i < table.uk.length; i++) {
405+
var uk = table.uk[i];
397406
var ukaddr = uk.onrightfn(r);
398407
if (typeof table.uniqs[uk.hh][ukaddr] !== 'undefined') {
399-
if (orreplace) toreplace = table.uniqs[uk.hh][ukaddr];
400-
else throw new Error('Cannot insert record, because it already exists in unique index');
408+
if (orreplace) {
409+
toreplace = table.uniqs[uk.hh][ukaddr];
410+
} else if (ignore) {
411+
alasql.inserted = oldinserted;
412+
return false; // Silently skip insertion and indicate it was skipped
413+
} else {
414+
throw new Error('Cannot insert record, because it already exists in unique index');
415+
}
401416
}
402417
// table.uniqs[uk.hh][ukaddr]=r;
403-
});
418+
}
404419
}
405420

406421
if (toreplace) {

src/70insert.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ yy.Insert.prototype.toString = function () {
1414
var s = 'INSERT ';
1515
if (this.orreplace) s += 'OR REPLACE ';
1616
if (this.replaceonly) s = 'REPLACE ';
17+
if (this.ignore) s += 'IGNORE ';
1718
s += 'INTO ' + this.into.toString();
1819
if (this.columns) s += '(' + this.columns.toString() + ')';
1920
if (this.values) {
@@ -207,10 +208,27 @@ yy.Insert.prototype.compile = function (databaseid) {
207208
// s += 'db.tables[\''+tableid+'\'].insert(r);';
208209
if (db.tables[tableid].insert) {
209210
s += "var db=alasql.databases['" + databaseid + "'];";
210-
s += "db.tables['" + tableid + "'].insert(a," + (self.orreplace ? 'true' : 'false') + ');';
211+
s +=
212+
"var inserted=db.tables['" +
213+
tableid +
214+
"'].insert(a," +
215+
(self.orreplace ? 'true' : 'false') +
216+
',' +
217+
(self.ignore ? 'true' : 'false') +
218+
');';
219+
// Track successful inserts (insert returns false when ignored)
220+
if (self.ignore) {
221+
s += 'if(inserted!==false){';
222+
}
211223
// Also push to aa for OUTPUT clause
212224
if (self.output) {
213225
s += 'aa.push(a);';
226+
} else if (self.ignore) {
227+
// For ignore mode without output, track successful insertions
228+
s += 'aa.push(a);';
229+
}
230+
if (self.ignore) {
231+
s += '}';
214232
}
215233
} else {
216234
s += 'aa.push(a);';
@@ -259,10 +277,20 @@ yy.Insert.prototype.compile = function (databaseid) {
259277
if (db.tables[tableid].isclass) {
260278
s += 'return a.$id;';
261279
} else {
262-
s += 'return ' + self.values.length;
280+
// For IGNORE mode, return count of actually inserted rows
281+
if (self.ignore) {
282+
s += 'return aa.length;';
283+
} else {
284+
s += 'return ' + self.values.length;
285+
}
263286
}
264287
} else {
265-
s += 'return ' + self.values.length;
288+
// For IGNORE mode, return count of actually inserted rows
289+
if (self.ignore) {
290+
s += 'return aa.length;';
291+
} else {
292+
s += 'return ' + self.values.length;
293+
}
266294
}
267295

268296
//console.log(186,s3+s);
@@ -297,7 +325,7 @@ yy.Insert.prototype.compile = function (databaseid) {
297325
for (var i = 0, ilen = res.length; i < ilen; i++) {
298326
var r = cloneDeep(res[i]);
299327
defaultfn(r, db, params, alasql);
300-
db.tables[tableid].insert(r, self.orreplace);
328+
db.tables[tableid].insert(r, self.orreplace, self.ignore);
301329
insertedRows.push(r);
302330
}
303331
} else {

src/alasqlparser.jison

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ DATABASE(S)? return 'DATABASE'
148148
/*'HELP' return 'HELP'*/
149149
'IF' return 'IF'
150150
'IDENTITY' return 'IDENTITY'
151+
'IGNORE' return 'IGNORE'
151152
'IS' return 'IS'
152153
'IN' return 'IN'
153154
'INDEX' return 'INDEX'
@@ -1844,6 +1845,18 @@ Insert
18441845
{ $$ = new yy.Insert({into:$3, values: $5}); yy.extend($$,$6); }
18451846
| INSERT Into Table ValuesListsList OutputClause
18461847
{ $$ = new yy.Insert({into:$3, values: $4}); yy.extend($$,$5); }
1848+
| INSERT IGNORE Into Table Values ValuesListsList OutputClause
1849+
{ $$ = new yy.Insert({into:$4, values: $6, ignore:true}); yy.extend($$,$7); }
1850+
| INSERT IGNORE Into Table ValuesListsList OutputClause
1851+
{ $$ = new yy.Insert({into:$4, values: $5, ignore:true}); yy.extend($$,$6); }
1852+
| INSERT IGNORE Into Table LPAR ColumnsList RPAR Values ValuesListsList OutputClause
1853+
{ $$ = new yy.Insert({into:$4, columns: $6, values: $9, ignore:true}); yy.extend($$,$10); }
1854+
| INSERT IGNORE Into Table LPAR ColumnsList RPAR ValuesListsList OutputClause
1855+
{ $$ = new yy.Insert({into:$4, columns: $6, values: $8, ignore:true}); yy.extend($$,$9); }
1856+
| INSERT IGNORE Into Table Select OutputClause
1857+
{ $$ = new yy.Insert({into:$4, select: $5, ignore:true}); yy.extend($$,$6); }
1858+
| INSERT IGNORE Into Table LPAR ColumnsList RPAR Select OutputClause
1859+
{ $$ = new yy.Insert({into:$4, columns: $6, select: $8, ignore:true}); yy.extend($$,$9); }
18471860
| INSERT OR REPLACE Into Table Values ValuesListsList OutputClause
18481861
{ $$ = new yy.Insert({into:$5, values: $7, orreplace:true}); yy.extend($$,$8); }
18491862
| INSERT OR REPLACE Into Table ValuesListsList OutputClause

0 commit comments

Comments
 (0)