Skip to content
Prev Previous commit
Next Next commit
feat: Deparser for Expression Lists
Visit each Expression of a List instead ExpressionList.toString()
fixes #1608
  • Loading branch information
manticore-projects committed Nov 15, 2022
commit 695ba4ad69c7d3fbd4b07e0820db55322384ea29
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ public static String getStringList(List<?> list, boolean useComma, boolean useBr
*/
public static StringBuilder appendStringListTo(StringBuilder builder, List<?> list, boolean useComma, boolean useBrackets) {
if (list != null) {
String comma = useComma ? "," : "";
String comma = useComma ? ", " : " ";

if (useBrackets) {
builder.append("(");
Expand All @@ -581,7 +581,7 @@ public static StringBuilder appendStringListTo(StringBuilder builder, List<?> li
int size = list.size();
for (int i = 0; i < size; i++) {
builder.append(list.get(i)).append(i < size - 1
? comma + " "
? comma
: "");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public String toString() {
StringBuilder b = new StringBuilder();

b.append("(VALUES ");
for (Iterator<ExpressionList> it = getMultiExpressionList().getExprList().iterator(); it.
for (Iterator<ExpressionList> it = getMultiExpressionList().getExpressionLists().iterator(); it.
hasNext();) {
b.append(PlainSelect.getStringList(it.next().getExpressions(), true, !isNoBrackets()));
if (it.hasNext()) {
Expand All @@ -97,7 +97,7 @@ public String toString() {
}
b.append(")");
if (alias != null) {
b.append(alias.toString());
b.append(alias);

if (columnNames != null) {
b.append("(");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,19 +465,7 @@ public void visit(Function function) {

@Override
public void visit(ExpressionList expressionList) {
if (expressionList.isUsingBrackets()) {
buffer.append("(");
}
for (Iterator<Expression> iter = expressionList.getExpressions().iterator(); iter.hasNext();) {
Expression expression = iter.next();
expression.accept(this);
if (iter.hasNext()) {
buffer.append(", ");
}
}
if (expressionList.isUsingBrackets()) {
buffer.append(")");
}
new ExpressionListDeParser(this, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
}

@Override
Expand Down Expand Up @@ -840,7 +828,8 @@ public void visit(MySQLGroupConcat groupConcat) {

@Override
public void visit(ValueListExpression valueList) {
buffer.append(valueList.toString());
ExpressionList expressionList = valueList.getExpressionList();
expressionList.accept(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2019 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.util.deparser;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;

import java.util.Collection;

public class ExpressionListDeParser extends AbstractDeParser<Collection<Expression>> {

private final ExpressionVisitor expressionVisitor;
private final boolean useBrackets;
private final boolean useComma;

public ExpressionListDeParser(ExpressionVisitor expressionVisitor, StringBuilder builder, boolean useBrackets, boolean useComma) {
super(builder);
this.expressionVisitor = expressionVisitor;
this.useBrackets = useBrackets;
this.useComma = useComma;
}

@Override
public void deParse(Collection<Expression> expressions) {
if (expressions != null) {
String comma = useComma ? ", " : " ";
if (useBrackets) {
buffer.append("(");
}
int i=0;
int size = expressions.size() - 1;
for (Expression expression: expressions) {
expression.accept(expressionVisitor);
if (i<size) {
buffer.append(comma);
}
i++;
}

if (useBrackets) {
buffer.append(")");
}
}
}
}
34 changes: 12 additions & 22 deletions src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package net.sf.jsqlparser.util.deparser;

import java.util.Iterator;
import java.util.List;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
Expand All @@ -20,6 +21,7 @@
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.WithItem;
Expand Down Expand Up @@ -93,7 +95,8 @@ public void deParse(Insert insert) {
}
buffer.append(" ");
}
insert.getSelect().getSelectBody().accept(selectVisitor);
SelectBody selectBody = insert.getSelect().getSelectBody();
selectBody.accept(selectVisitor);
if (insert.getSelect().isUsingWithBrackets()) {
buffer.append(")");
}
Expand Down Expand Up @@ -147,15 +150,7 @@ public void deParse(Insert insert) {

@Override
public void visit(ExpressionList expressionList) {
buffer.append(" VALUES (");
for (Iterator<Expression> iter = expressionList.getExpressions().iterator(); iter.hasNext();) {
Expression expression = iter.next();
expression.accept(expressionVisitor);
if (iter.hasNext()) {
buffer.append(", ");
}
}
buffer.append(")");
new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
}

@Override
Expand All @@ -165,20 +160,15 @@ public void visit(NamedExpressionList NamedExpressionList) {

@Override
public void visit(MultiExpressionList multiExprList) {
buffer.append(" VALUES ");
for (Iterator<ExpressionList> it = multiExprList.getExprList().iterator(); it.hasNext();) {
buffer.append("(");
for (Iterator<Expression> iter = it.next().getExpressions().iterator(); iter.hasNext();) {
Expression expression = iter.next();
expression.accept(expressionVisitor);
if (iter.hasNext()) {
buffer.append(", ");
}
}
buffer.append(")");
if (it.hasNext()) {
List<ExpressionList> expressionLists = multiExprList.getExpressionLists();
int n = expressionLists.size() - 1;
int i = 0;
for (ExpressionList expressionList : expressionLists) {
new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
if (i<n) {
buffer.append(", ");
}
i++;
}
}

Expand Down
56 changes: 53 additions & 3 deletions src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,32 @@ public void visit(LateralSubSelect lateralSubSelect) {

@Override
public void visit(ValuesList valuesList) {
buffer.append(valuesList.toString());
buffer.append("(VALUES ");
List<ExpressionList> expressionLists = valuesList.getMultiExpressionList().getExpressionLists();
int n = expressionLists.size() - 1;
int i = 0;
for (ExpressionList expressionList : expressionLists) {
new ExpressionListDeParser(expressionVisitor, buffer, !valuesList.isNoBrackets(), true).deParse(expressionList.getExpressions());
if (i<n) {
buffer.append(", ");
}
i++;
}
buffer.append(")");
if (valuesList.getAlias() != null) {
buffer.append(valuesList.getAlias());

if (valuesList.getColumnNames() != null) {
buffer.append("(");
for (Iterator<String> it = valuesList.getColumnNames().iterator(); it.hasNext();) {
buffer.append(it.next());
if (it.hasNext()) {
buffer.append(", ");
}
}
buffer.append(")");
}
}
}

@Override
Expand Down Expand Up @@ -577,16 +602,41 @@ void deParse(PlainSelect statement) {

@Override
public void visit(ExpressionList expressionList) {
buffer.append(expressionList.toString());
new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
}

@Override
public void visit(NamedExpressionList namedExpressionList) {
buffer.append(namedExpressionList.toString());

buffer.append("(");
List<Expression> expressions = namedExpressionList.getExpressions();
List<String> names = namedExpressionList.getNames();
for (int i = 0; i < expressions.size(); i++) {
Expression expression = expressions.get(i);
String name = names.get(i);
if (i > 0) {
buffer.append(" ");
}
if (!name.equals("")) {
buffer.append(name).append(" ");
}
expression.accept(expressionVisitor);
}
buffer.append(")");
}

@Override
public void visit(MultiExpressionList multiExprList) {
buffer.append(multiExprList.toString());
List<ExpressionList> expressionLists = multiExprList.getExpressionLists();
int n = expressionLists.size() - 1;
int i = 0;
for (ExpressionList expressionList : expressionLists) {
new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
if (i<n) {
buffer.append(", ");
}
i++;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.List;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
Expand All @@ -27,6 +29,7 @@
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import net.sf.jsqlparser.statement.upsert.Upsert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -381,4 +384,33 @@ public void testIssue1500AllTableColumns() throws JSQLParserException {
PlainSelect selectBody = (PlainSelect) select.getSelectBody();
selectBody.accept(new SelectDeParser());
}

@Test
public void testIssue1608DeparseValueList() throws JSQLParserException {
String providedSql ="INSERT INTO example (num, name, address, tel) VALUES (1, 'name', 'test ', '1234-1234')";
String expectedSql ="INSERT INTO example (num, name, address, tel) VALUES (?, ?, ?, ?)";

net.sf.jsqlparser.statement.Statement statement = CCJSqlParserUtil.parse(providedSql);
StringBuilder builder = new StringBuilder();
ExpressionDeParser expressionDeParser = new ExpressionDeParser() {
@Override
public void visit(StringValue stringValue) {
buffer.append("?");
}

@Override
public void visit(LongValue longValue) {
buffer.append("?");
}
};

SelectDeParser selectDeParser = new SelectDeParser(expressionDeParser, builder);
expressionDeParser.setSelectVisitor(selectDeParser);
expressionDeParser.setBuffer(builder);

StatementDeParser statementDeParser = new StatementDeParser(expressionDeParser, selectDeParser, builder);
statement.accept(statementDeParser);

Assertions.assertEquals(expectedSql, builder.toString());
}
}