Skip to content

Commit

Permalink
Merge pull request #43 from shellcromancer/main
Browse files Browse the repository at this point in the history
feat: add kusto scalar functions: now(), toupper(), tolower()
  • Loading branch information
abraithwaite authored Mar 5, 2024
2 parents d5ecd4e + 9bf8648 commit 2f99ca8
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# binaries in cmd/
pql
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,16 @@ list will be passed through to the underlying SQL engine. This allows the usage
of the full APIs implemented by the underlying engine.

- [`not`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/not-function)
- [`now`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/now-function)
- [`isnull`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/isnull-function)
and [`isnotnull`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/isnotnull-function)
- [`strcat`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/strcat-function)
- [`iff`/`iif`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/iff-function)
- [`count`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/count-aggregation-function)
- [`countif`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/countif-aggregation-function)
- [`tolower`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/tolower-function)
- [`toupper`](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/toupper-function)


Column names with special characters can be escaped with backticks.

Expand Down
66 changes: 61 additions & 5 deletions pql.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,14 +711,17 @@ var knownFunctions struct {
func initKnownFunctions() map[string]*functionRewrite {
knownFunctions.init.Do(func() {
knownFunctions.m = map[string]*functionRewrite{
"not": {write: writeNotFunction},
"isnull": {write: writeIsNullFunction, needsParens: true},
"isnotnull": {write: writeIsNotNullFunction, needsParens: true},
"strcat": {write: writeStrcatFunction, needsParens: true},
"count": {write: writeCountFunction},
"countif": {write: writeCountIfFunction},
"iff": {write: writeIfFunction, needsParens: true},
"iif": {write: writeIfFunction, needsParens: true},
"iff": {write: writeIfFunction, needsParens: true},
"isnotnull": {write: writeIsNotNullFunction, needsParens: true},
"isnull": {write: writeIsNullFunction, needsParens: true},
"not": {write: writeNotFunction},
"now": {write: writeNowFunction},
"strcat": {write: writeStrcatFunction, needsParens: true},
"tolower": {write: writeToLowerFunction, needsParens: true},
"toupper": {write: writeToUpperFunction, needsParens: true},
}
})
return knownFunctions.m
Expand All @@ -742,6 +745,21 @@ func writeNotFunction(ctx *exprContext, sb *strings.Builder, x *parser.CallExpr)
return nil
}

func writeNowFunction(ctx *exprContext, sb *strings.Builder, x *parser.CallExpr) error {
if len(x.Args) != 0 {
return &compileError{
source: ctx.source,
span: parser.Span{
Start: x.Lparen.End,
End: x.Rparen.Start,
},
err: fmt.Errorf("now()) takes a no arguments (got %d)", len(x.Args)),
}
}
sb.WriteString("CURRENT_TIMESTAMP")
return nil
}

func writeIsNullFunction(ctx *exprContext, sb *strings.Builder, x *parser.CallExpr) error {
if len(x.Args) != 1 {
return &compileError{
Expand Down Expand Up @@ -862,6 +880,44 @@ func writeIfFunction(ctx *exprContext, sb *strings.Builder, x *parser.CallExpr)
return nil
}

func writeToLowerFunction(ctx *exprContext, sb *strings.Builder, x *parser.CallExpr) error {
if len(x.Args) != 1 {
return &compileError{
source: ctx.source,
span: parser.Span{
Start: x.Lparen.End,
End: x.Rparen.Start,
},
err: fmt.Errorf("tolower(x) takes a single argument (got %d)", len(x.Args)),
}
}
sb.WriteString("LOWER(")
if err := writeExpression(ctx, sb, x.Args[0]); err != nil {
return err
}
sb.WriteString(")")
return nil
}

func writeToUpperFunction(ctx *exprContext, sb *strings.Builder, x *parser.CallExpr) error {
if len(x.Args) != 1 {
return &compileError{
source: ctx.source,
span: parser.Span{
Start: x.Lparen.End,
End: x.Rparen.Start,
},
err: fmt.Errorf("toupper(x) takes a single argument (got %d)", len(x.Args)),
}
}
sb.WriteString("UPPER(")
if err := writeExpression(ctx, sb, x.Args[0]); err != nil {
return err
}
sb.WriteString(")")
return nil
}

func quoteSQLString(sb *strings.Builder, s string) {
sb.WriteString("'")
for _, b := range []byte(s) {
Expand Down
2 changes: 2 additions & 0 deletions testdata/Goldens/ProjectNow/input.pql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
StormEvents
| project now = now(), State
1 change: 1 addition & 0 deletions testdata/Goldens/ProjectNow/output.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT CURRENT_TIMESTAMP AS "now", "State" AS "State" FROM "StormEvents";
2 changes: 2 additions & 0 deletions testdata/Goldens/WhereToLower/input.pql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
StormEvents
| where tolower(EventType) == "tornado"
2 changes: 2 additions & 0 deletions testdata/Goldens/WhereToLower/output.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EventId,State,EventType,DamageProperty
60913,FLORIDA,Tornado,6200000
1 change: 1 addition & 0 deletions testdata/Goldens/WhereToLower/output.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * FROM "StormEvents" WHERE coalesce((LOWER("EventType")) = 'tornado', FALSE);
2 changes: 2 additions & 0 deletions testdata/Goldens/WhereToUpper/input.pql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
StormEvents
| where toupper(EventType) == "TORNADO"
2 changes: 2 additions & 0 deletions testdata/Goldens/WhereToUpper/output.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EventId,State,EventType,DamageProperty
60913,FLORIDA,Tornado,6200000
1 change: 1 addition & 0 deletions testdata/Goldens/WhereToUpper/output.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * FROM "StormEvents" WHERE coalesce((UPPER("EventType")) = 'TORNADO', FALSE);

0 comments on commit 2f99ca8

Please sign in to comment.