Skip to content

Commit

Permalink
feat(hogql): nullish coalescing (#16276)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusandra authored Jun 28, 2023
1 parent 41080c6 commit 63d6abe
Show file tree
Hide file tree
Showing 11 changed files with 1,495 additions and 1,407 deletions.
1 change: 1 addition & 0 deletions posthog/hogql/grammar/HogQLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ LE: '<=';
LPAREN: '(';
LT: '<';
NOT_EQ: '!=' | '<>';
NULLISH: '??';
PERCENT: '%';
PLUS: '+';
QUERY: '?';
Expand Down
5 changes: 4 additions & 1 deletion posthog/hogql/grammar/HogQLLexer.interp

Large diffs are not rendered by default.

1,706 changes: 855 additions & 851 deletions posthog/hogql/grammar/HogQLLexer.py

Large diffs are not rendered by default.

52 changes: 27 additions & 25 deletions posthog/hogql/grammar/HogQLLexer.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,21 @@ LE=218
LPAREN=219
LT=220
NOT_EQ=221
PERCENT=222
PLUS=223
QUERY=224
QUOTE_DOUBLE=225
QUOTE_SINGLE=226
RBRACE=227
RBRACKET=228
RPAREN=229
SEMICOLON=230
SLASH=231
UNDERSCORE=232
MULTI_LINE_COMMENT=233
SINGLE_LINE_COMMENT=234
WHITESPACE=235
NULLISH=222
PERCENT=223
PLUS=224
QUERY=225
QUOTE_DOUBLE=226
QUOTE_SINGLE=227
RBRACE=228
RBRACKET=229
RPAREN=230
SEMICOLON=231
SLASH=232
UNDERSCORE=233
MULTI_LINE_COMMENT=234
SINGLE_LINE_COMMENT=235
WHITESPACE=236
'false'=191
'true'=192
'->'=201
Expand All @@ -255,14 +256,15 @@ WHITESPACE=235
'<='=218
'('=219
'<'=220
'%'=222
'+'=223
'?'=224
'"'=225
'\''=226
'}'=227
']'=228
')'=229
';'=230
'/'=231
'_'=232
'??'=222
'%'=223
'+'=224
'?'=225
'"'=226
'\''=227
'}'=228
']'=229
')'=230
';'=231
'/'=232
'_'=233
1 change: 1 addition & 0 deletions posthog/hogql/grammar/HogQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ columnExpr
| operator=NOT? (LIKE | ILIKE) // like, notLike, ilike, notILike
) right=columnExpr # ColumnExprPrecedence3
| columnExpr IS NOT? NULL_SQL # ColumnExprIsNull
| columnExpr NULLISH columnExpr # ColumnExprNullish
| NOT columnExpr # ColumnExprNot
| columnExpr AND columnExpr # ColumnExprAnd
| columnExpr OR columnExpr # ColumnExprOr
Expand Down
4 changes: 3 additions & 1 deletion posthog/hogql/grammar/HogQLParser.interp

Large diffs are not rendered by default.

1,050 changes: 546 additions & 504 deletions posthog/hogql/grammar/HogQLParser.py

Large diffs are not rendered by default.

52 changes: 27 additions & 25 deletions posthog/hogql/grammar/HogQLParser.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,21 @@ LE=218
LPAREN=219
LT=220
NOT_EQ=221
PERCENT=222
PLUS=223
QUERY=224
QUOTE_DOUBLE=225
QUOTE_SINGLE=226
RBRACE=227
RBRACKET=228
RPAREN=229
SEMICOLON=230
SLASH=231
UNDERSCORE=232
MULTI_LINE_COMMENT=233
SINGLE_LINE_COMMENT=234
WHITESPACE=235
NULLISH=222
PERCENT=223
PLUS=224
QUERY=225
QUOTE_DOUBLE=226
QUOTE_SINGLE=227
RBRACE=228
RBRACKET=229
RPAREN=230
SEMICOLON=231
SLASH=232
UNDERSCORE=233
MULTI_LINE_COMMENT=234
SINGLE_LINE_COMMENT=235
WHITESPACE=236
'false'=191
'true'=192
'->'=201
Expand All @@ -255,14 +256,15 @@ WHITESPACE=235
'<='=218
'('=219
'<'=220
'%'=222
'+'=223
'?'=224
'"'=225
'\''=226
'}'=227
']'=228
')'=229
';'=230
'/'=231
'_'=232
'??'=222
'%'=223
'+'=224
'?'=225
'"'=226
'\''=227
'}'=228
']'=229
')'=230
';'=231
'/'=232
'_'=233
5 changes: 5 additions & 0 deletions posthog/hogql/grammar/HogQLParserVisitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ def visitColumnExprTimestamp(self, ctx:HogQLParser.ColumnExprTimestampContext):
return self.visitChildren(ctx)


# Visit a parse tree produced by HogQLParser#ColumnExprNullish.
def visitColumnExprNullish(self, ctx:HogQLParser.ColumnExprNullishContext):
return self.visitChildren(ctx)


# Visit a parse tree produced by HogQLParser#ColumnExprAnd.
def visitColumnExprAnd(self, ctx:HogQLParser.ColumnExprAndContext):
return self.visitChildren(ctx)
Expand Down
3 changes: 3 additions & 0 deletions posthog/hogql/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,3 +759,6 @@ def visitIdentifier(self, ctx: HogQLParser.IdentifierContext):

def visitEnumValue(self, ctx: HogQLParser.EnumValueContext):
raise NotImplementedException(f"Unsupported node: EnumValue")

def visitColumnExprNullish(self, ctx: HogQLParser.ColumnExprNullishContext):
return ast.Call(name="ifNull", args=[self.visit(ctx.columnExpr(0)), self.visit(ctx.columnExpr(1))])
23 changes: 23 additions & 0 deletions posthog/hogql/test/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,3 +1143,26 @@ def test_null_equality(self):
query = f"select a {op} {b} from (select {a} as a)"
response = execute_hogql_query(query, team=self.team)
self.assertEqual(response.results, [(res,)], query)

def test_nullish_coalescing(self):
query = """
SELECT
null ?? 1,
null ?? null ?? 2,
3 ?? null,
null ?? 'string',
1 + (null ?? 2) + 3,
1 + null ?? 2 + 3,
10 ?? true ? 20 : 30,
10 ?? 5 + 10
"""

response = execute_hogql_query(
query,
team=self.team,
)

self.assertEqual(
response.results,
[(1, 2, 3, "string", 6, 5, 20, 10)],
)

0 comments on commit 63d6abe

Please sign in to comment.