@@ -36,6 +36,14 @@ public enum JsonTableOnErrorType {
3636 ERROR , NULL , EMPTY
3737 }
3838
39+ public enum JsonTableOnEmptyType {
40+ ERROR , NULL , EMPTY
41+ }
42+
43+ public enum JsonTableParsingType {
44+ STRICT , LAX
45+ }
46+
3947 public static class JsonTablePassingClause extends ASTNodeAccessImpl implements Serializable {
4048 private Expression valueExpression ;
4149 private String parameterName ;
@@ -78,10 +86,28 @@ public String toString() {
7886 }
7987
8088 public static class JsonTableWrapperClause extends ASTNodeAccessImpl implements Serializable {
89+ private boolean beforePathExpression ;
8190 private JsonFunction .JsonWrapperType wrapperType ;
8291 private JsonFunction .JsonWrapperMode wrapperMode ;
8392 private boolean array ;
8493
94+ /**
95+ * Creates a wrapper clause. Depending on the dialect, this clause can come before or after the PATH expression.
96+ * <ul>
97+ * <li>Trino: after PATH</li>
98+ * <li>Oracle: before PATH</li>
99+ * </ul>
100+ *
101+ * @param beforePathExpression A flag to determine wether the clause is rendered before or after the PATH expression
102+ */
103+ public JsonTableWrapperClause (boolean beforePathExpression ) {
104+ this .beforePathExpression = beforePathExpression ;
105+ }
106+
107+ public boolean isBeforePathExpression () {
108+ return beforePathExpression ;
109+ }
110+
85111 public JsonFunction .JsonWrapperType getWrapperType () {
86112 return wrapperType ;
87113 }
@@ -159,6 +185,15 @@ public String toString() {
159185
160186 public static class JsonTableOnErrorClause extends ASTNodeAccessImpl implements Serializable {
161187 private JsonTableOnErrorType type ;
188+ private boolean beforeColumns = true ;
189+
190+ public JsonTableOnErrorClause (boolean beforeColumns ) {
191+ this .beforeColumns = beforeColumns ;
192+ }
193+
194+ public boolean isBeforeColumns () {
195+ return beforeColumns ;
196+ }
162197
163198 public JsonTableOnErrorType getType () {
164199 return type ;
@@ -175,6 +210,48 @@ public String toString() {
175210 }
176211 }
177212
213+ public static class JsonTableOnEmptyClause extends ASTNodeAccessImpl implements Serializable {
214+ private JsonTableOnEmptyType type ;
215+
216+ public JsonTableOnEmptyClause () {
217+ }
218+
219+ public JsonTableOnEmptyType getType () {
220+ return type ;
221+ }
222+
223+ public JsonTableOnEmptyClause setType (JsonTableOnEmptyType type ) {
224+ this .type = type ;
225+ return this ;
226+ }
227+
228+ @ Override
229+ public String toString () {
230+ return type + " ON EMPTY" ;
231+ }
232+ }
233+
234+ public static class JsonTableParsingTypeClause extends ASTNodeAccessImpl implements Serializable {
235+ private JsonTableParsingType type ;
236+
237+ public JsonTableParsingTypeClause () {
238+ }
239+
240+ public JsonTableParsingType getType () {
241+ return type ;
242+ }
243+
244+ public JsonTableParsingTypeClause setType (JsonTableParsingType type ) {
245+ this .type = type ;
246+ return this ;
247+ }
248+
249+ @ Override
250+ public String toString () {
251+ return "TYPE(" + type + ")" ;
252+ }
253+ }
254+
178255 public static class JsonTablePlanTerm extends ASTNodeAccessImpl implements Serializable {
179256 private JsonTablePlanExpression nestedPlanExpression ;
180257 private String name ;
@@ -532,10 +609,13 @@ public String toString() {
532609 builder .append (scalarsType );
533610 builder .append (" SCALARS" );
534611 }
612+ if (wrapperClause != null && wrapperClause .isBeforePathExpression ()) {
613+ builder .append (" " ).append (wrapperClause );
614+ }
535615 if (pathExpression != null ) {
536616 builder .append (" PATH " ).append (pathExpression );
537617 }
538- if (wrapperClause != null ) {
618+ if (wrapperClause != null && ! wrapperClause . isBeforePathExpression () ) {
539619 builder .append (" " ).append (wrapperClause );
540620 }
541621 if (quotesClause != null ) {
@@ -595,11 +675,23 @@ public String toString() {
595675 private JsonTableColumnsClause columnsClause ;
596676 private JsonTablePlanClause planClause ;
597677 private JsonTableOnErrorClause onErrorClause ;
678+ private JsonTableParsingTypeClause parsingTypeClause ;
679+ private JsonTableOnEmptyClause onEmptyClause ;
680+ private boolean formatJson ;
598681
599682 public JsonTableFunction () {
600683 setName ("JSON_TABLE" );
601684 }
602685
686+ public boolean getFormatJson () {
687+ return formatJson ;
688+ }
689+
690+ public JsonTableFunction setFormatJson (boolean formatJson ) {
691+ this .formatJson = formatJson ;
692+ return this ;
693+ }
694+
603695 public Expression getJsonInputExpression () {
604696 return jsonInputExpression ;
605697 }
@@ -663,6 +755,24 @@ public JsonTableFunction setOnErrorClause(JsonTableOnErrorClause onErrorClause)
663755 return this ;
664756 }
665757
758+ public JsonTableParsingTypeClause getParsingTypeClause () {
759+ return parsingTypeClause ;
760+ }
761+
762+ public JsonTableFunction setParsingTypeClause (JsonTableParsingTypeClause parsingTypeClause ) {
763+ this .parsingTypeClause = parsingTypeClause ;
764+ return this ;
765+ }
766+
767+ public JsonTableOnEmptyClause getOnEmptyClause () {
768+ return onEmptyClause ;
769+ }
770+
771+ public JsonTableFunction setOnEmptyClause (JsonTableOnEmptyClause onEmptyClause ) {
772+ this .onEmptyClause = onEmptyClause ;
773+ return this ;
774+ }
775+
666776 public List <Expression > getAllExpressions () {
667777 List <Expression > expressions = new ArrayList <>();
668778 if (jsonInputExpression != null ) {
@@ -692,6 +802,9 @@ public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
692802 public String toString () {
693803 StringBuilder builder = new StringBuilder ("JSON_TABLE(" );
694804 builder .append (jsonInputExpression );
805+ if (formatJson ) {
806+ builder .append (" FORMAT JSON" );
807+ }
695808 if (jsonPathExpression != null ) {
696809 builder .append (", " ).append (jsonPathExpression );
697810 }
@@ -709,11 +822,20 @@ public String toString() {
709822 first = false ;
710823 }
711824 }
825+ if (onErrorClause != null && onErrorClause .isBeforeColumns ()) {
826+ builder .append (" " ).append (onErrorClause );
827+ }
828+ if (parsingTypeClause != null ) {
829+ builder .append (" " ).append (parsingTypeClause );
830+ }
831+ if (onEmptyClause != null ) {
832+ builder .append (" " ).append (onEmptyClause );
833+ }
712834 builder .append (" " ).append (columnsClause );
713835 if (planClause != null ) {
714836 builder .append (" " ).append (planClause );
715837 }
716- if (onErrorClause != null ) {
838+ if (onErrorClause != null && ! onErrorClause . isBeforeColumns () ) {
717839 builder .append (" " ).append (onErrorClause );
718840 }
719841 builder .append (")" );
0 commit comments