Skip to content

Commit 1e02ab3

Browse files
committed
Render JSON children through the configured expression deparser
Share callback-based rendering for JSON functions and JSON_TABLE so custom deparsers can rewrite structured inputs, paths, defaults, passing values, and plan expressions. Preserve opaque and incomplete-builder output, and document the rendering hooks for subclasses. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent cdbaf1a commit 1e02ab3

7 files changed

Lines changed: 582 additions & 67 deletions

File tree

‎src/main/java/net/sf/jsqlparser/expression/JsonFunction.java‎

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.ArrayList;
1313
import java.util.Locale;
1414
import java.util.Objects;
15+
import java.util.function.Consumer;
1516

1617
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
1718
import net.sf.jsqlparser.statement.create.table.ColDataType;
@@ -77,6 +78,11 @@ public void setExpression(Expression expression) {
7778
}
7879

7980
public StringBuilder append(StringBuilder builder) {
81+
return appendTo(builder, builder::append);
82+
}
83+
84+
public StringBuilder appendTo(StringBuilder builder,
85+
Consumer<Expression> expressionPrinter) {
8086
switch (type) {
8187
case ERROR:
8288
builder.append("ERROR");
@@ -85,7 +91,12 @@ public StringBuilder append(StringBuilder builder) {
8591
builder.append("NULL");
8692
break;
8793
case DEFAULT:
88-
builder.append("DEFAULT ").append(expression);
94+
builder.append("DEFAULT ");
95+
if (expression == null) {
96+
builder.append("null");
97+
} else {
98+
expressionPrinter.accept(expression);
99+
}
89100
break;
90101
case EMPTY:
91102
builder.append("EMPTY ");
@@ -389,39 +400,49 @@ public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
389400

390401
// avoid countless Builder --> String conversion
391402
public StringBuilder append(StringBuilder builder) {
403+
return appendTo(builder, builder::append);
404+
}
405+
406+
/** Renders structured children through the supplied expression printer. */
407+
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
392408
switch (functionType) {
393409
case OBJECT:
394410
case POSTGRES_OBJECT:
395411
case MYSQL_OBJECT:
396-
appendObject(builder);
412+
appendObject(builder, expressionPrinter);
397413
break;
398414
case ARRAY:
399-
appendArray(builder);
415+
appendArray(builder, expressionPrinter);
400416
break;
401417
case VALUE:
402-
appendValue(builder);
418+
appendValue(builder, expressionPrinter);
403419
break;
404420
case QUERY:
405-
appendQuery(builder);
421+
appendQuery(builder, expressionPrinter);
406422
break;
407423
case EXISTS:
408-
appendExists(builder);
424+
appendExists(builder, expressionPrinter);
409425
break;
410426
default:
411427
// this should never happen really
412428
}
413429
return builder;
414430
}
415431

416-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
417432
public StringBuilder appendObject(StringBuilder builder) {
433+
return appendObject(builder, builder::append);
434+
}
435+
436+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
437+
public StringBuilder appendObject(StringBuilder builder,
438+
Consumer<Expression> expressionPrinter) {
418439
builder.append("JSON_OBJECT( ");
419440
int i = 0;
420441
for (JsonKeyValuePair keyValuePair : keyValuePairs) {
421442
if (i > 0) {
422443
builder.append(", ");
423444
}
424-
keyValuePair.append(builder);
445+
keyValuePair.appendTo(builder, expressionPrinter);
425446
i++;
426447
}
427448

@@ -467,16 +488,21 @@ private void appendUniqueKeys(StringBuilder builder) {
467488
}
468489
}
469490

470-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
471491
public StringBuilder appendArray(StringBuilder builder) {
492+
return appendArray(builder, builder::append);
493+
}
494+
495+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
496+
public StringBuilder appendArray(StringBuilder builder,
497+
Consumer<Expression> expressionPrinter) {
472498
builder.append("JSON_ARRAY( ");
473499
int i = 0;
474500

475501
for (JsonFunctionExpression expr : expressions) {
476502
if (i > 0) {
477503
builder.append(", ");
478504
}
479-
expr.append(builder);
505+
expr.appendTo(builder, expressionPrinter);
480506
i++;
481507
}
482508

@@ -487,33 +513,43 @@ public StringBuilder appendArray(StringBuilder builder) {
487513
return builder;
488514
}
489515

490-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
491516
public StringBuilder appendValue(StringBuilder builder) {
517+
return appendValue(builder, builder::append);
518+
}
519+
520+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
521+
public StringBuilder appendValue(StringBuilder builder,
522+
Consumer<Expression> expressionPrinter) {
492523
builder.append("JSON_VALUE(");
493-
appendValueOrQueryPrefix(builder);
524+
appendValueOrQueryPrefix(builder, expressionPrinter);
494525

495526
if (returningType != null) {
496527
builder.append(" RETURNING ").append(returningType);
497528
}
498529

499-
appendOnResponseClause(builder, onEmptyBehavior, "EMPTY");
500-
appendOnResponseClause(builder, onErrorBehavior, "ERROR");
530+
appendOnResponseClause(builder, onEmptyBehavior, "EMPTY", expressionPrinter);
531+
appendOnResponseClause(builder, onErrorBehavior, "ERROR", expressionPrinter);
501532

502533
builder.append(")");
503534
return builder;
504535
}
505536

506-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
507537
public StringBuilder appendQuery(StringBuilder builder) {
538+
return appendQuery(builder, builder::append);
539+
}
540+
541+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
542+
public StringBuilder appendQuery(StringBuilder builder,
543+
Consumer<Expression> expressionPrinter) {
508544
builder.append("JSON_QUERY(");
509-
appendValueOrQueryPrefix(builder);
545+
appendValueOrQueryPrefix(builder, expressionPrinter);
510546

511547
appendReturningClause(builder, true);
512548

513549
appendWrapperClause(builder);
514550
appendQuotesClause(builder);
515-
appendOnResponseClause(builder, onEmptyBehavior, "EMPTY");
516-
appendOnResponseClause(builder, onErrorBehavior, "ERROR");
551+
appendOnResponseClause(builder, onEmptyBehavior, "EMPTY", expressionPrinter);
552+
appendOnResponseClause(builder, onErrorBehavior, "ERROR", expressionPrinter);
517553

518554
for (String additionalQueryPathArgument : additionalQueryPathArguments) {
519555
builder.append(", ").append(additionalQueryPathArgument);
@@ -523,25 +559,31 @@ public StringBuilder appendQuery(StringBuilder builder) {
523559
return builder;
524560
}
525561

526-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
527562
public StringBuilder appendExists(StringBuilder builder) {
563+
return appendExists(builder, builder::append);
564+
}
565+
566+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
567+
public StringBuilder appendExists(StringBuilder builder,
568+
Consumer<Expression> expressionPrinter) {
528569
builder.append("JSON_EXISTS(");
529-
appendValueOrQueryPrefix(builder);
530-
appendOnResponseClause(builder, onErrorBehavior, "ERROR");
570+
appendValueOrQueryPrefix(builder, expressionPrinter);
571+
appendOnResponseClause(builder, onErrorBehavior, "ERROR", expressionPrinter);
531572
builder.append(")");
532573
return builder;
533574
}
534575

535-
private void appendValueOrQueryPrefix(StringBuilder builder) {
576+
private void appendValueOrQueryPrefix(StringBuilder builder,
577+
Consumer<Expression> expressionPrinter) {
536578
if (inputExpression != null) {
537-
inputExpression.append(builder);
579+
inputExpression.appendTo(builder, expressionPrinter);
538580
}
539581

540582
if (jsonPathExpression != null) {
541583
if (inputExpression != null) {
542584
builder.append(", ");
543585
}
544-
builder.append(jsonPathExpression);
586+
expressionPrinter.accept(jsonPathExpression);
545587
}
546588

547589
if (!passingExpressions.isEmpty()) {
@@ -553,16 +595,20 @@ private void appendValueOrQueryPrefix(StringBuilder builder) {
553595
} else {
554596
comma = true;
555597
}
556-
builder.append(passingExpression);
598+
if (passingExpression == null) {
599+
builder.append("null");
600+
} else {
601+
expressionPrinter.accept(passingExpression);
602+
}
557603
}
558604
}
559605
}
560606

561607
private void appendOnResponseClause(StringBuilder builder, JsonOnResponseBehavior behavior,
562-
String clause) {
608+
String clause, Consumer<Expression> expressionPrinter) {
563609
if (behavior != null) {
564610
builder.append(" ");
565-
behavior.append(builder);
611+
behavior.appendTo(builder, expressionPrinter);
566612
builder.append(" ON ").append(clause);
567613
}
568614
}

‎src/main/java/net/sf/jsqlparser/expression/JsonFunctionExpression.java‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import java.io.Serializable;
1414
import java.util.Objects;
15+
import java.util.function.Consumer;
1516

1617
/**
1718
* @author <a href="mailto:andreas@manticore-projects.com">Andreas Reichel</a>
@@ -58,7 +59,11 @@ public JsonFunctionExpression withEncoding(String encoding) {
5859
}
5960

6061
public StringBuilder append(StringBuilder builder) {
61-
builder.append(getExpression());
62+
return appendTo(builder, builder::append);
63+
}
64+
65+
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
66+
expressionPrinter.accept(getExpression());
6267
if (isUsingFormatJson()) {
6368
builder.append(" FORMAT JSON");
6469
if (encoding != null) {

‎src/main/java/net/sf/jsqlparser/expression/JsonKeyValuePair.java‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import java.io.Serializable;
1414
import java.util.Objects;
15+
import java.util.function.Consumer;
1516

1617
/**
1718
* @author <a href="mailto:andreas@manticore-projects.com">Andreas Reichel</a>
@@ -153,14 +154,18 @@ public Object getValue() {
153154
}
154155

155156
public StringBuilder append(StringBuilder builder) {
157+
return appendTo(builder, builder::append);
158+
}
159+
160+
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
156161
if (isUsingKeyKeyword() && getSeparator() == JsonKeyValuePairSeparator.VALUE) {
157162
builder.append("KEY ");
158163
}
159-
builder.append(getKey());
164+
appendValue(builder, getKey(), expressionPrinter);
160165

161166
if (getValue() != null) {
162167
builder.append(getSeparator().getSeparatorString());
163-
builder.append(getValue());
168+
appendValue(builder, getValue(), expressionPrinter);
164169
}
165170

166171
if (isUsingFormatJson()) {
@@ -173,6 +178,15 @@ public StringBuilder append(StringBuilder builder) {
173178
return builder;
174179
}
175180

181+
private static void appendValue(StringBuilder builder, Object value,
182+
Consumer<Expression> expressionPrinter) {
183+
if (value instanceof Expression) {
184+
expressionPrinter.accept((Expression) value);
185+
} else {
186+
builder.append(value);
187+
}
188+
}
189+
176190
@Override
177191
public String toString() {
178192
return append(new StringBuilder()).toString();

0 commit comments

Comments
 (0)