diff --git a/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/PlSqlKeyword.kt b/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/PlSqlKeyword.kt index 16a4652e..437bf32a 100644 --- a/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/PlSqlKeyword.kt +++ b/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/PlSqlKeyword.kt @@ -281,6 +281,7 @@ enum class PlSqlKeyword(override val value: String, val isReserved: Boolean = fa JSON_MERGEPATCH("json_mergepatch"), JSON_OBJECT("json_object"), JSON_OBJECTAGG("json_objectagg"), + JSON_SCALAR("json_scalar"), JSON_QUERY("json_query"), KEEP("keep"), KEY("key"), diff --git a/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/SingleRowSqlFunctionsGrammar.kt b/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/SingleRowSqlFunctionsGrammar.kt index 5aaa5068..18edbda4 100644 --- a/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/SingleRowSqlFunctionsGrammar.kt +++ b/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/SingleRowSqlFunctionsGrammar.kt @@ -56,6 +56,7 @@ enum class SingleRowSqlFunctionsGrammar : GrammarRuleKey { JSON_ARRAY_EXPRESSION, JSON_MERGEPATCH_EXPRESSION, JSON_OBJECT_EXPRESSION, + JSON_SCALAR_EXPRESSION, JSON_QUERY_EXPRESSION, XMLATTRIBUTES_EXPRESSION, XMLELEMENT_EXPRESSION, @@ -93,6 +94,7 @@ enum class SingleRowSqlFunctionsGrammar : GrammarRuleKey { JSON_ARRAY_EXPRESSION, JSON_MERGEPATCH_EXPRESSION, JSON_OBJECT_EXPRESSION, + JSON_SCALAR_EXPRESSION, JSON_QUERY_EXPRESSION, XMLATTRIBUTES_EXPRESSION, XMLELEMENT_EXPRESSION, @@ -354,6 +356,18 @@ enum class SingleRowSqlFunctionsGrammar : GrammarRuleKey { b.optional(FORMAT, JSON) ) + b.rule(JSON_SCALAR_EXPRESSION).define( + JSON_SCALAR, + LPARENTHESIS, + EXPRESSION, + b.optional(b.firstOf( + b.sequence(b.firstOf(JSON, SQL), NULL), + b.sequence(EMPTY, STRING) + ), ON, NULL), + b.optional(b.firstOf(NULL, ERROR), ON, ERROR), + RPARENTHESIS + ) + b.rule(JSON_QUERY_EXPRESSION).define( JSON_QUERY, LPARENTHESIS, diff --git a/zpa-core/src/test/kotlin/org/sonar/plugins/plsqlopen/api/expressions/JsonScalarTest.kt b/zpa-core/src/test/kotlin/org/sonar/plugins/plsqlopen/api/expressions/JsonScalarTest.kt new file mode 100644 index 00000000..4eb09820 --- /dev/null +++ b/zpa-core/src/test/kotlin/org/sonar/plugins/plsqlopen/api/expressions/JsonScalarTest.kt @@ -0,0 +1,65 @@ +/** + * Z PL/SQL Analyzer + * Copyright (C) 2015-2024 Felipe Zorzo + * mailto:felipe AT felipezorzo DOT com DOT br + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.plugins.plsqlopen.api.expressions + +import com.felipebz.flr.tests.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.sonar.plugins.plsqlopen.api.PlSqlGrammar +import org.sonar.plugins.plsqlopen.api.RuleTest + +class JsonScalarTest : RuleTest() { + + @BeforeEach + fun init() { + setRootRule(PlSqlGrammar.EXPRESSION) + } + + @Test + fun matchesJsonScalar() { + assertThat(p).matches("json_scalar(val)") + } + + @Test + fun matchesJsonScalarJsonNullOnNull() { + assertThat(p).matches("json_scalar(val json null on null)") + } + + @Test + fun matchesJsonScalarSqlNullOnNull() { + assertThat(p).matches("json_scalar(val sql null on null)") + } + + @Test + fun matchesJsonScalarEmptyStringOnNull() { + assertThat(p).matches("json_scalar(val empty string on null)") + } + + @Test + fun matchesJsonScalarJsonNullOnError() { + assertThat(p).matches("json_scalar(val null on error)") + } + + @Test + fun matchesLongJsonScalar() { + assertThat(p).matches("json_scalar(val sql null on null error on error)") + } + +}