diff --git a/zpa-checks/src/integrationTest/resources/expected/oracle-database_19/ParsingErrorCheck.json b/zpa-checks/src/integrationTest/resources/expected/oracle-database_19/ParsingErrorCheck.json index ff862183..c4564591 100644 --- a/zpa-checks/src/integrationTest/resources/expected/oracle-database_19/ParsingErrorCheck.json +++ b/zpa-checks/src/integrationTest/resources/expected/oracle-database_19/ParsingErrorCheck.json @@ -2153,9 +2153,6 @@ "Interval-Expressions-0.sql" : [ 2 ], - "JSON_OBJECTAGG-0.sql" : [ - 2 - ], "JSON_TABLE-0.sql" : [ 5 ], diff --git a/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/AggregateSqlFunctionsGrammar.kt b/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/AggregateSqlFunctionsGrammar.kt index 6ccda840..770a8762 100644 --- a/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/AggregateSqlFunctionsGrammar.kt +++ b/zpa-core/src/main/kotlin/org/sonar/plugins/plsqlopen/api/AggregateSqlFunctionsGrammar.kt @@ -32,6 +32,7 @@ enum class AggregateSqlFunctionsGrammar : GrammarRuleKey { XMLAGG_EXPRESSION, COLLECT_EXPRESSION, JSON_ARRAYAGG_EXPRESSION, + JSON_OBJECTAGG_EXPRESSION, AGGREGATE_SQL_FUNCTION; companion object { @@ -69,12 +70,24 @@ enum class AggregateSqlFunctionsGrammar : GrammarRuleKey { RPARENTHESIS ) + b.rule(JSON_OBJECTAGG_EXPRESSION).define( + JSON_OBJECTAGG, LPARENTHESIS, + b.optional(KEY), EXPRESSION, VALUE, EXPRESSION, + b.optional(FORMAT, JSON), + b.optional(SingleRowSqlFunctionsGrammar.JSON_ON_NULL_CLAUSE), + b.optional(SingleRowSqlFunctionsGrammar.JSON_RETURNING_CLAUSE), + b.optional(STRICT), + b.optional(WITH, UNIQUE, KEYS), + RPARENTHESIS + ) + b.rule(AGGREGATE_SQL_FUNCTION).define( b.firstOf( LISTAGG_EXPRESSION, XMLAGG_EXPRESSION, COLLECT_EXPRESSION, - JSON_ARRAYAGG_EXPRESSION + JSON_ARRAYAGG_EXPRESSION, + JSON_OBJECTAGG_EXPRESSION ) ) } 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 3cb104fa..16a4652e 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 @@ -280,6 +280,7 @@ enum class PlSqlKeyword(override val value: String, val isReserved: Boolean = fa JSON_ARRAYAGG("json_arrayagg"), JSON_MERGEPATCH("json_mergepatch"), JSON_OBJECT("json_object"), + JSON_OBJECTAGG("json_objectagg"), JSON_QUERY("json_query"), KEEP("keep"), KEY("key"), diff --git a/zpa-core/src/test/kotlin/org/sonar/plugins/plsqlopen/api/expressions/JsonObjectAggExpressionTest.kt b/zpa-core/src/test/kotlin/org/sonar/plugins/plsqlopen/api/expressions/JsonObjectAggExpressionTest.kt new file mode 100644 index 00000000..6042d42a --- /dev/null +++ b/zpa-core/src/test/kotlin/org/sonar/plugins/plsqlopen/api/expressions/JsonObjectAggExpressionTest.kt @@ -0,0 +1,68 @@ +/** + * 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 JsonObjectAggExpressionTest : RuleTest() { + + @BeforeEach + fun init() { + setRootRule(PlSqlGrammar.EXPRESSION) + } + + @Test + fun matchesSimpleJsonObjectAgg() { + assertThat(p).matches("json_objectagg(k value 'v')") + } + + @Test + fun matchesJsonObjectAggWithExplicitKey() { + assertThat(p).matches("json_objectagg(key k value 'v')") + } + + @Test + fun matchesJsonObjectAggWithFormatJson() { + assertThat(p).matches("json_objectagg('k' value '{}' format json)") + } + + @Test + fun matchesJsonObjectAggWithReturning() { + assertThat(p).matches("json_objectagg(k value 'v' returning clob)") + } + + @Test + fun matchesJsonObjectAggWithAbsentOnNull() { + assertThat(p).matches("json_objectagg('v' value val absent on null)") + } + + @Test + fun matchesLongJsonObjectAgg() { + assertThat(p).matches("""json_objectagg('a' value '{}' format json + null on null + returning varchar2(200) + strict with unique keys)""") + } + +}