diff --git a/jOOQ/src/main/java/org/jooq/JSONExistsOnStep.java b/jOOQ/src/main/java/org/jooq/JSONExistsOnStep.java new file mode 100644 index 0000000000..552907fd82 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/JSONExistsOnStep.java @@ -0,0 +1,85 @@ +/* + * 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.jooq.impl.DSL; + +/** + * A step in the construction of {@link DSL#jsonExists(Field, Field)} or + * {@link DSL#jsonbExists(Field, Field)} functions where the + * ON ERROR clause can be defined. + * + * @author Lukas Eder + */ +public interface JSONExistsOnStep extends Condition { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index b46f611e38..e3e59a11d5 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -73,6 +73,7 @@ import static org.jooq.SQLDialect.POSTGRES; // ... // ... // ... +// ... import static org.jooq.SQLDialect.SQLITE; // ... // ... @@ -236,6 +237,7 @@ import org.jooq.JSONArrayAggOrderByStep; import org.jooq.JSONArrayNullStep; import org.jooq.JSONB; import org.jooq.JSONEntry; +import org.jooq.JSONExistsOnStep; import org.jooq.JSONObjectAggNullStep; import org.jooq.JSONObjectNullStep; import org.jooq.JSONValueOnStep; @@ -18498,32 +18500,32 @@ public class DSL { /** * The JSON value extractor function. */ - @Support({ MARIADB }) - public static JSONValueOnStep jsonValue(Field json, String path) { + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONValueOnStep jsonValue(Field json, String path) { return jsonValue(json, Tools.field(path)); } /** * The JSON value extractor function. */ - @Support({ MARIADB }) - public static JSONValueOnStep jsonValue(Field json, Field path) { + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONValueOnStep jsonValue(Field json, Field path) { return new JSONValue<>(SQLDataType.JSON, json, path); } /** * The JSON value extractor function. */ - @Support({ MARIADB }) - public static JSONValueOnStep jsonbValue(Field json, String path) { + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONValueOnStep jsonbValue(Field json, String path) { return jsonbValue(json, Tools.field(path)); } /** * The JSON value extractor function. */ - @Support({ MARIADB }) - public static JSONValueOnStep jsonbValue(Field json, Field path) { + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONValueOnStep jsonbValue(Field json, Field path) { return new JSONValue<>(SQLDataType.JSONB, json, path); } @@ -18628,7 +18630,7 @@ public class DSL { */ @Support({ H2, MARIADB, MYSQL, POSTGRES }) public static JSONArrayAggOrderByStep jsonArrayAgg(Field value) { - return new JSONArrayAgg(JSON, value); + return new JSONArrayAgg<>(JSON, value); } /** @@ -18636,7 +18638,7 @@ public class DSL { */ @Support({ H2, MARIADB, MYSQL, POSTGRES }) public static JSONArrayAggOrderByStep jsonbArrayAgg(Field value) { - return new JSONArrayAgg(JSONB, value); + return new JSONArrayAgg<>(JSONB, value); } /** @@ -18660,7 +18662,7 @@ public class DSL { */ @Support({ H2, MARIADB, MYSQL, POSTGRES }) public static JSONObjectAggNullStep jsonObjectAgg(JSONEntry entry) { - return new JSONObjectAgg(JSON, entry); + return new JSONObjectAgg<>(JSON, entry); } /** @@ -18684,7 +18686,39 @@ public class DSL { */ @Support({ H2, MARIADB, MYSQL, POSTGRES }) public static JSONObjectAggNullStep jsonbObjectAgg(JSONEntry entry) { - return new JSONObjectAgg(JSONB, entry); + return new JSONObjectAgg<>(JSONB, entry); + } + + /** + * The JSON exists predicate. + */ + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONExistsOnStep jsonExists(Field field, String path) { + return jsonExists(field, Tools.field(path)); + } + + /** + * The JSON exists predicate. + */ + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONExistsOnStep jsonExists(Field field, Field path) { + return new JSONExists(field, nullSafe(path)); + } + + /** + * The JSONB exists predicate. + */ + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONExistsOnStep jsonbExists(Field field, String path) { + return jsonbExists(field, Tools.field(path)); + } + + /** + * The JSONB exists predicate. + */ + @Support({ MARIADB, MYSQL, POSTGRES }) + public static JSONExistsOnStep jsonbExists(Field field, Field path) { + return new JSONExists(field, nullSafe(path)); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONExists.java b/jOOQ/src/main/java/org/jooq/impl/JSONExists.java new file mode 100644 index 0000000000..e42f70b2a9 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/JSONExists.java @@ -0,0 +1,175 @@ +/* + * 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.conf.ParamType.INLINED; +import static org.jooq.impl.JSONExists.Behaviour.ERROR; +import static org.jooq.impl.JSONExists.Behaviour.FALSE; +import static org.jooq.impl.JSONExists.Behaviour.TRUE; +import static org.jooq.impl.JSONExists.Behaviour.UNKNOWN; +import static org.jooq.impl.JSONValue.NO_SUPPORT_PATH_BINDS; +import static org.jooq.impl.Keywords.K_ERROR; +import static org.jooq.impl.Keywords.K_JSON_EXISTS; +import static org.jooq.impl.Keywords.K_ON; +import static org.jooq.impl.Names.N_JSONB_PATH_EXISTS; +import static org.jooq.impl.Names.N_JSON_CONTAINS_PATH; +import static org.jooq.impl.SQLDataType.JSONB; +import static org.jooq.impl.Tools.castIfNeeded; + +import org.jooq.Context; +import org.jooq.Field; +import org.jooq.JSONExistsOnStep; +import org.jooq.Keyword; +import org.jooq.conf.ParamType; + + +/** + * The JSON value constructor. + * + * @author Lukas Eder + */ +final class JSONExists extends AbstractCondition implements JSONExistsOnStep { + + /** + * Generated UID + */ + private static final long serialVersionUID = 1772007627336725780L; + + private final Field json; + private final Field path; + + + + + + JSONExists(Field json, Field path) { + this(json, path, null); + } + + private JSONExists( + Field json, + Field path, + Behaviour onError + ) { + + this.json = json; + this.path = path; + + + + + } + + // ------------------------------------------------------------------------- + // XXX: DSL API + // ------------------------------------------------------------------------- + + + + + + + + + + + + + + + + + + + + + + + + + + // ------------------------------------------------------------------------- + // XXX: QueryPart API + // ------------------------------------------------------------------------- + + @Override + public final void accept(Context ctx) { + switch (ctx.family()) { + + + + case MYSQL: + ctx.visit(N_JSON_CONTAINS_PATH).sql('(').visit(json).sql(", 'one', ").visit(path).sql(')'); + break; + + case POSTGRES: + ctx.visit(N_JSONB_PATH_EXISTS).sql('(').visit(castIfNeeded(json, JSONB)).sql(", ").visit(path).sql("::jsonpath)"); + break; + + default: + ctx.visit(K_JSON_EXISTS).sql('(').visit(json).sql(", "); + + + + + + + + + ctx.visit(path); + + + + + + + ctx.sql(')'); + break; + } + } + + enum Behaviour { + ERROR, TRUE, FALSE, UNKNOWN; + + final Keyword keyword; + + Behaviour() { + this.keyword = DSL.keyword(name().toLowerCase()); + } + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONValue.java b/jOOQ/src/main/java/org/jooq/impl/JSONValue.java index d43c02700f..7096c1bd42 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONValue.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONValue.java @@ -37,13 +37,21 @@ */ package org.jooq.impl; +// ... +import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.JSONValue.Behaviour.DEFAULT; import static org.jooq.impl.JSONValue.Behaviour.ERROR; import static org.jooq.impl.JSONValue.Behaviour.NULL; import static org.jooq.impl.Keywords.K_EMPTY; import static org.jooq.impl.Keywords.K_ERROR; import static org.jooq.impl.Keywords.K_ON; +import static org.jooq.impl.Names.N_JSONB_PATH_QUERY_FIRST; +import static org.jooq.impl.Names.N_JSON_EXTRACT; import static org.jooq.impl.Names.N_JSON_VALUE; +import static org.jooq.impl.SQLDataType.JSONB; +import static org.jooq.impl.Tools.castIfNeeded; + +import java.util.Set; import org.jooq.Context; import org.jooq.DataType; @@ -51,6 +59,9 @@ import org.jooq.Field; import org.jooq.JSONValueDefaultStep; import org.jooq.JSONValueOnStep; import org.jooq.Keyword; +// ... +import org.jooq.SQLDialect; +import org.jooq.conf.ParamType; /** @@ -67,10 +78,14 @@ implements /** * Generated UID */ - private static final long serialVersionUID = 1772007627336725780L; + private static final long serialVersionUID = 1772007627336725780L; - private final Field json; - private final Field path; + + + + + private final Field json; + private final Field path; @@ -159,7 +174,29 @@ implements @Override public final void accept(Context ctx) { - ctx.visit(N_JSON_VALUE).sql('(').visit(json).sql(", ").visit(path); + switch (ctx.family()) { + + + + case MYSQL: + ctx.visit(N_JSON_EXTRACT).sql('(').visit(json).sql(", ").visit(path).sql(')'); + break; + + case POSTGRES: + ctx.visit(N_JSONB_PATH_QUERY_FIRST).sql('(').visit(castIfNeeded(json, JSONB)).sql(", ").visit(path).sql("::jsonpath)"); + break; + + default: + ctx.visit(N_JSON_VALUE).sql('(').visit(json).sql(", "); + + + + + + + + + ctx.visit(path); @@ -171,7 +208,9 @@ implements - ctx.sql(')'); + ctx.sql(')'); + break; + } } @@ -191,6 +230,8 @@ implements + + enum Behaviour { ERROR, NULL, DEFAULT; diff --git a/jOOQ/src/main/java/org/jooq/impl/Keywords.java b/jOOQ/src/main/java/org/jooq/impl/Keywords.java index 22fcac23cb..ed2f751037 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Keywords.java +++ b/jOOQ/src/main/java/org/jooq/impl/Keywords.java @@ -217,6 +217,7 @@ final class Keywords { static final Keyword K_ITERATE = keyword("iterate"); static final Keyword K_JSON = keyword("json"); static final Keyword K_JSON_ARRAY = keyword("json_array"); + static final Keyword K_JSON_EXISTS = keyword("json_exists"); static final Keyword K_JSON_OBJECT = keyword("json_object"); static final Keyword K_KEEP = keyword("keep"); static final Keyword K_KEY = keyword("key"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Names.java b/jOOQ/src/main/java/org/jooq/impl/Names.java index 47f5f77871..c8860d111d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Names.java +++ b/jOOQ/src/main/java/org/jooq/impl/Names.java @@ -46,127 +46,131 @@ import org.jooq.Name; */ final class Names { - static final Name N_ARRAY_TABLE = DSL.name("array_table"); - static final Name N_COLUMN_VALUE = DSL.name("COLUMN_VALUE"); + static final Name N_ARRAY_TABLE = DSL.name("array_table"); + static final Name N_COLUMN_VALUE = DSL.name("COLUMN_VALUE"); - static final Name N_ACOS = DSL.unquotedName("acos"); - static final Name N_ARRAY = DSL.unquotedName("array"); - static final Name N_ARRAY_AGG = DSL.unquotedName("array_agg"); - static final Name N_ASCII = DSL.unquotedName("ascii"); - static final Name N_ASIN = DSL.unquotedName("asin"); - static final Name N_ATAN = DSL.unquotedName("atan"); - static final Name N_BIT_COUNT = DSL.unquotedName("bit_count"); - static final Name N_CASE = DSL.unquotedName("case"); - static final Name N_CAST = DSL.unquotedName("cast"); - static final Name N_CEIL = DSL.unquotedName("ceil"); - static final Name N_CHOOSE = DSL.unquotedName("choose"); - static final Name N_COALESCE = DSL.unquotedName("coalesce"); - static final Name N_COLLECT = DSL.unquotedName("collect"); - static final Name N_CONCAT = DSL.unquotedName("concat"); - static final Name N_CONVERT = DSL.unquotedName("convert"); - static final Name N_COSH = DSL.unquotedName("cosh"); - static final Name N_COT = DSL.unquotedName("cot"); - static final Name N_CURRENT_DATE = DSL.unquotedName("current_date"); - static final Name N_CURRENT_SCHEMA = DSL.unquotedName("current_schema"); - static final Name N_CURRENT_TIME = DSL.unquotedName("current_time"); - static final Name N_CURRENT_TIMESTAMP = DSL.unquotedName("current_timestamp"); - static final Name N_CURRENT_USER = DSL.unquotedName("current_user"); - static final Name N_CURRVAL = DSL.unquotedName("currval"); - static final Name N_DATEADD = DSL.unquotedName("dateadd"); - static final Name N_DATEDIFF = DSL.unquotedName("datediff"); - static final Name N_DECODE = DSL.unquotedName("decode"); - static final Name N_DEGREES = DSL.unquotedName("degrees"); - static final Name N_DUAL = DSL.unquotedName("dual"); - static final Name N_E = DSL.unquotedName("e"); - static final Name N_EXP = DSL.unquotedName("exp"); - static final Name N_EXTRACT = DSL.unquotedName("extract"); - static final Name N_FLASHBACK = DSL.unquotedName("flashback"); - static final Name N_FLOOR = DSL.unquotedName("floor"); - static final Name N_FUNCTION = DSL.unquotedName("function"); - static final Name N_GENERATE_SERIES = DSL.unquotedName("generate_series"); - static final Name N_GREATEST = DSL.unquotedName("greatest"); - static final Name N_GROUP_CONCAT = DSL.unquotedName("group_concat"); - static final Name N_IIF = DSL.unquotedName("iif"); - static final Name N_JOIN = DSL.unquotedName("join"); - static final Name N_JSON_AGG = DSL.unquotedName("json_agg"); - static final Name N_JSON_ARRAY = DSL.unquotedName("json_array"); - static final Name N_JSON_ARRAYAGG = DSL.unquotedName("json_arrayagg"); - static final Name N_JSON_OBJECT = DSL.unquotedName("json_object"); - static final Name N_JSON_OBJECT_AGG = DSL.unquotedName("json_object_agg"); - static final Name N_JSON_OBJECTAGG = DSL.unquotedName("json_objectagg"); - static final Name N_JSON_VALUE = DSL.unquotedName("json_value"); - static final Name N_JSONB_AGG = DSL.unquotedName("jsonb_agg"); - static final Name N_JSONB_OBJECT = DSL.unquotedName("jsonb_object"); - static final Name N_JSONB_OBJECT_AGG = DSL.unquotedName("jsonb_object_agg"); - static final Name N_JSONB_OBJECTAGG = DSL.unquotedName("jsonb_objectagg"); - static final Name N_LEAST = DSL.unquotedName("least"); - static final Name N_LEFT = DSL.unquotedName("left"); - static final Name N_LIST = DSL.unquotedName("list"); - static final Name N_LISTAGG = DSL.unquotedName("listagg"); - static final Name N_LN = DSL.unquotedName("ln"); - static final Name N_LOWER = DSL.unquotedName("lower"); - static final Name N_LPAD = DSL.unquotedName("lpad"); - static final Name N_LTRIM = DSL.unquotedName("ltrim"); - static final Name N_MD5 = DSL.unquotedName("md5"); - static final Name N_MEDIAN = DSL.unquotedName("median"); - static final Name N_MOD = DSL.unquotedName("mod"); - static final Name N_MODE = DSL.unquotedName("mode"); - static final Name N_NEXTVAL = DSL.unquotedName("nextval"); - static final Name N_NOT = DSL.unquotedName("not"); - static final Name N_NTILE = DSL.unquotedName("ntile"); - static final Name N_NULLIF = DSL.unquotedName("nullif"); - static final Name N_NVL = DSL.unquotedName("nvl"); - static final Name N_NVL2 = DSL.unquotedName("nvl2"); - static final Name N_OVERLAY = DSL.unquotedName("overlay"); - static final Name N_PI = DSL.unquotedName("pi"); - static final Name N_PIVOT = DSL.unquotedName("pivot"); - static final Name N_POSITION = DSL.unquotedName("position"); - static final Name N_POWER = DSL.unquotedName("power"); - static final Name N_PRIOR = DSL.unquotedName("prior"); - static final Name N_PRODUCT = DSL.unquotedName("product"); - static final Name N_RADIANS = DSL.unquotedName("radians"); - static final Name N_RANDOM = DSL.unquotedName("rand"); - static final Name N_REPLACE = DSL.unquotedName("replace"); - static final Name N_REVERSE = DSL.unquotedName("reverse"); - static final Name N_RIGHT = DSL.unquotedName("right"); - static final Name N_ROLLUP = DSL.unquotedName("rollup"); - static final Name N_ROUND = DSL.unquotedName("round"); - static final Name N_ROW = DSL.unquotedName("row"); - static final Name N_ROW_NUMBER = DSL.unquotedName("row_number"); - static final Name N_ROWNUM = DSL.unquotedName("rownum"); - static final Name N_ROWSFROM = DSL.unquotedName("rowsfrom"); - static final Name N_RPAD = DSL.unquotedName("rpad"); - static final Name N_RTRIM = DSL.unquotedName("rtrim"); - static final Name N_SELECT = DSL.unquotedName("select"); - static final Name N_SIGN = DSL.unquotedName("sign"); - static final Name N_SINH = DSL.unquotedName("sinh"); - static final Name N_SPACE = DSL.unquotedName("space"); - static final Name N_SQRT = DSL.unquotedName("sqrt"); - static final Name N_STATS_MODE = DSL.unquotedName("stats_mode"); - static final Name N_STRING_AGG = DSL.unquotedName("string_agg"); - static final Name N_SUBSTRING = DSL.unquotedName("substring"); - static final Name N_SYSTEM_TIME = DSL.unquotedName("system_time"); - static final Name N_T = DSL.unquotedName("t"); - static final Name N_TANH = DSL.unquotedName("tanh"); - static final Name N_TIMESTAMPDIFF = DSL.unquotedName("timestampdiff"); - static final Name N_TRANSLATE = DSL.unquotedName("translate"); - static final Name N_TRIM = DSL.unquotedName("trim"); - static final Name N_TRUNC = DSL.unquotedName("trunc"); - static final Name N_UPPER = DSL.unquotedName("upper"); - static final Name N_VALUES = DSL.unquotedName("values"); - static final Name N_WIDTH_BUCKET = DSL.unquotedName("width_bucket"); - static final Name N_XMLAGG = DSL.unquotedName("xmlagg"); - static final Name N_XMLATTRIBUTES = DSL.unquotedName("xmlattributes"); - static final Name N_XMLCOMMENT = DSL.unquotedName("xmlcomment"); - static final Name N_XMLCONCAT = DSL.unquotedName("xmlconcat"); - static final Name N_XMLDOCUMENT = DSL.unquotedName("xmldocument"); - static final Name N_XMLELEMENT = DSL.unquotedName("xmlelement"); - static final Name N_XMLFOREST = DSL.unquotedName("xmlforest"); - static final Name N_XMLPARSE = DSL.unquotedName("xmlparse"); - static final Name N_XMLPI = DSL.unquotedName("xmlpi"); - static final Name N_XMLQUERY = DSL.unquotedName("xmlquery"); - static final Name N_XMLROOT = DSL.unquotedName("xmlroot"); - static final Name N_XMLTABLE = DSL.unquotedName("xmltable"); - static final Name N_XPATH = DSL.unquotedName("xpath"); + static final Name N_ACOS = DSL.unquotedName("acos"); + static final Name N_ARRAY = DSL.unquotedName("array"); + static final Name N_ARRAY_AGG = DSL.unquotedName("array_agg"); + static final Name N_ASCII = DSL.unquotedName("ascii"); + static final Name N_ASIN = DSL.unquotedName("asin"); + static final Name N_ATAN = DSL.unquotedName("atan"); + static final Name N_BIT_COUNT = DSL.unquotedName("bit_count"); + static final Name N_CASE = DSL.unquotedName("case"); + static final Name N_CAST = DSL.unquotedName("cast"); + static final Name N_CEIL = DSL.unquotedName("ceil"); + static final Name N_CHOOSE = DSL.unquotedName("choose"); + static final Name N_COALESCE = DSL.unquotedName("coalesce"); + static final Name N_COLLECT = DSL.unquotedName("collect"); + static final Name N_CONCAT = DSL.unquotedName("concat"); + static final Name N_CONVERT = DSL.unquotedName("convert"); + static final Name N_COSH = DSL.unquotedName("cosh"); + static final Name N_COT = DSL.unquotedName("cot"); + static final Name N_CURRENT_DATE = DSL.unquotedName("current_date"); + static final Name N_CURRENT_SCHEMA = DSL.unquotedName("current_schema"); + static final Name N_CURRENT_TIME = DSL.unquotedName("current_time"); + static final Name N_CURRENT_TIMESTAMP = DSL.unquotedName("current_timestamp"); + static final Name N_CURRENT_USER = DSL.unquotedName("current_user"); + static final Name N_CURRVAL = DSL.unquotedName("currval"); + static final Name N_DATEADD = DSL.unquotedName("dateadd"); + static final Name N_DATEDIFF = DSL.unquotedName("datediff"); + static final Name N_DECODE = DSL.unquotedName("decode"); + static final Name N_DEGREES = DSL.unquotedName("degrees"); + static final Name N_DUAL = DSL.unquotedName("dual"); + static final Name N_E = DSL.unquotedName("e"); + static final Name N_EXP = DSL.unquotedName("exp"); + static final Name N_EXTRACT = DSL.unquotedName("extract"); + static final Name N_FLASHBACK = DSL.unquotedName("flashback"); + static final Name N_FLOOR = DSL.unquotedName("floor"); + static final Name N_FUNCTION = DSL.unquotedName("function"); + static final Name N_GENERATE_SERIES = DSL.unquotedName("generate_series"); + static final Name N_GREATEST = DSL.unquotedName("greatest"); + static final Name N_GROUP_CONCAT = DSL.unquotedName("group_concat"); + static final Name N_IIF = DSL.unquotedName("iif"); + static final Name N_JOIN = DSL.unquotedName("join"); + static final Name N_JSON_AGG = DSL.unquotedName("json_agg"); + static final Name N_JSON_ARRAY = DSL.unquotedName("json_array"); + static final Name N_JSON_ARRAYAGG = DSL.unquotedName("json_arrayagg"); + static final Name N_JSON_CONTAINS_PATH = DSL.unquotedName("json_contains_path"); + static final Name N_JSON_EXTRACT = DSL.unquotedName("json_extract"); + static final Name N_JSON_OBJECT = DSL.unquotedName("json_object"); + static final Name N_JSON_OBJECT_AGG = DSL.unquotedName("json_object_agg"); + static final Name N_JSON_OBJECTAGG = DSL.unquotedName("json_objectagg"); + static final Name N_JSON_VALUE = DSL.unquotedName("json_value"); + static final Name N_JSONB_AGG = DSL.unquotedName("jsonb_agg"); + static final Name N_JSONB_OBJECT = DSL.unquotedName("jsonb_object"); + static final Name N_JSONB_OBJECT_AGG = DSL.unquotedName("jsonb_object_agg"); + static final Name N_JSONB_OBJECTAGG = DSL.unquotedName("jsonb_objectagg"); + static final Name N_JSONB_PATH_EXISTS = DSL.unquotedName("jsonb_path_exists"); + static final Name N_JSONB_PATH_QUERY_FIRST = DSL.unquotedName("jsonb_path_query_first"); + static final Name N_LEAST = DSL.unquotedName("least"); + static final Name N_LEFT = DSL.unquotedName("left"); + static final Name N_LIST = DSL.unquotedName("list"); + static final Name N_LISTAGG = DSL.unquotedName("listagg"); + static final Name N_LN = DSL.unquotedName("ln"); + static final Name N_LOWER = DSL.unquotedName("lower"); + static final Name N_LPAD = DSL.unquotedName("lpad"); + static final Name N_LTRIM = DSL.unquotedName("ltrim"); + static final Name N_MD5 = DSL.unquotedName("md5"); + static final Name N_MEDIAN = DSL.unquotedName("median"); + static final Name N_MOD = DSL.unquotedName("mod"); + static final Name N_MODE = DSL.unquotedName("mode"); + static final Name N_NEXTVAL = DSL.unquotedName("nextval"); + static final Name N_NOT = DSL.unquotedName("not"); + static final Name N_NTILE = DSL.unquotedName("ntile"); + static final Name N_NULLIF = DSL.unquotedName("nullif"); + static final Name N_NVL = DSL.unquotedName("nvl"); + static final Name N_NVL2 = DSL.unquotedName("nvl2"); + static final Name N_OVERLAY = DSL.unquotedName("overlay"); + static final Name N_PI = DSL.unquotedName("pi"); + static final Name N_PIVOT = DSL.unquotedName("pivot"); + static final Name N_POSITION = DSL.unquotedName("position"); + static final Name N_POWER = DSL.unquotedName("power"); + static final Name N_PRIOR = DSL.unquotedName("prior"); + static final Name N_PRODUCT = DSL.unquotedName("product"); + static final Name N_RADIANS = DSL.unquotedName("radians"); + static final Name N_RANDOM = DSL.unquotedName("rand"); + static final Name N_REPLACE = DSL.unquotedName("replace"); + static final Name N_REVERSE = DSL.unquotedName("reverse"); + static final Name N_RIGHT = DSL.unquotedName("right"); + static final Name N_ROLLUP = DSL.unquotedName("rollup"); + static final Name N_ROUND = DSL.unquotedName("round"); + static final Name N_ROW = DSL.unquotedName("row"); + static final Name N_ROW_NUMBER = DSL.unquotedName("row_number"); + static final Name N_ROWNUM = DSL.unquotedName("rownum"); + static final Name N_ROWSFROM = DSL.unquotedName("rowsfrom"); + static final Name N_RPAD = DSL.unquotedName("rpad"); + static final Name N_RTRIM = DSL.unquotedName("rtrim"); + static final Name N_SELECT = DSL.unquotedName("select"); + static final Name N_SIGN = DSL.unquotedName("sign"); + static final Name N_SINH = DSL.unquotedName("sinh"); + static final Name N_SPACE = DSL.unquotedName("space"); + static final Name N_SQRT = DSL.unquotedName("sqrt"); + static final Name N_STATS_MODE = DSL.unquotedName("stats_mode"); + static final Name N_STRING_AGG = DSL.unquotedName("string_agg"); + static final Name N_SUBSTRING = DSL.unquotedName("substring"); + static final Name N_SYSTEM_TIME = DSL.unquotedName("system_time"); + static final Name N_T = DSL.unquotedName("t"); + static final Name N_TANH = DSL.unquotedName("tanh"); + static final Name N_TIMESTAMPDIFF = DSL.unquotedName("timestampdiff"); + static final Name N_TRANSLATE = DSL.unquotedName("translate"); + static final Name N_TRIM = DSL.unquotedName("trim"); + static final Name N_TRUNC = DSL.unquotedName("trunc"); + static final Name N_UPPER = DSL.unquotedName("upper"); + static final Name N_VALUES = DSL.unquotedName("values"); + static final Name N_WIDTH_BUCKET = DSL.unquotedName("width_bucket"); + static final Name N_XMLAGG = DSL.unquotedName("xmlagg"); + static final Name N_XMLATTRIBUTES = DSL.unquotedName("xmlattributes"); + static final Name N_XMLCOMMENT = DSL.unquotedName("xmlcomment"); + static final Name N_XMLCONCAT = DSL.unquotedName("xmlconcat"); + static final Name N_XMLDOCUMENT = DSL.unquotedName("xmldocument"); + static final Name N_XMLELEMENT = DSL.unquotedName("xmlelement"); + static final Name N_XMLFOREST = DSL.unquotedName("xmlforest"); + static final Name N_XMLPARSE = DSL.unquotedName("xmlparse"); + static final Name N_XMLPI = DSL.unquotedName("xmlpi"); + static final Name N_XMLQUERY = DSL.unquotedName("xmlquery"); + static final Name N_XMLROOT = DSL.unquotedName("xmlroot"); + static final Name N_XMLTABLE = DSL.unquotedName("xmltable"); + static final Name N_XPATH = DSL.unquotedName("xpath"); } diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 61ae53e4ad..8dd1126457 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -154,6 +154,7 @@ import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.isnull; import static org.jooq.impl.DSL.isoDayOfWeek; import static org.jooq.impl.DSL.jsonEntry; +import static org.jooq.impl.DSL.jsonExists; import static org.jooq.impl.DSL.jsonValue; import static org.jooq.impl.DSL.keyword; import static org.jooq.impl.DSL.lag; @@ -4712,6 +4713,25 @@ final class ParserImpl implements Parser { return unique(select); } + else if (parseKeywordIf(ctx, "JSON_EXISTS")) { + parse(ctx, '('); + Field json = parseField(ctx); + parse(ctx, ','); + Field path = (Field) parseField(ctx); + JSONExists.Behaviour b = parseJSONExistsOnErrorBehaviourIf(ctx); + parse(ctx, ')'); + + if (b == JSONExists.Behaviour.ERROR) + return jsonExists(json, path).errorOnError(); + else if (b == JSONExists.Behaviour.TRUE) + return jsonExists(json, path).trueOnError(); + else if (b == JSONExists.Behaviour.FALSE) + return jsonExists(json, path).falseOnError(); + else if (b == JSONExists.Behaviour.UNKNOWN) + return jsonExists(json, path).unknownOnError(); + else + return jsonExists(json, path); + } else if (parseKeywordIf(ctx, "XMLEXISTS")) { parse(ctx, '('); Field xpath = (Field) parseField(ctx); @@ -6975,12 +6995,12 @@ final class ParserImpl implements Parser { private static final Field parseFieldJSONValueIf(ParserContext ctx) { if (parseFunctionNameIf(ctx, "JSON_VALUE")) { parse(ctx, '('); - Field json = parseField(ctx); + Field json = parseField(ctx); parse(ctx, ','); Field path = (Field) parseField(ctx); JSONValueOnStep s1 = jsonValue(json, path); - JSONValue.Behaviour behaviour = parseBehaviourIf(ctx); + JSONValue.Behaviour behaviour = parseJSONValueBehaviourIf(ctx); @@ -7020,7 +7040,7 @@ final class ParserImpl implements Parser { return null; } - private static final JSONValue.Behaviour parseBehaviourIf(ParserContext ctx) { + private static final JSONValue.Behaviour parseJSONValueBehaviourIf(ParserContext ctx) { if (parseKeywordIf(ctx, "ERROR") && ctx.requireProEdition()) return JSONValue.Behaviour.ERROR; else if (parseKeywordIf(ctx, "NULL") && ctx.requireProEdition()) @@ -7031,6 +7051,19 @@ final class ParserImpl implements Parser { return null; } + private static final JSONExists.Behaviour parseJSONExistsOnErrorBehaviourIf(ParserContext ctx) { + if (parseKeywordIf(ctx, "ERROR") && parseKeyword(ctx, "ON ERROR") && ctx.requireProEdition()) + return JSONExists.Behaviour.ERROR; + else if (parseKeywordIf(ctx, "TRUE") && parseKeyword(ctx, "ON ERROR") && ctx.requireProEdition()) + return JSONExists.Behaviour.TRUE; + else if (parseKeywordIf(ctx, "FALSE") && parseKeyword(ctx, "ON ERROR") && ctx.requireProEdition()) + return JSONExists.Behaviour.FALSE; + else if (parseKeywordIf(ctx, "UNKNOWN") && parseKeyword(ctx, "ON ERROR") && ctx.requireProEdition()) + return JSONExists.Behaviour.UNKNOWN; + else + return null; + } + private static final Field parseFieldJSONArrayConstructorIf(ParserContext ctx) { if (parseFunctionNameIf(ctx, "JSON_ARRAY")) { parse(ctx, '(');