diff --git a/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java b/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java index 9d2131555..f13f1b07c 100644 --- a/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java +++ b/src/main/java/net/sf/jsqlparser/parser/feature/Feature.java @@ -457,7 +457,7 @@ public enum Feature { */ oracleBlock, - execute, executeExec, executeCall, executeExecute, doStatement, + execute, executeExec, executeCall, executeExecute, doStatement, insertBulk, /** * SQL "EXECUTE" statement is allowed diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java b/src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java index 7f13f5efc..7ee627c3e 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java @@ -61,6 +61,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.imprt.Import; import net.sf.jsqlparser.statement.insert.Insert; +import net.sf.jsqlparser.statement.insert.InsertBulk; import net.sf.jsqlparser.statement.lock.LockStatement; import net.sf.jsqlparser.statement.merge.Merge; import net.sf.jsqlparser.statement.refresh.RefreshMaterializedViewStatement; @@ -392,6 +393,13 @@ public Void visit(Insert insert, S context) { return super.visit(insert, context); } + @Override + public Void visit(InsertBulk statement, S context) { + analysis.claimTopLevel(); + analysis.certain(StmtFeature.MODIFIES_DATA); + return super.visit(statement, context); + } + @Override public Void visit(Update update, S context) { boolean topLevel = analysis.claimTopLevel(); diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java index 2001533ae..efc42f5ba 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java @@ -56,6 +56,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.imprt.Import; import net.sf.jsqlparser.statement.insert.Insert; +import net.sf.jsqlparser.statement.insert.InsertBulk; import net.sf.jsqlparser.statement.insert.ParenthesedInsert; import net.sf.jsqlparser.statement.lock.LockStatement; import net.sf.jsqlparser.statement.merge.Merge; @@ -70,6 +71,14 @@ public interface StatementVisitor { + default T visit(InsertBulk statement, S context) { + return null; + } + + default void visit(InsertBulk statement) { + this.visit(statement, null); + } + T visit(Analyze analyze, S context); default void visit(Analyze analyze) { diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java index e633adebb..d39ccb8b2 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java @@ -62,6 +62,7 @@ import net.sf.jsqlparser.statement.grant.Grant; import net.sf.jsqlparser.statement.imprt.Import; import net.sf.jsqlparser.statement.insert.Insert; +import net.sf.jsqlparser.statement.insert.InsertBulk; import net.sf.jsqlparser.statement.insert.InsertConflictAction; import net.sf.jsqlparser.statement.insert.ParenthesedInsert; import net.sf.jsqlparser.statement.lock.LockStatement; @@ -314,6 +315,13 @@ private T visitReturningClause(ReturningClause returningClause, S context) { return null; } + @Override + public T visit(InsertBulk statement, S context) { + fromItemVisitor.visitFromItem(statement.getTable(), context); + statement.visitExpressions(expression -> expression.accept(expressionVisitor, context)); + return null; + } + @Override public T visit(ParenthesedInsert insert, S context) { insert.getInsert().accept(this, context); diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/InsertBulk.java b/src/main/java/net/sf/jsqlparser/statement/insert/InsertBulk.java new file mode 100644 index 000000000..8464a4fa9 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/insert/InsertBulk.java @@ -0,0 +1,162 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2026 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.insert; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.StatementVisitor; +import net.sf.jsqlparser.statement.create.table.ColumnDefinition; +import net.sf.jsqlparser.statement.select.OrderByElement; + +/** SQL Server's SQL declaration preceding a separate bulk-load data stream. */ +public class InsertBulk implements Statement { + private Table table; + private List columns = new ArrayList<>(); + private List