[CALCITE-6255] Support BigQuery-style JSON_OBJECT invocation syntax
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index b11d83e..90497ac 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -6732,6 +6732,12 @@
     (
         <VALUE>
     |
+        <COMMA> {
+            if (kvMode) {
+                throw SqlUtil.newContextException(getPos(), RESOURCE.illegalComma());
+            }
+        }
+    |
         <COLON> {
             if (kvMode) {
                 throw SqlUtil.newContextException(getPos(), RESOURCE.illegalColon());
diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
index 2791918..5a3c6e4 100644
--- a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
+++ b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
@@ -109,9 +109,12 @@
   @BaseMessage("ROW expression encountered in illegal context")
   ExInst<CalciteException> illegalRowExpression();
 
-  @BaseMessage("Illegal identifier '':''. Was expecting ''VALUE''")
+  @BaseMessage("Unexpected symbol '':''. Was expecting ''VALUE''")
   ExInst<CalciteException> illegalColon();
 
+  @BaseMessage("Unexpected symbol '',''. Was expecting ''VALUE''")
+  ExInst<CalciteException> illegalComma();
+
   @BaseMessage("TABLESAMPLE percentage must be between 0 and 100, inclusive")
   @Property(name = "SQLSTATE", value = "2202H")
   ExInst<CalciteException> invalidSampleSize();
diff --git a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
index a0a23f4..32b7bb2 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -8815,6 +8815,16 @@
         .ok("JSON_OBJECT(KEY 'foo' VALUE "
             + "JSON_OBJECT(KEY 'foo' VALUE 'bar' NULL ON NULL) "
             + "FORMAT JSON NULL ON NULL)");
+    expr("json_object('foo', 'bar')")
+        .ok("JSON_OBJECT(KEY 'foo' VALUE 'bar' NULL ON NULL)");
+    expr("json_object('foo', 'bar', 'baz', 'qux')")
+        .ok("JSON_OBJECT(KEY 'foo' VALUE 'bar', KEY 'baz' VALUE 'qux' NULL ON NULL)");
+    expr("json_object('foo', json_object('bar': 'baz') format json)")
+        .ok("JSON_OBJECT(KEY 'foo' VALUE "
+            + "JSON_OBJECT(KEY 'bar' VALUE 'baz' NULL ON NULL) "
+            + "FORMAT JSON NULL ON NULL)");
+    expr("json_object('foo', 'bar', 'baz'^)^")
+        .fails("(?s)Encountered \"\\)\".*Was expecting.*");
 
     if (!Bug.TODO_FIXED) {
       return;