Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;

import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
Expand Down Expand Up @@ -64,6 +65,15 @@ public FunctionSignature customSignature() {
return FunctionSignature.of(JsonType.INSTANCE, arguments);
}

@Override
public void checkLegalityBeforeTypeCoercion() {
// arguments are a JSON document followed by (path, value) pairs, so arity must be odd
if ((arity() & 1) == 0) {
throw new AnalysisException(getName() + " requires a JSON document followed by path/value pairs,"
+ " so the number of arguments must be odd, but got " + arity() + ": " + this.toSql());
}
}

/**
* withChildren.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;

import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
Expand Down Expand Up @@ -64,6 +65,15 @@ public FunctionSignature customSignature() {
return FunctionSignature.of(JsonType.INSTANCE, arguments);
}

@Override
public void checkLegalityBeforeTypeCoercion() {
// arguments are a JSON document followed by (path, value) pairs, so arity must be odd
if ((arity() & 1) == 0) {
throw new AnalysisException(getName() + " requires a JSON document followed by path/value pairs,"
+ " so the number of arguments must be odd, but got " + arity() + ": " + this.toSql());
}
}

/**
* withChildren.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.doris.nereids.trees.expressions.functions.scalar;

import org.apache.doris.catalog.FunctionSignature;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
import org.apache.doris.nereids.trees.expressions.functions.CustomSignature;
Expand Down Expand Up @@ -64,6 +65,15 @@ public FunctionSignature customSignature() {
return FunctionSignature.of(JsonType.INSTANCE, arguments);
}

@Override
public void checkLegalityBeforeTypeCoercion() {
// arguments are a JSON document followed by (path, value) pairs, so arity must be odd
if ((arity() & 1) == 0) {
throw new AnalysisException(getName() + " requires a JSON document followed by path/value pairs,"
+ " so the number of arguments must be odd, but got " + arity() + ": " + this.toSql());
}
}

/**
* withChildren.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ public void testArraySortLambdaArgumentCount() {
});
}

@Test
public void testJsonModifyFunctionsRejectEvenArity() {
ConnectContext connectContext = MemoTestUtils.createConnectContext();
for (String function : new String[] {"json_set", "jsonb_set", "json_insert", "jsonb_insert",
"json_replace", "jsonb_replace"}) {
ExceptionChecker.expectThrowsWithMsg(AnalysisException.class,
"number of arguments must be odd, but got 4", () ->
PlanChecker.from(connectContext)
.analyze("select " + function + "('{}', '$.a', 1, '$.b')"));
ExceptionChecker.expectThrowsWithMsg(AnalysisException.class,
"number of arguments must be odd, but got 6", () ->
PlanChecker.from(connectContext)
.analyze("select " + function + "('{}', '$.a', 1, '$.b', 2, '$.c')"));
PlanChecker.from(connectContext).analyze("select " + function + "('{}', '$.a', 1)");
PlanChecker.from(connectContext).analyze("select " + function + "('{}', '$.a', 1, '$.b', 2)");
}
}

@Test
public void testCountDistinctBitmap() {
ConnectContext connectContext = MemoTestUtils.createConnectContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,6 @@
-- !insert7 --
{"a":200}

-- !insert_odd_arity_ok --
{"a":1} {"a":1,"b":2} {"a":1,"b":2}

Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,6 @@ null
-- !replace8 --
{"a":100}

-- !replace_odd_arity_ok --
{} {} {}

Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,6 @@ null
-- !set8 --
{"a":100}

-- !set_odd_arity_ok --
{"a":1} {"a":1,"b":2} {"a":1,"b":2}

Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,26 @@ suite("test_query_json_insert", "query,arrow_flight_sql") {
sql "select json_insert('1', '\$.', 4);"
exception "Json path error: Invalid Json Path for value"
}

// arguments must be a JSON document followed by path/value pairs, so an even count is rejected by FE
test {
sql "select json_insert('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}

test {
sql "select json_insert('{}', '\$.a', 1, '\$.b', 2, '\$.c');"
exception "number of arguments must be odd, but got 6"
}

test {
sql "select jsonb_insert('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}

test {
sql "explain select json_insert('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}
qt_insert_odd_arity_ok """select json_insert('{}', '\$.a', 1), json_insert('{}', '\$.a', 1, '\$.b', 2), jsonb_insert('{}', '\$.a', 1, '\$.b', 2);"""
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,26 @@ suite("test_query_json_replace", "query") {
sql "select json_replace('1', '\$.', 4);"
exception "Json path error: Invalid Json Path for value"
}

// arguments must be a JSON document followed by path/value pairs, so an even count is rejected by FE
test {
sql "select json_replace('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}

test {
sql "select json_replace('{}', '\$.a', 1, '\$.b', 2, '\$.c');"
exception "number of arguments must be odd, but got 6"
}

test {
sql "select jsonb_replace('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}

test {
sql "explain select json_replace('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}
qt_replace_odd_arity_ok """select json_replace('{}', '\$.a', 1), json_replace('{}', '\$.a', 1, '\$.b', 2), jsonb_replace('{}', '\$.a', 1, '\$.b', 2);"""
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,26 @@ suite("test_query_json_set", "query") {
sql "select json_set('1', '\$.', 4);"
exception "Json path error: Invalid Json Path for value"
}

// arguments must be a JSON document followed by path/value pairs, so an even count is rejected by FE
test {
sql "select json_set('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}

test {
sql "select json_set('{}', '\$.a', 1, '\$.b', 2, '\$.c');"
exception "number of arguments must be odd, but got 6"
}

test {
sql "select jsonb_set('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}

test {
sql "explain select json_set('{}', '\$.a', 1, '\$.b');"
exception "number of arguments must be odd, but got 4"
}
qt_set_odd_arity_ok """select json_set('{}', '\$.a', 1), json_set('{}', '\$.a', 1, '\$.b', 2), jsonb_set('{}', '\$.a', 1, '\$.b', 2);"""
}
Loading