[jOOQ/jOOQ#11318] Add native support for the standard JSON function
RETURNING clause Added API and parser support for RETURNING on: - JSON_ARRAY - JSON_ARRAYAGG - JSON_OBJECT - JSON_OBJECTAGG - JSON_VALUE
This commit is contained in:
parent
753242b86c
commit
8da28a94c3
@ -55,19 +55,19 @@ import org.jooq.impl.DSL;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface JSONArrayAggNullStep<T> extends AggregateFilterStep<T> {
|
||||
public interface JSONArrayAggNullStep<T> extends JSONArrayAggReturningStep<T> {
|
||||
|
||||
/**
|
||||
* Include <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, POSTGRES })
|
||||
AggregateFilterStep<T> nullOnNull();
|
||||
JSONArrayAggReturningStep<T> nullOnNull();
|
||||
|
||||
/**
|
||||
* Exclude <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, POSTGRES })
|
||||
AggregateFilterStep<T> absentOnNull();
|
||||
JSONArrayAggReturningStep<T> absentOnNull();
|
||||
}
|
||||
|
||||
67
jOOQ/src/main/java/org/jooq/JSONArrayAggReturningStep.java
Normal file
67
jOOQ/src/main/java/org/jooq/JSONArrayAggReturningStep.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
/**
|
||||
* A step in the construction of {@link DSL#jsonArrayAgg(Field)} or
|
||||
* {@link DSL#jsonbArrayAgg(Field)} functions where the <code>RETURNING</code>
|
||||
* clause can be defined.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface JSONArrayAggReturningStep<T> extends AggregateFilterStep<T> {
|
||||
|
||||
/**
|
||||
* Add a <code>RETURNING</code> clause to the <code>JSON_ARRAYAGG</code>
|
||||
* function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, POSTGRES })
|
||||
AggregateFilterStep<T> returning(DataType<?> returning);
|
||||
}
|
||||
@ -37,40 +37,51 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
/**
|
||||
* A step in the construction of {@link DSL#jsonArray(Field...)} or
|
||||
* {@link DSL#jsonbArray(Field...)} functions where the <code>NULL</code> clause
|
||||
* can be defined.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* A step in the construction of the <code>JSON ARRAY</code> function.
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
* <p>
|
||||
* It is usually not recommended to reference any <code>XYZ*Step</code> types
|
||||
* directly from client code, or assign them to local variables. When writing
|
||||
* dynamic SQL, creating a statement's components dynamically, and passing them
|
||||
* to the DSL API statically is usually a better choice. See the manual's
|
||||
* section about dynamic SQL for details: <a href=
|
||||
* "https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql">https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql</a>.
|
||||
* <p>
|
||||
* Drawbacks of referencing the <code>XYZ*Step</code> types directly:
|
||||
* <ul>
|
||||
* <li>They're operating on mutable implementations (as of jOOQ 3.x)</li>
|
||||
* <li>They're less composable and not easy to get right when dynamic SQL gets
|
||||
* complex</li>
|
||||
* <li>They're less readable</li>
|
||||
* <li>They might have binary incompatible changes between minor releases</li>
|
||||
* </ul>
|
||||
*/
|
||||
public interface JSONArrayNullStep<T> extends Field<T> {
|
||||
@SuppressWarnings({ "unused" })
|
||||
public interface JSONArrayNullStep<T> extends JSONArrayReturningStep<T> {
|
||||
|
||||
/**
|
||||
* Add the <code>NULL ON NULL</code> clause to the <code>JSON ARRAY</code> function.
|
||||
* <p>
|
||||
* Include <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
Field<T> nullOnNull();
|
||||
@NotNull
|
||||
JSONArrayReturningStep<T> nullOnNull();
|
||||
|
||||
/**
|
||||
* Add the <code>ABSENT ON NULL</code> clause to the <code>JSON ARRAY</code> function.
|
||||
* <p>
|
||||
* Exclude <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, POSTGRES })
|
||||
Field<T> absentOnNull();
|
||||
@NotNull
|
||||
JSONArrayReturningStep<T> absentOnNull();
|
||||
}
|
||||
|
||||
76
jOOQ/src/main/java/org/jooq/JSONArrayReturningStep.java
Normal file
76
jOOQ/src/main/java/org/jooq/JSONArrayReturningStep.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
/**
|
||||
* A step in the construction of the <code>JSON ARRAY</code> function.
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
* <p>
|
||||
* It is usually not recommended to reference any <code>XYZ*Step</code> types
|
||||
* directly from client code, or assign them to local variables. When writing
|
||||
* dynamic SQL, creating a statement's components dynamically, and passing them
|
||||
* to the DSL API statically is usually a better choice. See the manual's
|
||||
* section about dynamic SQL for details: <a href=
|
||||
* "https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql">https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql</a>.
|
||||
* <p>
|
||||
* Drawbacks of referencing the <code>XYZ*Step</code> types directly:
|
||||
* <ul>
|
||||
* <li>They're operating on mutable implementations (as of jOOQ 3.x)</li>
|
||||
* <li>They're less composable and not easy to get right when dynamic SQL gets
|
||||
* complex</li>
|
||||
* <li>They're less readable</li>
|
||||
* <li>They might have binary incompatible changes between minor releases</li>
|
||||
* </ul>
|
||||
*/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public interface JSONArrayReturningStep<T> extends Field<T> {
|
||||
|
||||
/**
|
||||
* Add the <code>RETURNING</code> clause to the <code>JSON ARRAY</code> function.
|
||||
*/
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
@NotNull
|
||||
Field<T> returning(DataType<?> returning);
|
||||
}
|
||||
@ -58,19 +58,19 @@ import org.jooq.impl.DSL;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface JSONObjectAggNullStep<T> extends AggregateFilterStep<T> {
|
||||
public interface JSONObjectAggNullStep<T> extends JSONObjectAggReturningStep<T> {
|
||||
|
||||
/**
|
||||
* Include <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
AggregateFilterStep<T> nullOnNull();
|
||||
JSONObjectAggReturningStep<T> nullOnNull();
|
||||
|
||||
/**
|
||||
* Exclude <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
AggregateFilterStep<T> absentOnNull();
|
||||
JSONObjectAggReturningStep<T> absentOnNull();
|
||||
}
|
||||
|
||||
70
jOOQ/src/main/java/org/jooq/JSONObjectAggReturningStep.java
Normal file
70
jOOQ/src/main/java/org/jooq/JSONObjectAggReturningStep.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
/**
|
||||
* A step in the construction of {@link DSL#jsonObjectAgg(JSONEntry)} or
|
||||
* {@link DSL#jsonbObjectAgg(JSONEntry)} functions where the
|
||||
* <code>RETURNING</code> clause can be defined.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface JSONObjectAggReturningStep<T> extends AggregateFilterStep<T> {
|
||||
|
||||
/**
|
||||
* Add a <code>RETURNING</code> clause to the <code>JSON_ARRAYAGG</code>
|
||||
* function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
AggregateFilterStep<T> returning(DataType<?> returning);
|
||||
}
|
||||
@ -37,41 +37,51 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
// ...
|
||||
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
/**
|
||||
* A step in the construction of {@link DSL#jsonObject(JSONEntry...)} or
|
||||
* {@link DSL#jsonbObject(JSONEntry...)} functions where the <code>NULL</code>
|
||||
* clause can be defined.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* A step in the construction of the <code>JSON OBJECT</code> function.
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
* <p>
|
||||
* It is usually not recommended to reference any <code>XYZ*Step</code> types
|
||||
* directly from client code, or assign them to local variables. When writing
|
||||
* dynamic SQL, creating a statement's components dynamically, and passing them
|
||||
* to the DSL API statically is usually a better choice. See the manual's
|
||||
* section about dynamic SQL for details: <a href=
|
||||
* "https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql">https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql</a>.
|
||||
* <p>
|
||||
* Drawbacks of referencing the <code>XYZ*Step</code> types directly:
|
||||
* <ul>
|
||||
* <li>They're operating on mutable implementations (as of jOOQ 3.x)</li>
|
||||
* <li>They're less composable and not easy to get right when dynamic SQL gets
|
||||
* complex</li>
|
||||
* <li>They're less readable</li>
|
||||
* <li>They might have binary incompatible changes between minor releases</li>
|
||||
* </ul>
|
||||
*/
|
||||
public interface JSONObjectNullStep<T> extends Field<T> {
|
||||
@SuppressWarnings({ "unused" })
|
||||
public interface JSONObjectNullStep<T> extends JSONObjectReturningStep<T> {
|
||||
|
||||
/**
|
||||
* Add the <code>NULL ON NULL</code> clause to the <code>JSON OBJECT</code> function.
|
||||
* <p>
|
||||
* Include <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
Field<T> nullOnNull();
|
||||
@NotNull
|
||||
JSONObjectReturningStep<T> nullOnNull();
|
||||
|
||||
/**
|
||||
* Add the <code>ABSENT ON NULL</code> clause to the <code>JSON OBJECT</code> function.
|
||||
* <p>
|
||||
* Exclude <code>NULL</code> values in output JSON.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, POSTGRES })
|
||||
Field<T> absentOnNull();
|
||||
@NotNull
|
||||
JSONObjectReturningStep<T> absentOnNull();
|
||||
}
|
||||
|
||||
76
jOOQ/src/main/java/org/jooq/JSONObjectReturningStep.java
Normal file
76
jOOQ/src/main/java/org/jooq/JSONObjectReturningStep.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
/**
|
||||
* A step in the construction of the <code>JSON OBJECT</code> function.
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
* <p>
|
||||
* It is usually not recommended to reference any <code>XYZ*Step</code> types
|
||||
* directly from client code, or assign them to local variables. When writing
|
||||
* dynamic SQL, creating a statement's components dynamically, and passing them
|
||||
* to the DSL API statically is usually a better choice. See the manual's
|
||||
* section about dynamic SQL for details: <a href=
|
||||
* "https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql">https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql</a>.
|
||||
* <p>
|
||||
* Drawbacks of referencing the <code>XYZ*Step</code> types directly:
|
||||
* <ul>
|
||||
* <li>They're operating on mutable implementations (as of jOOQ 3.x)</li>
|
||||
* <li>They're less composable and not easy to get right when dynamic SQL gets
|
||||
* complex</li>
|
||||
* <li>They're less readable</li>
|
||||
* <li>They might have binary incompatible changes between minor releases</li>
|
||||
* </ul>
|
||||
*/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public interface JSONObjectReturningStep<T> extends Field<T> {
|
||||
|
||||
/**
|
||||
* Add the <code>RETURNING</code> clause to the <code>JSON OBJECT</code> function.
|
||||
*/
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
@NotNull
|
||||
Field<T> returning(DataType<?> returning);
|
||||
}
|
||||
@ -52,7 +52,7 @@ import org.jooq.impl.DSL;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface JSONValueOnStep<J> extends Field<J> {
|
||||
public interface JSONValueOnStep<J> extends JSONValueReturningStep<J> {
|
||||
|
||||
|
||||
|
||||
|
||||
76
jOOQ/src/main/java/org/jooq/JSONValueReturningStep.java
Normal file
76
jOOQ/src/main/java/org/jooq/JSONValueReturningStep.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
/**
|
||||
* A step in the construction of the <code>JSON VALUE</code> function.
|
||||
* <p>
|
||||
* <h3>Referencing <code>XYZ*Step</code> types directly from client code</h3>
|
||||
* <p>
|
||||
* It is usually not recommended to reference any <code>XYZ*Step</code> types
|
||||
* directly from client code, or assign them to local variables. When writing
|
||||
* dynamic SQL, creating a statement's components dynamically, and passing them
|
||||
* to the DSL API statically is usually a better choice. See the manual's
|
||||
* section about dynamic SQL for details: <a href=
|
||||
* "https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql">https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql</a>.
|
||||
* <p>
|
||||
* Drawbacks of referencing the <code>XYZ*Step</code> types directly:
|
||||
* <ul>
|
||||
* <li>They're operating on mutable implementations (as of jOOQ 3.x)</li>
|
||||
* <li>They're less composable and not easy to get right when dynamic SQL gets
|
||||
* complex</li>
|
||||
* <li>They're less readable</li>
|
||||
* <li>They might have binary incompatible changes between minor releases</li>
|
||||
* </ul>
|
||||
*/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public interface JSONValueReturningStep<T> extends Field<T> {
|
||||
|
||||
/**
|
||||
* Add the <code>RETURNING</code> clause to the <code>JSON VALUE</code> function.
|
||||
*/
|
||||
@Support({ MARIADB, MYSQL, POSTGRES })
|
||||
@NotNull
|
||||
Field<T> returning(DataType<?> returning);
|
||||
}
|
||||
@ -18389,6 +18389,100 @@ public class DSL {
|
||||
return new Xmlforest(fields);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// JSON functions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The <code>JSON_ARRAY</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSON> jsonArray(Field<?>... fields) {
|
||||
return new JSONArray<>(SQLDataType.JSON, Arrays.asList(fields));
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSON_ARRAY</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSON> jsonArray(Collection<? extends Field<?>> fields) {
|
||||
return new JSONArray<>(SQLDataType.JSON, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSONB_ARRAY</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSONB> jsonbArray(Field<?>... fields) {
|
||||
return new JSONArray<>(SQLDataType.JSONB, Arrays.asList(fields));
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSONB_ARRAY</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSONB> jsonbArray(Collection<? extends Field<?>> fields) {
|
||||
return new JSONArray<>(SQLDataType.JSONB, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSON_OBJECT</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSON> jsonObject(Field<?>... entries) {
|
||||
return new JSONObject<>(SQLDataType.JSON, Tools.jsonEntries(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSON_OBJECT</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSON> jsonObject(JSONEntry<?>... entries) {
|
||||
return new JSONObject<>(SQLDataType.JSON, Arrays.asList(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSON_OBJECT</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSON> jsonObject(Collection<? extends JSONEntry<?>> entries) {
|
||||
return new JSONObject<>(SQLDataType.JSON, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSONB_OBJECT</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSONB> jsonbObject(Field<?>... entries) {
|
||||
return new JSONObject<>(SQLDataType.JSONB, Tools.jsonEntries(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSONB_OBJECT</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSONB> jsonbObject(JSONEntry<?>... entries) {
|
||||
return new JSONObject<>(SQLDataType.JSONB, Arrays.asList(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>JSONB_OBJECT</code> function.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSONB> jsonbObject(Collection<? extends JSONEntry<?>> entries) {
|
||||
return new JSONObject<>(SQLDataType.JSONB, entries);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -22228,7 +22322,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support({ MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONValueOnStep<JSON> jsonValue(Field<JSON> json, Field<String> path) {
|
||||
return new JSONValue<>(SQLDataType.JSON, json, path);
|
||||
return new JSONValue<>(SQLDataType.JSON, json, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22246,43 +22340,7 @@ public class DSL {
|
||||
@NotNull
|
||||
@Support({ MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONValueOnStep<JSONB> jsonbValue(Field<JSONB> json, Field<String> path) {
|
||||
return new JSONValue<>(SQLDataType.JSONB, json, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSON array constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSON> jsonArray(Field<?>... fields) {
|
||||
return jsonArray(Arrays.asList(fields));
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSON array constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSON> jsonArray(Collection<? extends Field<?>> fields) {
|
||||
return new JSONArray<>(JSON, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSONB array constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSONB> jsonbArray(Field<?>... fields) {
|
||||
return jsonbArray(Arrays.asList(fields));
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSONB array constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONArrayNullStep<JSONB> jsonbArray(Collection<? extends Field<?>> fields) {
|
||||
return new JSONArray<>(JSONB, fields);
|
||||
return new JSONValue<>(SQLDataType.JSONB, json, path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22379,63 +22437,6 @@ public class DSL {
|
||||
return jsonObject(Tools.EMPTY_JSONENTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSON object constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSON> jsonObject(Field<?>... entries) {
|
||||
return jsonObject(Tools.jsonEntries(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSON object constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSON> jsonObject(JSONEntry<?>... entries) {
|
||||
return jsonObject(Arrays.asList(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSON object constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSON> jsonObject(Collection<? extends JSONEntry<?>> entries) {
|
||||
return new JSONObject<>(JSON, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSONB object constructor.
|
||||
* <p>
|
||||
* This is the same as calling {@link #jsonEntry(String, Field)} with
|
||||
* {@link Field#getName()} as a key.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSONB> jsonbObject(Field<?>... entries) {
|
||||
return jsonbObject(Tools.jsonEntries(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSONB object constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSONB> jsonbObject(JSONEntry<?>... entries) {
|
||||
return jsonbObject(Arrays.asList(entries));
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSONB object constructor.
|
||||
*/
|
||||
@NotNull
|
||||
@Support({ H2, MARIADB, MYSQL, POSTGRES })
|
||||
public static JSONObjectNullStep<JSONB> jsonbObject(Collection<? extends JSONEntry<?>> entries) {
|
||||
return new JSONObject<>(JSONB, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* The JSON array aggregate function.
|
||||
*/
|
||||
|
||||
@ -160,7 +160,7 @@ implements
|
||||
|
||||
private void accept0(Context<?> ctx) {
|
||||
if (dropSchemaIfExists && !supportsIfExists(ctx))
|
||||
tryCatch(ctx, DDLStatementType.DROP_SCHEMA, c -> accept0(c));
|
||||
tryCatch(ctx, DDLStatementType.DROP_SCHEMA, c -> accept1(c));
|
||||
else
|
||||
accept1(ctx);
|
||||
}
|
||||
|
||||
@ -37,56 +37,71 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.impl.DSL.jsonArrayAgg;
|
||||
import static org.jooq.impl.DSL.jsonbArrayAgg;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.values;
|
||||
import static org.jooq.impl.JSONEntryImpl.jsonCastMapper;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
|
||||
import static org.jooq.impl.Keywords.K_JSON_ARRAY;
|
||||
import static org.jooq.impl.Names.N_JSONB_BUILD_ARRAY;
|
||||
import static org.jooq.impl.Names.N_JSON_ARRAY;
|
||||
import static org.jooq.impl.Names.N_JSON_BUILD_ARRAY;
|
||||
import static org.jooq.impl.QueryPartListView.wrap;
|
||||
import static org.jooq.impl.SQLDataType.JSON;
|
||||
import static org.jooq.impl.DSL.*;
|
||||
import static org.jooq.impl.Internal.*;
|
||||
import static org.jooq.impl.Keywords.*;
|
||||
import static org.jooq.impl.Names.*;
|
||||
import static org.jooq.impl.SQLDataType.*;
|
||||
import static org.jooq.impl.Tools.*;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.*;
|
||||
import static org.jooq.impl.Tools.DataExtendedKey.*;
|
||||
import static org.jooq.impl.Tools.DataKey.*;
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.jooq.*;
|
||||
import org.jooq.conf.*;
|
||||
import org.jooq.impl.*;
|
||||
import org.jooq.tools.*;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSONArrayNullStep;
|
||||
import org.jooq.Row1;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.impl.JSONNull.JSONNullType;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* The JSON array constructor.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* The <code>JSON ARRAY</code> statement.
|
||||
*/
|
||||
final class JSONArray<J> extends AbstractField<J> implements JSONArrayNullStep<J> {
|
||||
@SuppressWarnings({ "hiding", "rawtypes", "unchecked", "unused" })
|
||||
final class JSONArray<T>
|
||||
extends
|
||||
AbstractField<T>
|
||||
implements
|
||||
JSONArrayNullStep<T>,
|
||||
JSONArrayReturningStep<T>
|
||||
{
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = 1772007627336725780L;
|
||||
private final QueryPartList<Field<?>> args;
|
||||
private final JSONNullType nullType;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
JSONArray(DataType<J> type, Collection<? extends Field<?>> args) {
|
||||
this(type, args, null);
|
||||
private final DataType<T> type;
|
||||
private final Collection<? extends Field<?>> fields;
|
||||
private JSONOnNull onNull;
|
||||
private DataType<?> returning;
|
||||
|
||||
JSONArray(
|
||||
DataType<T> type,
|
||||
Collection<? extends Field<?>> fields
|
||||
) {
|
||||
this(
|
||||
type,
|
||||
fields,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
JSONArray(DataType<J> type, Collection<? extends Field<?>> args, JSONNullType nullType) {
|
||||
super(N_JSON_ARRAY, type);
|
||||
JSONArray(
|
||||
DataType<T> type,
|
||||
Collection<? extends Field<?>> fields,
|
||||
JSONOnNull onNull,
|
||||
DataType<?> returning
|
||||
) {
|
||||
super(
|
||||
N_JSON_ARRAY,
|
||||
type
|
||||
);
|
||||
|
||||
this.args = new QueryPartList<>(args);
|
||||
this.nullType = nullType;
|
||||
this.type = type;
|
||||
this.fields = fields;
|
||||
this.onNull = onNull;
|
||||
this.returning = returning;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -94,20 +109,29 @@ final class JSONArray<J> extends AbstractField<J> implements JSONArrayNullStep<J
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final JSONArray<J> nullOnNull() {
|
||||
return new JSONArray<>(getDataType(), args, NULL_ON_NULL);
|
||||
public final JSONArray<T> nullOnNull() {
|
||||
this.onNull = JSONOnNull.NULL_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONArray<J> absentOnNull() {
|
||||
return new JSONArray<>(getDataType(), args, ABSENT_ON_NULL);
|
||||
public final JSONArray<T> absentOnNull() {
|
||||
this.onNull = JSONOnNull.ABSENT_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONArray<T> returning(DataType<?> returning) {
|
||||
this.returning = returning;
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: QueryPart API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
|
||||
|
||||
@Override
|
||||
public void accept(Context<?> ctx) {
|
||||
switch (ctx.family()) {
|
||||
@ -117,11 +141,12 @@ final class JSONArray<J> extends AbstractField<J> implements JSONArrayNullStep<J
|
||||
|
||||
|
||||
case POSTGRES:
|
||||
if (nullType == ABSENT_ON_NULL) {
|
||||
Row1[] rows = new Row1[args.size()];
|
||||
if (onNull == JSONOnNull.ABSENT_ON_NULL) {
|
||||
Row1[] rows = new Row1[fields.size()];
|
||||
|
||||
for (int i = 0; i < rows.length; i++)
|
||||
rows[i] = row(args.get(i));
|
||||
int i = 0;
|
||||
for (Field<?> field : fields)
|
||||
rows[i++] = row(field);
|
||||
|
||||
Table<?> t = values(rows).as("t", "a");
|
||||
Field<?> a = t.field("a");
|
||||
@ -132,23 +157,51 @@ final class JSONArray<J> extends AbstractField<J> implements JSONArrayNullStep<J
|
||||
));
|
||||
}
|
||||
else {
|
||||
ctx.visit(getDataType() == JSON ? N_JSON_BUILD_ARRAY : N_JSONB_BUILD_ARRAY).sql('(').visit(args).sql(')');
|
||||
ctx.visit(getDataType() == JSON ? N_JSON_BUILD_ARRAY : N_JSONB_BUILD_ARRAY).sql('(').visit(QueryPartCollectionView.wrap(fields)).sql(')');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: {
|
||||
JSONNull jsonNull;
|
||||
JSONReturning jsonReturning = new JSONReturning(returning);
|
||||
|
||||
// Workaround for https://github.com/h2database/h2database/issues/2496
|
||||
if (ctx.family() == H2 && args.isEmpty())
|
||||
jsonNull = new JSONNull(NULL_ON_NULL);
|
||||
if (ctx.family() == H2 && fields.isEmpty())
|
||||
jsonNull = new JSONNull(JSONOnNull.NULL_ON_NULL);
|
||||
else
|
||||
jsonNull = new JSONNull(nullType);
|
||||
jsonNull = new JSONNull(onNull);
|
||||
|
||||
ctx.visit(K_JSON_ARRAY).sql('(').visit(
|
||||
QueryPartListView.wrap(
|
||||
QueryPartCollectionView.wrap((Collection<Field<?>>) fields).map(JSONEntryImpl.jsonCastMapper(ctx)),
|
||||
jsonNull,
|
||||
jsonReturning
|
||||
).separator("")
|
||||
).sql(')');
|
||||
|
||||
ctx.visit(K_JSON_ARRAY).sql('(').visit(wrap(wrap(args).map(jsonCastMapper(ctx)), jsonNull).separator("")).sql(')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The Object API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that instanceof JSONArray) {
|
||||
return
|
||||
StringUtils.equals(type, ((JSONArray) that).type) &&
|
||||
StringUtils.equals(fields, ((JSONArray) that).fields) &&
|
||||
StringUtils.equals(onNull, ((JSONArray) that).onNull) &&
|
||||
StringUtils.equals(returning, ((JSONArray) that).returning)
|
||||
;
|
||||
}
|
||||
else
|
||||
return super.equals(that);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,8 +44,8 @@ import static org.jooq.impl.DSL.function;
|
||||
import static org.jooq.impl.DSL.groupConcat;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.JSONEntryImpl.jsonCast;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.NULL_ON_NULL;
|
||||
import static org.jooq.impl.Names.N_JSONB_AGG;
|
||||
import static org.jooq.impl.Names.N_JSON_AGG;
|
||||
import static org.jooq.impl.Names.N_JSON_ARRAYAGG;
|
||||
@ -57,13 +57,15 @@ import static org.jooq.impl.SQLDataType.VARCHAR;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.AggregateFilterStep;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSONArrayAggOrderByStep;
|
||||
import org.jooq.OrderField;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.impl.JSONNull.JSONNullType;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
/**
|
||||
@ -81,7 +83,8 @@ implements JSONArrayAggOrderByStep<J> {
|
||||
private static final long serialVersionUID = 1772007627336725780L;
|
||||
static final Set<SQLDialect> EMULATE_WITH_GROUP_CONCAT = SQLDialect.supportedBy(MARIADB, MYSQL);
|
||||
|
||||
private JSONNullType nullType;
|
||||
private JSONOnNull onNull;
|
||||
private DataType<?> returning;
|
||||
|
||||
JSONArrayAgg(DataType<J> type, Field<?> arg) {
|
||||
super(false, N_JSON_ARRAYAGG, type, arg);
|
||||
@ -117,7 +120,7 @@ implements JSONArrayAggOrderByStep<J> {
|
||||
ctx.sql(')');
|
||||
|
||||
// TODO: What about a user-defined filter clause?
|
||||
if (nullType == ABSENT_ON_NULL)
|
||||
if (onNull == ABSENT_ON_NULL)
|
||||
acceptFilterClause(ctx, arguments.get(0).isNotNull());
|
||||
|
||||
break;
|
||||
@ -161,22 +164,32 @@ implements JSONArrayAggOrderByStep<J> {
|
||||
ctx.visit(jsonCast(ctx, arguments.get(0)));
|
||||
acceptOrderBy(ctx);
|
||||
|
||||
JSONNull jsonNull = new JSONNull(nullType);
|
||||
JSONNull jsonNull = new JSONNull(onNull);
|
||||
if (jsonNull.rendersContent(ctx))
|
||||
ctx.sql(' ').visit(jsonNull);
|
||||
|
||||
JSONReturning jsonReturning = new JSONReturning(returning);
|
||||
if (jsonReturning.rendersContent(ctx))
|
||||
ctx.sql(' ').visit(jsonReturning);
|
||||
|
||||
ctx.sql(')');
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONArrayAgg<J> nullOnNull() {
|
||||
nullType = NULL_ON_NULL;
|
||||
onNull = NULL_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONArrayAgg<J> absentOnNull() {
|
||||
nullType = ABSENT_ON_NULL;
|
||||
onNull = ABSENT_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONArrayAgg<J> returning(DataType<?> r) {
|
||||
this.returning = r;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ final class JSONEntryImpl<T> extends AbstractQueryPart implements JSONEntry<T>,
|
||||
}
|
||||
}
|
||||
|
||||
static final Function<Field<?>, Field<?>> jsonCastMapper(final Context<?> ctx) {
|
||||
static final Function<? super Field<?>, ? extends Field<?>> jsonCastMapper(final Context<?> ctx) {
|
||||
return field -> jsonCast(ctx, field);
|
||||
}
|
||||
|
||||
|
||||
@ -39,8 +39,8 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.NULL_ON_NULL;
|
||||
import static org.jooq.impl.Keywords.K_ABSENT;
|
||||
import static org.jooq.impl.Keywords.K_NULL;
|
||||
import static org.jooq.impl.Keywords.K_ON;
|
||||
@ -61,9 +61,9 @@ final class JSONNull extends AbstractQueryPart {
|
||||
private static final long serialVersionUID = 3121287280045911346L;
|
||||
static final Set<SQLDialect> NO_SUPPORT_ABSENT_ON_NULL = SQLDialect.supportedBy(MARIADB, MYSQL);
|
||||
|
||||
final JSONNullType type;
|
||||
final JSONOnNull type;
|
||||
|
||||
JSONNull(JSONNullType type) {
|
||||
JSONNull(JSONOnNull type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@ -80,8 +80,4 @@ final class JSONNull extends AbstractQueryPart {
|
||||
else if (type == ABSENT_ON_NULL)
|
||||
ctx.visit(K_ABSENT).sql(' ').visit(K_ON).sql(' ').visit(K_NULL);
|
||||
}
|
||||
|
||||
enum JSONNullType {
|
||||
NULL_ON_NULL, ABSENT_ON_NULL
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,64 +37,71 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
// ...
|
||||
import static org.jooq.impl.DSL.asterisk;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.jsonEntry;
|
||||
import static org.jooq.impl.DSL.jsonObject;
|
||||
import static org.jooq.impl.DSL.key;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.unquotedName;
|
||||
import static org.jooq.impl.DSL.values;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
|
||||
import static org.jooq.impl.Keywords.K_JSON_OBJECT;
|
||||
import static org.jooq.impl.Names.N_JSON_MERGE;
|
||||
import static org.jooq.impl.Names.N_JSON_OBJECT;
|
||||
import static org.jooq.impl.Names.N_T;
|
||||
import static org.jooq.impl.QueryPartListView.wrap;
|
||||
import static org.jooq.impl.SQLDataType.VARCHAR;
|
||||
import static org.jooq.impl.DSL.*;
|
||||
import static org.jooq.impl.Internal.*;
|
||||
import static org.jooq.impl.Keywords.*;
|
||||
import static org.jooq.impl.Names.*;
|
||||
import static org.jooq.impl.SQLDataType.*;
|
||||
import static org.jooq.impl.Tools.*;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.*;
|
||||
import static org.jooq.impl.Tools.DataExtendedKey.*;
|
||||
import static org.jooq.impl.Tools.DataKey.*;
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import org.jooq.*;
|
||||
import org.jooq.conf.*;
|
||||
import org.jooq.impl.*;
|
||||
import org.jooq.tools.*;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSONB;
|
||||
import org.jooq.JSONEntry;
|
||||
import org.jooq.JSONObjectNullStep;
|
||||
import org.jooq.Name;
|
||||
// ...
|
||||
import org.jooq.impl.JSONNull.JSONNullType;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* The JSON array constructor.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
* The <code>JSON OBJECT</code> statement.
|
||||
*/
|
||||
final class JSONObject<J> extends AbstractField<J> implements JSONObjectNullStep<J> {
|
||||
@SuppressWarnings({ "hiding", "rawtypes", "unchecked", "unused" })
|
||||
final class JSONObject<T>
|
||||
extends
|
||||
AbstractField<T>
|
||||
implements
|
||||
JSONObjectNullStep<T>,
|
||||
JSONObjectReturningStep<T>
|
||||
{
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = 1772007627336725780L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final QueryPartList<JSONEntry<?>> args;
|
||||
private final JSONNullType nullType;
|
||||
private final DataType<T> type;
|
||||
private final Collection<? extends JSONEntry<?>> entries;
|
||||
private JSONOnNull onNull;
|
||||
private DataType<?> returning;
|
||||
|
||||
JSONObject(DataType<J> type, Collection<? extends JSONEntry<?>> args) {
|
||||
this(type, args, null);
|
||||
JSONObject(
|
||||
DataType<T> type,
|
||||
Collection<? extends JSONEntry<?>> entries
|
||||
) {
|
||||
this(
|
||||
type,
|
||||
entries,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
JSONObject(DataType<J> type, Collection<? extends JSONEntry<?>> args, JSONNullType nullType) {
|
||||
super(N_JSON_OBJECT, type);
|
||||
JSONObject(
|
||||
DataType<T> type,
|
||||
Collection<? extends JSONEntry<?>> entries,
|
||||
JSONOnNull onNull,
|
||||
DataType<?> returning
|
||||
) {
|
||||
super(
|
||||
N_JSON_OBJECT,
|
||||
type
|
||||
);
|
||||
|
||||
this.args = new QueryPartList<>(args);
|
||||
this.nullType = nullType;
|
||||
this.type = type;
|
||||
this.entries = entries;
|
||||
this.onNull = onNull;
|
||||
this.returning = returning;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -102,19 +109,29 @@ final class JSONObject<J> extends AbstractField<J> implements JSONObjectNullStep
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final JSONObject<J> nullOnNull() {
|
||||
return new JSONObject<>(getDataType(), args, NULL_ON_NULL);
|
||||
public final JSONObject<T> nullOnNull() {
|
||||
this.onNull = JSONOnNull.NULL_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONObject<J> absentOnNull() {
|
||||
return new JSONObject<>(getDataType(), args, ABSENT_ON_NULL);
|
||||
public final JSONObject<T> absentOnNull() {
|
||||
this.onNull = JSONOnNull.ABSENT_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONObject<T> returning(DataType<?> returning) {
|
||||
this.returning = returning;
|
||||
return this;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: QueryPart API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
switch (ctx.family()) {
|
||||
@ -124,12 +141,12 @@ final class JSONObject<J> extends AbstractField<J> implements JSONObjectNullStep
|
||||
|
||||
|
||||
case POSTGRES:
|
||||
if (nullType == ABSENT_ON_NULL)
|
||||
if (onNull == JSONOnNull.ABSENT_ON_NULL)
|
||||
ctx.visit(unquotedName(getDataType().getType() == JSONB.class ? "jsonb_strip_nulls" : "json_strip_nulls")).sql('(');
|
||||
|
||||
ctx.visit(unquotedName(getDataType().getType() == JSONB.class ? "jsonb_build_object" : "json_build_object")).sql('(').visit(args).sql(')');
|
||||
ctx.visit(unquotedName(getDataType().getType() == JSONB.class ? "jsonb_build_object" : "json_build_object")).sql('(').visit(QueryPartCollectionView.wrap(entries)).sql(')');
|
||||
|
||||
if (nullType == ABSENT_ON_NULL)
|
||||
if (onNull == JSONOnNull.ABSENT_ON_NULL)
|
||||
ctx.sql(')');
|
||||
|
||||
break;
|
||||
@ -170,29 +187,31 @@ final class JSONObject<J> extends AbstractField<J> implements JSONObjectNullStep
|
||||
|
||||
|
||||
|
||||
case MARIADB:
|
||||
case MARIADB: {
|
||||
JSONEntry<?> first;
|
||||
|
||||
// Workaround for https://jira.mariadb.org/browse/MDEV-13701
|
||||
if (args.size() > 1) {
|
||||
if (entries.size() > 1) {
|
||||
ctx.visit(N_JSON_MERGE).sql('(').visit(inline("{}"))
|
||||
.formatIndentStart();
|
||||
|
||||
for (JSONEntry<?> entry : args)
|
||||
for (JSONEntry<?> entry : entries)
|
||||
ctx.sql(',').formatSeparator().visit(jsonObject(entry));
|
||||
|
||||
ctx.formatIndentEnd()
|
||||
.formatNewLine()
|
||||
.sql(')');
|
||||
}
|
||||
else if (!args.isEmpty() && isJSONArray(args.get(0).value())) {
|
||||
else if (!entries.isEmpty() && isJSONArray((first = entries.iterator().next()).value())) {
|
||||
ctx.visit(jsonObject(
|
||||
key(args.get(0).key()).value(DSL.field("{0}({1}, {2})", getDataType(), N_JSON_MERGE, inline("[]"), args.get(0).value()))
|
||||
key(first.key()).value(DSL.field("{0}({1}, {2})", getDataType(), N_JSON_MERGE, inline("[]"), first.value()))
|
||||
));
|
||||
}
|
||||
else
|
||||
acceptStandard(ctx);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
acceptStandard(ctx);
|
||||
@ -208,18 +227,39 @@ final class JSONObject<J> extends AbstractField<J> implements JSONObjectNullStep
|
||||
|
||||
private final void acceptStandard(Context<?> ctx) {
|
||||
JSONNull jsonNull;
|
||||
JSONReturning jsonReturning = new JSONReturning(returning);
|
||||
|
||||
// Workaround for https://github.com/h2database/h2database/issues/2496
|
||||
if (args.isEmpty() && ctx.family() == H2)
|
||||
jsonNull = new JSONNull(NULL_ON_NULL);
|
||||
if (entries.isEmpty() && ctx.family() == H2)
|
||||
jsonNull = new JSONNull(JSONOnNull.NULL_ON_NULL);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
else
|
||||
jsonNull = new JSONNull(nullType);
|
||||
jsonNull = new JSONNull(onNull);
|
||||
|
||||
ctx.visit(K_JSON_OBJECT).sql('(').visit(wrap(args, jsonNull).separator("")).sql(')');
|
||||
ctx.visit(K_JSON_OBJECT).sql('(').visit(QueryPartListView.wrap(QueryPartCollectionView.wrap(entries), jsonNull, jsonReturning).separator("")).sql(')');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The Object API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that instanceof JSONObject) {
|
||||
return
|
||||
StringUtils.equals(type, ((JSONObject) that).type) &&
|
||||
StringUtils.equals(entries, ((JSONObject) that).entries) &&
|
||||
StringUtils.equals(onNull, ((JSONObject) that).onNull) &&
|
||||
StringUtils.equals(returning, ((JSONObject) that).returning)
|
||||
;
|
||||
}
|
||||
else
|
||||
return super.equals(that);
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,8 +43,8 @@ import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.jsonObject;
|
||||
import static org.jooq.impl.DSL.jsonValue;
|
||||
import static org.jooq.impl.DSL.when;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.NULL_ON_NULL;
|
||||
import static org.jooq.impl.Names.N_JSONB_OBJECT_AGG;
|
||||
import static org.jooq.impl.Names.N_JSON_OBJECTAGG;
|
||||
import static org.jooq.impl.Names.N_JSON_OBJECT_AGG;
|
||||
@ -56,7 +56,6 @@ import org.jooq.Field;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONEntry;
|
||||
import org.jooq.JSONObjectAggNullStep;
|
||||
import org.jooq.impl.JSONNull.JSONNullType;
|
||||
|
||||
|
||||
/**
|
||||
@ -74,7 +73,8 @@ implements JSONObjectAggNullStep<J> {
|
||||
private static final long serialVersionUID = 1772007627336725780L;
|
||||
|
||||
private final JSONEntry<?> entry;
|
||||
private JSONNullType nullType;
|
||||
private JSONOnNull onNull;
|
||||
private DataType<?> returning;
|
||||
|
||||
JSONObjectAgg(DataType<J> type, JSONEntry<?> entry) {
|
||||
super(false, N_JSON_OBJECTAGG, type, entry.key(), entry.value());
|
||||
@ -101,7 +101,7 @@ implements JSONObjectAggNullStep<J> {
|
||||
// [#10089] These dialects support non-standard JSON_OBJECTAGG without ABSENT ON NULL support
|
||||
case MARIADB:
|
||||
case MYSQL:
|
||||
if (nullType == ABSENT_ON_NULL)
|
||||
if (onNull == ABSENT_ON_NULL)
|
||||
acceptGroupConcat(ctx);
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ implements JSONObjectAggNullStep<J> {
|
||||
ctx.sql(')');
|
||||
|
||||
// TODO: What about a user-defined filter clause?
|
||||
if (nullType == ABSENT_ON_NULL)
|
||||
if (onNull == ABSENT_ON_NULL)
|
||||
acceptFilterClause(ctx, entry.value().isNotNull());
|
||||
|
||||
acceptOverClause(ctx);
|
||||
@ -152,7 +152,7 @@ implements JSONObjectAggNullStep<J> {
|
||||
break;
|
||||
}
|
||||
|
||||
if (nullType == ABSENT_ON_NULL)
|
||||
if (onNull == ABSENT_ON_NULL)
|
||||
value = when(entry.value().isNull(), inline((String) null)).else_((Field) value);
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ implements JSONObjectAggNullStep<J> {
|
||||
inline('"'),
|
||||
DSL.replace(entry.key(), inline('"'), inline("\\\"")),
|
||||
inline("\":"),
|
||||
nullType == ABSENT_ON_NULL ? value1 : DSL.coalesce(value1, inline("null"))
|
||||
onNull == ABSENT_ON_NULL ? value1 : DSL.coalesce(value1, inline("null"))
|
||||
)));
|
||||
acceptOverClause(c);
|
||||
}));
|
||||
@ -173,23 +173,33 @@ implements JSONObjectAggNullStep<J> {
|
||||
private final void acceptStandard(Context<?> ctx) {
|
||||
ctx.visit(N_JSON_OBJECTAGG).sql('(').visit(entry);
|
||||
|
||||
JSONNull jsonNull = new JSONNull(nullType);
|
||||
JSONNull jsonNull = new JSONNull(onNull);
|
||||
if (jsonNull.rendersContent(ctx))
|
||||
ctx.sql(' ').visit(jsonNull);
|
||||
|
||||
JSONReturning jsonReturning = new JSONReturning(returning);
|
||||
if (jsonReturning.rendersContent(ctx))
|
||||
ctx.sql(' ').visit(jsonReturning);
|
||||
|
||||
ctx.sql(')');
|
||||
acceptOverClause(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONObjectAgg<J> nullOnNull() {
|
||||
nullType = NULL_ON_NULL;
|
||||
onNull = NULL_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONObjectAgg<J> absentOnNull() {
|
||||
nullType = ABSENT_ON_NULL;
|
||||
onNull = ABSENT_ON_NULL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final JSONObjectAgg<J> returning(DataType<?> r) {
|
||||
this.returning = r;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
49
jOOQ/src/main/java/org/jooq/impl/JSONOnNull.java
Normal file
49
jOOQ/src/main/java/org/jooq/impl/JSONOnNull.java
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
|
||||
import org.jooq.*;
|
||||
|
||||
/**
|
||||
* The <code>JSONOnNull</code>.
|
||||
*/
|
||||
enum JSONOnNull {
|
||||
NULL_ON_NULL,
|
||||
ABSENT_ON_NULL,
|
||||
}
|
||||
80
jOOQ/src/main/java/org/jooq/impl/JSONReturning.java
Normal file
80
jOOQ/src/main/java/org/jooq/impl/JSONReturning.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.impl.Keywords.K_RETURNING;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.SQLDialect;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class JSONReturning extends AbstractQueryPart {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = 3121287280045911346L;
|
||||
static final Set<SQLDialect> NO_SUPPORT_RETURNING = SQLDialect.supportedBy(H2, MARIADB, MYSQL, POSTGRES);
|
||||
final DataType<?> type;
|
||||
|
||||
JSONReturning(DataType<?> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean rendersContent(Context<?> ctx) {
|
||||
return !NO_SUPPORT_RETURNING.contains(ctx.dialect()) && type != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (!NO_SUPPORT_RETURNING.contains(ctx.dialect()))
|
||||
ctx.visit(K_RETURNING).sql(' ').sql(type.getCastTypeName(ctx.configuration()));
|
||||
}
|
||||
}
|
||||
@ -62,7 +62,6 @@ import org.jooq.JSONValueOnStep;
|
||||
import org.jooq.Keyword;
|
||||
// ...
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.conf.ParamType;
|
||||
|
||||
|
||||
/**
|
||||
@ -87,25 +86,22 @@ implements
|
||||
|
||||
private final Field<?> json;
|
||||
private final Field<String> path;
|
||||
private final DataType<?> returning;
|
||||
private final Behaviour onError;
|
||||
private final Field<?> onErrorDefault;
|
||||
private final Behaviour onEmpty;
|
||||
private final Field<?> onEmptyDefault;
|
||||
private final Field<?> default_;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
JSONValue(DataType<J> type, Field<?> json, Field<String> path) {
|
||||
this(type, json, path, null, null, null, null, null);
|
||||
JSONValue(DataType<J> type, Field<?> json, Field<String> path, DataType<?> returning) {
|
||||
this(type, json, path, returning, null, null, null, null, null);
|
||||
}
|
||||
|
||||
private JSONValue(
|
||||
DataType<J> type,
|
||||
Field<?> json,
|
||||
Field<String> path,
|
||||
DataType<?> returning,
|
||||
Behaviour onError,
|
||||
Field<?> onErrorDefault,
|
||||
Behaviour onEmpty,
|
||||
@ -116,13 +112,12 @@ implements
|
||||
|
||||
this.json = json;
|
||||
this.path = path;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.returning = returning;
|
||||
this.onError = onError;
|
||||
this.onErrorDefault = onErrorDefault;
|
||||
this.onEmpty = onEmpty;
|
||||
this.onEmptyDefault = onEmptyDefault;
|
||||
this.default_ = default_;
|
||||
|
||||
}
|
||||
|
||||
@ -168,6 +163,11 @@ implements
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final JSONValue<J> returning(DataType<?> r) {
|
||||
return new JSONValue<>(getDataType(), json, path, r, onError, onErrorDefault, onEmpty, onEmptyDefault, null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: QueryPart API
|
||||
@ -210,6 +210,9 @@ implements
|
||||
|
||||
|
||||
|
||||
if (returning != null)
|
||||
ctx.separatorRequired(true).visit(new JSONReturning(returning));
|
||||
|
||||
ctx.sql(')');
|
||||
break;
|
||||
}
|
||||
|
||||
@ -291,7 +291,6 @@ import static org.jooq.impl.DSL.splitPart;
|
||||
import static org.jooq.impl.DSL.sql;
|
||||
import static org.jooq.impl.DSL.sqrt;
|
||||
import static org.jooq.impl.DSL.square;
|
||||
// ...
|
||||
import static org.jooq.impl.DSL.stddevPop;
|
||||
import static org.jooq.impl.DSL.stddevSamp;
|
||||
import static org.jooq.impl.DSL.sum;
|
||||
@ -337,8 +336,8 @@ import static org.jooq.impl.DSL.xmlquery;
|
||||
import static org.jooq.impl.DSL.xmltable;
|
||||
import static org.jooq.impl.DSL.year;
|
||||
import static org.jooq.impl.DSL.zero;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONNull.JSONNullType.NULL_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.ABSENT_ON_NULL;
|
||||
import static org.jooq.impl.JSONOnNull.NULL_ON_NULL;
|
||||
import static org.jooq.impl.Keywords.K_DELETE;
|
||||
import static org.jooq.impl.Keywords.K_INSERT;
|
||||
import static org.jooq.impl.Keywords.K_SELECT;
|
||||
@ -378,7 +377,6 @@ import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@ -497,10 +495,14 @@ import org.jooq.InsertValuesStepN;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONArrayAggNullStep;
|
||||
import org.jooq.JSONArrayAggOrderByStep;
|
||||
import org.jooq.JSONArrayAggReturningStep;
|
||||
import org.jooq.JSONArrayNullStep;
|
||||
import org.jooq.JSONArrayReturningStep;
|
||||
import org.jooq.JSONEntry;
|
||||
import org.jooq.JSONObjectAggNullStep;
|
||||
import org.jooq.JSONObjectAggReturningStep;
|
||||
import org.jooq.JSONObjectNullStep;
|
||||
import org.jooq.JSONObjectReturningStep;
|
||||
import org.jooq.JSONTableColumnPathStep;
|
||||
import org.jooq.JSONTableColumnsStep;
|
||||
import org.jooq.JSONValueDefaultStep;
|
||||
@ -595,7 +597,6 @@ import org.jooq.conf.RenderNameCase;
|
||||
import org.jooq.conf.RenderQuotedNames;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.conf.SettingsTools;
|
||||
import org.jooq.impl.JSONNull.JSONNullType;
|
||||
import org.jooq.impl.ScopeStack.Value;
|
||||
import org.jooq.impl.XMLParse.DocumentOrContent;
|
||||
import org.jooq.tools.StringUtils;
|
||||
@ -8308,8 +8309,9 @@ final class ParserContext {
|
||||
|
||||
|
||||
|
||||
DataType<?> returning = parseJSONReturningIf();
|
||||
parse(')');
|
||||
return s1;
|
||||
return returning == null ? s1 : s1.returning(returning);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -8339,6 +8341,10 @@ final class ParserContext {
|
||||
return null;
|
||||
}
|
||||
|
||||
private final DataType<?> parseJSONReturningIf() {
|
||||
return parseKeywordIf("RETURNING") ? parseDataType() : null;
|
||||
}
|
||||
|
||||
private final Field<?> parseFieldJSONArrayConstructorIf() {
|
||||
if (parseFunctionNameIf("JSON_ARRAY")) {
|
||||
parse('(');
|
||||
@ -8346,21 +8352,24 @@ final class ParserContext {
|
||||
return DSL.jsonArray();
|
||||
|
||||
List<Field<?>> result = null;
|
||||
JSONNullType nullType = parseJSONNullTypeIf();
|
||||
JSONOnNull onNull = parseJSONNullTypeIf();
|
||||
DataType<?> returning = parseJSONReturningIf();
|
||||
|
||||
if (nullType == null) {
|
||||
if (onNull == null && returning == null) {
|
||||
result = parseFields();
|
||||
nullType = parseJSONNullTypeIf();
|
||||
onNull = parseJSONNullTypeIf();
|
||||
returning = parseJSONReturningIf();
|
||||
}
|
||||
|
||||
parse(')');
|
||||
|
||||
JSONArrayNullStep<JSON> a = result == null ? DSL.jsonArray() : DSL.jsonArray(result);
|
||||
return nullType == NULL_ON_NULL
|
||||
? a.nullOnNull()
|
||||
: nullType == ABSENT_ON_NULL
|
||||
? a.absentOnNull()
|
||||
: a;
|
||||
JSONArrayNullStep<?> s1 = result == null ? DSL.jsonArray() : DSL.jsonArray(result);
|
||||
JSONArrayReturningStep<?> s2 = onNull == NULL_ON_NULL
|
||||
? s1.nullOnNull()
|
||||
: onNull == ABSENT_ON_NULL
|
||||
? s1.absentOnNull()
|
||||
: s1;
|
||||
return returning == null ? s2 : s2.returning(returning);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -8369,18 +8378,23 @@ final class ParserContext {
|
||||
private final Field<?> parseFieldJSONArrayAggIf() {
|
||||
if (parseFunctionNameIf("JSON_ARRAYAGG")) {
|
||||
Field<?> result;
|
||||
JSONArrayAggOrderByStep<JSON> s1;
|
||||
JSONArrayAggNullStep<JSON> s2;
|
||||
JSONNullType nullType;
|
||||
JSONArrayAggOrderByStep<?> s1;
|
||||
JSONArrayAggNullStep<?> s2;
|
||||
JSONArrayAggReturningStep<?> s3;
|
||||
JSONOnNull onNull;
|
||||
DataType<?> returning;
|
||||
|
||||
parse('(');
|
||||
result = s2 = s1 = DSL.jsonArrayAgg(parseField());
|
||||
result = s3 = s2 = s1 = DSL.jsonArrayAgg(parseField());
|
||||
|
||||
if (parseKeywordIf("ORDER BY"))
|
||||
result = s2 = s1.orderBy(parseSortSpecification());
|
||||
result = s3 = s2 = s1.orderBy(parseSortSpecification());
|
||||
|
||||
if ((nullType = parseJSONNullTypeIf()) != null)
|
||||
result = nullType == ABSENT_ON_NULL ? s2.absentOnNull() : s2.nullOnNull();
|
||||
if ((onNull = parseJSONNullTypeIf()) != null)
|
||||
result = s3 = onNull == ABSENT_ON_NULL ? s2.absentOnNull() : s2.nullOnNull();
|
||||
|
||||
if ((returning = parseJSONReturningIf()) != null)
|
||||
result = s3.returning(returning);
|
||||
|
||||
parse(')');
|
||||
return result;
|
||||
@ -8396,23 +8410,27 @@ final class ParserContext {
|
||||
return DSL.jsonObject();
|
||||
|
||||
List<JSONEntry<?>> result = new ArrayList<>();
|
||||
JSONNullType nullType = parseJSONNullTypeIf();
|
||||
JSONOnNull onNull = parseJSONNullTypeIf();
|
||||
DataType<?> returning = parseJSONReturningIf();
|
||||
|
||||
if (nullType == null) {
|
||||
if (onNull == null && returning == null) {
|
||||
do
|
||||
result.add(parseJSONEntry());
|
||||
while (parseIf(','));
|
||||
|
||||
nullType = parseJSONNullTypeIf();
|
||||
onNull = parseJSONNullTypeIf();
|
||||
returning = parseJSONReturningIf();
|
||||
}
|
||||
|
||||
parse(')');
|
||||
|
||||
JSONObjectNullStep<JSON> o = DSL.jsonObject(result);
|
||||
return nullType == NULL_ON_NULL
|
||||
? o.nullOnNull()
|
||||
: nullType == ABSENT_ON_NULL
|
||||
? o.absentOnNull()
|
||||
: o;
|
||||
JSONObjectNullStep<?> s1 = DSL.jsonObject(result);
|
||||
JSONObjectReturningStep<?> s2 = onNull == NULL_ON_NULL
|
||||
? s1.nullOnNull()
|
||||
: onNull == ABSENT_ON_NULL
|
||||
? s1.absentOnNull()
|
||||
: s1;
|
||||
return returning == null ? s2 : s2.returning(returning);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -8421,14 +8439,19 @@ final class ParserContext {
|
||||
private final Field<?> parseFieldJSONObjectAggIf() {
|
||||
if (parseFunctionNameIf("JSON_OBJECTAGG")) {
|
||||
Field<?> result;
|
||||
JSONObjectAggNullStep<JSON> s1;
|
||||
JSONNullType nullType;
|
||||
JSONObjectAggNullStep<?> s1;
|
||||
JSONObjectAggReturningStep<?> s2;
|
||||
JSONOnNull onNull;
|
||||
DataType<?> returning;
|
||||
|
||||
parse('(');
|
||||
result = s1 = DSL.jsonObjectAgg(parseJSONEntry());
|
||||
result = s2 = s1 = DSL.jsonObjectAgg(parseJSONEntry());
|
||||
|
||||
if ((nullType = parseJSONNullTypeIf()) != null)
|
||||
result = nullType == ABSENT_ON_NULL ? s1.absentOnNull() : s1.nullOnNull();
|
||||
if ((onNull = parseJSONNullTypeIf()) != null)
|
||||
result = s2 = onNull == ABSENT_ON_NULL ? s1.absentOnNull() : s1.nullOnNull();
|
||||
|
||||
if ((returning = parseJSONReturningIf()) != null)
|
||||
result = s2.returning(returning);
|
||||
|
||||
parse(')');
|
||||
return result;
|
||||
@ -8437,7 +8460,7 @@ final class ParserContext {
|
||||
return null;
|
||||
}
|
||||
|
||||
private final JSONNullType parseJSONNullTypeIf() {
|
||||
private final JSONOnNull parseJSONNullTypeIf() {
|
||||
if (parseKeywordIf("NULL ON NULL"))
|
||||
return NULL_ON_NULL;
|
||||
else if (parseKeywordIf("ABSENT ON NULL"))
|
||||
|
||||
@ -2017,13 +2017,13 @@ final class Tools {
|
||||
return result;
|
||||
}
|
||||
|
||||
static final JSONEntry<?>[] jsonEntries(Field<?>... fields) {
|
||||
static final List<JSONEntry<?>> jsonEntries(Field<?>... fields) {
|
||||
if (fields == null)
|
||||
return null;
|
||||
|
||||
JSONEntry<?>[] result = new JSONEntry[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
result[i] = jsonEntry(fields[i]);
|
||||
List<JSONEntry<?>> result = new ArrayList<>(fields.length);
|
||||
for (Field<?> field : fields)
|
||||
result.add(jsonEntry(field));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user