From 833a01de9b4eabf961ff556bc3d1dfe8efed35d5 Mon Sep 17 00:00:00 2001 From: tanjiro Kamado Date: Mon, 26 Oct 2026 20:25:27 +0530 Subject: [PATCH] avoid quadratic string concatenation in FullTextSearch.toString --- .../operators/relational/FullTextSearch.java | 6 ++--- .../FullTextSearchExpressionTest.java | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearch.java b/src/main/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearch.java index 0bf79f0ec8..8c1a8d97ef 100644 --- a/src/main/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearch.java +++ b/src/main/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearch.java @@ -75,13 +75,13 @@ public T accept(ExpressionVisitor expressionVisitor, S context) { @Override public String toString() { // Build a list of matched columns - String columnsListCommaSeperated = ""; + StringBuilder columnsListCommaSeperated = new StringBuilder(); Iterator iterator = this._matchColumns.iterator(); while (iterator.hasNext()) { Column col = iterator.next(); - columnsListCommaSeperated += col.getFullyQualifiedName(); + columnsListCommaSeperated.append(col.getFullyQualifiedName()); if (iterator.hasNext()) { - columnsListCommaSeperated += ","; + columnsListCommaSeperated.append(","); } } diff --git a/src/test/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearchExpressionTest.java b/src/test/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearchExpressionTest.java index 8a1c61714c..ee39216196 100644 --- a/src/test/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearchExpressionTest.java +++ b/src/test/java/net/sf/jsqlparser/expression/operators/relational/FullTextSearchExpressionTest.java @@ -9,7 +9,15 @@ */ package net.sf.jsqlparser.expression.operators.relational; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.StringValue; +import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.test.TestUtils; import org.junit.jupiter.api.Test; @@ -35,4 +43,18 @@ public void testIssue1223() throws JSQLParserException { + "full_text desc", true); } + + @Test + public void testToStringIsLinearInMatchColumns() { + List columns = new ArrayList<>(); + for (int i = 0; i < 200_000; i++) { + columns.add(new Column("c" + i)); + } + FullTextSearch fullTextSearch = new FullTextSearch() + .withMatchColumns(new ExpressionList<>(columns)) + .withAgainstValue(new StringValue("x")); + + String sql = assertTimeoutPreemptively(Duration.ofSeconds(2), fullTextSearch::toString); + assertThat(sql).startsWith("MATCH (c0,c1,").endsWith(",c199999) AGAINST ('x')"); + } }