Skip to content

Commit a87f797

Browse files
committed
[feat] JSON_OBJECT support for AllColumns and AllTableColumns
1 parent 157988d commit a87f797

File tree

4 files changed

+75
-9
lines changed

4 files changed

+75
-9
lines changed

build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ configurations.configureEach {
131131
}
132132

133133
compileJavacc {
134-
arguments = [grammar_encoding: 'UTF-8', static: 'false', java_template_type: 'modern']
134+
arguments = [
135+
grammar_encoding: 'UTF-8',
136+
static: 'false',
137+
java_template_type: 'modern',
138+
// Comment this in to build the parser with tracing. Setting it to false does NOT disable it
139+
DEBUG_PARSER: 'false'
140+
]
135141
}
136142

137143
java {

src/main/java/net/sf/jsqlparser/expression/JsonFunction.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public class JsonFunction extends ASTNodeAccessImpl implements Expression {
2525
private JsonAggregateOnNullType onNullType;
2626
private JsonAggregateUniqueKeysType uniqueKeysType;
2727

28+
private boolean isStrict = false;
29+
2830
public ArrayList<JsonKeyValuePair> getKeyValuePairs() {
2931
return keyValuePairs;
3032
}
@@ -114,6 +116,19 @@ public JsonFunction withType(String typeName) {
114116
return this;
115117
}
116118

119+
public boolean isStrict() {
120+
return isStrict;
121+
}
122+
123+
public void setStrict(boolean strict) {
124+
isStrict = strict;
125+
}
126+
127+
public JsonFunction withStrict(boolean strict) {
128+
this.setStrict(strict);
129+
return this;
130+
}
131+
117132
@Override
118133
public <T, S> T accept(ExpressionVisitor<T> expressionVisitor, S context) {
119134
return expressionVisitor.visit(this, context);
@@ -164,19 +179,33 @@ public StringBuilder appendObject(StringBuilder builder) {
164179
i++;
165180
}
166181

182+
appendOnNullType(builder);
183+
if (isStrict) {
184+
builder.append(" STRICT");
185+
}
186+
appendUniqueKeys(builder);
187+
188+
builder.append(" ) ");
189+
190+
return builder;
191+
}
192+
193+
private void appendOnNullType(StringBuilder builder) {
167194
if (onNullType != null) {
168195
switch (onNullType) {
169196
case NULL:
170197
builder.append(" NULL ON NULL");
171198
break;
172199
case ABSENT:
173-
builder.append(" ABSENT On NULL");
200+
builder.append(" ABSENT ON NULL");
174201
break;
175202
default:
176203
// this should never happen
177204
}
178205
}
206+
}
179207

208+
private void appendUniqueKeys(StringBuilder builder) {
180209
if (uniqueKeysType != null) {
181210
switch (uniqueKeysType) {
182211
case WITH:
@@ -189,10 +218,6 @@ public StringBuilder appendObject(StringBuilder builder) {
189218
// this should never happen
190219
}
191220
}
192-
193-
builder.append(" ) ");
194-
195-
return builder;
196221
}
197222

198223

@@ -205,6 +230,13 @@ public StringBuilder appendPostgresObject(StringBuilder builder) {
205230
builder.append(", ").append(keyValuePair.getValue());
206231
}
207232
}
233+
234+
appendOnNullType(builder);
235+
if (isStrict) {
236+
builder.append(" STRICT");
237+
}
238+
appendUniqueKeys(builder);
239+
208240
builder.append(" ) ");
209241

210242
return builder;

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6967,9 +6967,13 @@ JsonFunction JsonFunction() : {
69676967
"KEY" { usingKeyKeyword = true; } ( keyToken = <S_CHAR_LITERAL> { key = keyToken.image; } | key = Column() )
69686968
)
69696969
|
6970-
keyToken = <S_CHAR_LITERAL> { key = keyToken.image; }
6970+
LOOKAHEAD(2) ( key = AllTableColumns() )
6971+
|
6972+
key = AllColumns()
69716973
|
69726974
key = Column()
6975+
|
6976+
keyToken = <S_CHAR_LITERAL> { key = keyToken.image; }
69736977
)
69746978

69756979
( LOOKAHEAD(2)
@@ -6998,9 +7002,12 @@ JsonFunction JsonFunction() : {
69987002
"KEY" { usingKeyKeyword = true; } ( keyToken = <S_CHAR_LITERAL> { key = keyToken.image; } | key = Column() )
69997003
)
70007004
|
7001-
keyToken = <S_CHAR_LITERAL> { key = keyToken.image; }
7005+
LOOKAHEAD(2) ( key = AllTableColumns() )
70027006
|
70037007
key = Column()
7008+
|
7009+
keyToken = <S_CHAR_LITERAL> { key = keyToken.image; }
7010+
70047011
)
70057012
( ":" | "," { result.setType( JsonFunctionType.MYSQL_OBJECT ); } | "VALUE" { usingValueKeyword = true; } )
70067013
expression = Expression() { keyValuePair = new JsonKeyValuePair( key, expression, usingKeyKeyword, usingValueKeyword ); result.add(keyValuePair); }
@@ -7017,7 +7024,9 @@ JsonFunction JsonFunction() : {
70177024
<K_ABSENT> <K_ON> <K_NULL> { result.setOnNullType( JsonAggregateOnNullType.ABSENT ); }
70187025
)
70197026
]
7020-
7027+
[
7028+
<K_STRICT> { result.setStrict(true); }
7029+
]
70217030
[
70227031
(
70237032
<K_WITH> <K_UNIQUE> <K_KEYS> { result.setUniqueKeysType( JsonAggregateUniqueKeysType.WITH ); }

src/test/java/net/sf/jsqlparser/expression/JsonFunctionTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,25 @@ public void testObject() throws JSQLParserException {
164164
TestUtils.assertExpressionCanBeParsedAndDeparsed("json_object()", true);
165165
}
166166

167+
@Test
168+
void testObjectOracle() throws JSQLParserException {
169+
TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT JSON_OBJECT(*) FROM employees", true);
170+
171+
TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT JSON_OBJECT(* ABSENT ON NULL) FROM employees", true);
172+
173+
TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT JSON_OBJECT(e.*) FROM employees e", true);
174+
175+
TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT JSON_OBJECT(e.*, d.* NULL ON NULL) FROM employees e, departments d", true);
176+
177+
TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT JSON_OBJECT(e.* WITH UNIQUE KEYS) FROM employees e", true);
178+
179+
TestUtils.assertSqlCanBeParsedAndDeparsed(
180+
"SELECT JSON_OBJECT( 'foo':bar, 'fob':baz FORMAT JSON STRICT ) FROM dual ", true);
181+
182+
TestUtils.assertSqlCanBeParsedAndDeparsed(
183+
"SELECT JSON_OBJECT( 'foo':bar, 'fob':baz NULL ON NULL STRICT WITH UNIQUE KEYS) FROM dual ", true);
184+
}
185+
167186
@Test
168187
public void testObjectWithExpression() throws JSQLParserException {
169188
TestUtils.assertSqlCanBeParsedAndDeparsed(

0 commit comments

Comments
 (0)