Skip to content

Commit

Permalink
Implement project operator
Browse files Browse the repository at this point in the history
Fixes #7
  • Loading branch information
zombiezen committed Feb 5, 2024
1 parent 0af866a commit b9a40d1
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 2 deletions.
32 changes: 30 additions & 2 deletions pql.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func splitQueries(expr *parser.TabularExpr) ([]*subquery, error) {
for i := 0; i < len(expr.Operators); i++ {
switch op := expr.Operators[i].(type) {
case *parser.SortOperator:
if lastSubquery != nil && lastSubquery.sort == nil && lastSubquery.take == nil {
if lastSubquery != nil && canAttachSort(lastSubquery.op) && lastSubquery.sort == nil && lastSubquery.take == nil {
lastSubquery.sort = op
} else {
lastSubquery = &subquery{
Expand All @@ -66,7 +66,7 @@ func splitQueries(expr *parser.TabularExpr) ([]*subquery, error) {
subqueries = append(subqueries, lastSubquery)
}
case *parser.TakeOperator:
if lastSubquery != nil && lastSubquery.take == nil {
if lastSubquery != nil && canAttachSort(lastSubquery.op) && lastSubquery.take == nil {
lastSubquery.take = op
} else {
lastSubquery = &subquery{
Expand Down Expand Up @@ -107,11 +107,39 @@ func splitQueries(expr *parser.TabularExpr) ([]*subquery, error) {
return subqueries, nil
}

// canAttachSort reports whether the given operator's subquery can have a sort clause attached.
// This becomes significant for operators like "project"
// because they change the identifiers in scope.
func canAttachSort(op parser.TabularOperator) bool {
switch op.(type) {
case *parser.ProjectOperator, *parser.SummarizeOperator:
return false
default:
return true
}
}

func (sub *subquery) write(sb *strings.Builder) {
switch op := sub.op.(type) {
case nil:
sb.WriteString("SELECT * FROM ")
sb.WriteString(sub.sourceSQL)
case *parser.ProjectOperator:
sb.WriteString("SELECT ")
for i, col := range op.Cols {
if i > 0 {
sb.WriteString(", ")
}
if col.X == nil {
writeExpression(sb, col.Name)
} else {
writeExpression(sb, col.X)
}
sb.WriteString(" AS ")
quoteIdentifier(sb, col.Name.Name)
}
sb.WriteString(" FROM ")
sb.WriteString(sub.sourceSQL)
case *parser.WhereOperator:
sb.WriteString("SELECT * FROM ")
sb.WriteString(sub.sourceSQL)
Expand Down
2 changes: 2 additions & 0 deletions testdata/Goldens/Project/input.pql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
StormEvents
| project State, EventType, DamageProperty
5 changes: 5 additions & 0 deletions testdata/Goldens/Project/output.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ATLANTIC SOUTH,Waterspout,0
FLORIDA,Heavy Rain,0
FLORIDA,Tornado,6200000
GEORGIA,Thunderstorm Wind,2000
MISSISSIPPI,Thunderstorm Wind,20000
1 change: 1 addition & 0 deletions testdata/Goldens/Project/output.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "State" AS "State", "EventType" AS "EventType", "DamageProperty" AS "DamageProperty" FROM "StormEvents";
Empty file.
4 changes: 4 additions & 0 deletions testdata/Goldens/ProjectAfterTake/input.pql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
StormEvents
| sort by EventId asc
| take 3
| project State, EventType, DamageProperty
3 changes: 3 additions & 0 deletions testdata/Goldens/ProjectAfterTake/output.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ATLANTIC SOUTH,Waterspout,0
FLORIDA,Heavy Rain,0
GEORGIA,Thunderstorm Wind,2000
2 changes: 2 additions & 0 deletions testdata/Goldens/ProjectAfterTake/output.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
WITH "subquery0" AS (SELECT * FROM "StormEvents" ORDER BY "EventId" ASC NULLS FIRST LIMIT 3)
SELECT "State" AS "State", "EventType" AS "EventType", "DamageProperty" AS "DamageProperty" FROM "subquery0";
2 changes: 2 additions & 0 deletions testdata/Goldens/ProjectAssignment/input.pql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
StormEvents
| project Id = EventId, DamagePropertyK = DamageProperty / 1000
5 changes: 5 additions & 0 deletions testdata/Goldens/ProjectAssignment/output.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
11032,0
11098,0
60913,6200
11503,2
13913,20
1 change: 1 addition & 0 deletions testdata/Goldens/ProjectAssignment/output.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT "EventId" AS "Id", ("DamageProperty") / (1000) AS "DamagePropertyK" FROM "StormEvents";
Empty file.

0 comments on commit b9a40d1

Please sign in to comment.