From c032744b9e083e0327caa0190d32783ac4060ed1 Mon Sep 17 00:00:00 2001 From: wumpz Date: Fri, 5 Oct 2018 00:29:11 +0200 Subject: [PATCH] integrated values statement --- .../statement/StatementVisitor.java | 2 + .../statement/StatementVisitorAdapter.java | 5 ++ .../statement/values/ValuesStatement.java | 61 +++++++++++++++++++ .../sf/jsqlparser/util/TablesNamesFinder.java | 8 +++ .../util/deparser/StatementDeParser.java | 7 +++ .../deparser/ValuesStatementDeParser.java | 59 ++++++++++++++++++ .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 17 ++++++ .../statement/values/ValuesTest.java | 13 ++++ 8 files changed, 172 insertions(+) create mode 100644 src/main/java/net/sf/jsqlparser/statement/values/ValuesStatement.java create mode 100644 src/main/java/net/sf/jsqlparser/util/deparser/ValuesStatementDeParser.java create mode 100644 src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java index 34662c7f5..52790a462 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java @@ -36,6 +36,7 @@ import net.sf.jsqlparser.statement.truncate.Truncate; import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.upsert.Upsert; +import net.sf.jsqlparser.statement.values.ValuesStatement; public interface StatementVisitor { @@ -79,4 +80,5 @@ public interface StatementVisitor { void visit(Block block); + void visit(ValuesStatement values); } diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java index 63d1c85ba..fcc1188d0 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java @@ -36,6 +36,7 @@ import net.sf.jsqlparser.statement.truncate.Truncate; import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.upsert.Upsert; +import net.sf.jsqlparser.statement.values.ValuesStatement; public class StatementVisitorAdapter implements StatementVisitor { @@ -136,4 +137,8 @@ public void visit(UseStatement use) { @Override public void visit(Block block) { } + + @Override + public void visit(ValuesStatement values) { + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/values/ValuesStatement.java b/src/main/java/net/sf/jsqlparser/statement/values/ValuesStatement.java new file mode 100644 index 000000000..eebf4702d --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/values/ValuesStatement.java @@ -0,0 +1,61 @@ +/* + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2013 JSQLParser + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ +package net.sf.jsqlparser.statement.values; + +import java.util.List; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.StatementVisitor; +import net.sf.jsqlparser.statement.select.PlainSelect; + +/** + * The replace statement. + */ +public class ValuesStatement implements Statement { + + private List expressions; + + public ValuesStatement(List expressions) { + this.expressions = expressions; + } + + @Override + public void accept(StatementVisitor statementVisitor) { + statementVisitor.visit(this); + } + + public List getExpressions() { + return expressions; + } + + public void setExpressions(List list) { + expressions = list; + } + + @Override + public String toString() { + StringBuilder sql = new StringBuilder(); + sql.append("VALUES "); + sql.append(PlainSelect.getStringList(expressions, true, true)); + return sql.toString(); + } +} diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java index 991dbb95e..f3fbd7a1c 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -132,6 +132,7 @@ import net.sf.jsqlparser.statement.truncate.Truncate; import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.upsert.Upsert; +import net.sf.jsqlparser.statement.values.ValuesStatement; /** * Find all used tables within an select statement. @@ -811,4 +812,11 @@ public void visit(Block block) { visit(block.getStatements()); } } + + @Override + public void visit(ValuesStatement values) { + for (Expression expr : values.getExpressions()) { + expr.accept(this); + } + } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java index bf427c3c6..4d9a6667f 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -45,6 +45,7 @@ import net.sf.jsqlparser.statement.truncate.Truncate; import net.sf.jsqlparser.statement.update.Update; import net.sf.jsqlparser.statement.upsert.Upsert; +import net.sf.jsqlparser.statement.values.ValuesStatement; public class StatementDeParser implements StatementVisitor { @@ -240,4 +241,10 @@ public void visit(Block block) { } buffer.append("END"); } + + @Override + public void visit(ValuesStatement values) { + expressionDeParser.setBuffer(buffer); + new ValuesStatementDeParser(expressionDeParser, buffer).deParse(values); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/ValuesStatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/ValuesStatementDeParser.java new file mode 100644 index 000000000..894455935 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/util/deparser/ValuesStatementDeParser.java @@ -0,0 +1,59 @@ +/* + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2017 JSQLParser + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ +package net.sf.jsqlparser.util.deparser; + +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.ExpressionVisitor; +import net.sf.jsqlparser.statement.values.ValuesStatement; + +public class ValuesStatementDeParser { + + private StringBuilder buffer; + private final ExpressionVisitor expressionVisitor; + + public ValuesStatementDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer) { + this.buffer = buffer; + this.expressionVisitor = expressionVisitor; + } + + public StringBuilder getBuffer() { + return buffer; + } + + public void setBuffer(StringBuilder buffer) { + this.buffer = buffer; + } + + public void deParse(ValuesStatement values) { + boolean first = true; + buffer.append("VALUES ("); + for (Expression expr : values.getExpressions()) { + if (first) { + first = false; + } else { + buffer.append(", "); + } + expr.accept(expressionVisitor); + } + buffer.append(")"); + } +} diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index e59e663d0..0b4c20246 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -83,6 +83,7 @@ import net.sf.jsqlparser.statement.truncate.*; import net.sf.jsqlparser.statement.update.*; import net.sf.jsqlparser.statement.upsert.*; import net.sf.jsqlparser.statement.merge.*; +import net.sf.jsqlparser.statement.values.*; import java.util.*; /** @@ -379,6 +380,8 @@ Statement SingleStatement() : LOOKAHEAD(3) stm = Select() | + stm = Values() + | stm = Update() | stm = Insert() @@ -515,6 +518,20 @@ UseStatement Use(): { } } +ValuesStatement Values(): { + List expList = new ArrayList(); + Expression exp; +} { + + "(" + exp=PrimaryExpression() { expList.add(exp); } + ("," exp=PrimaryExpression() { expList.add(exp); } )* + ")" + { + return new ValuesStatement(expList); + } +} + Update Update(): { Update update = new Update(); diff --git a/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java b/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java new file mode 100644 index 000000000..d18413d20 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java @@ -0,0 +1,13 @@ +package net.sf.jsqlparser.statement.values; + +import net.sf.jsqlparser.JSQLParserException; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import org.junit.Test; + +public class ValuesTest { + + @Test + public void testDuplicateKey() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("VALUES (1, 2, 'test')"); + } +}