Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spaces in timestamp column name #1490

Merged
merged 3 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions runtime/queries/column_timeseries.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (q *ColumnTimeseries) Resolve(ctx context.Context, rt *runtime.Runtime, ins
return nil
}
var measures = normaliseMeasures(q.Measures, true)
var timestampColumn = q.TimestampColumnName
var timestampColumn = safeName(q.TimestampColumnName)
var tableName = q.TableName
var filter string
if q.Filters != nil {
Expand All @@ -98,7 +98,7 @@ func (q *ColumnTimeseries) Resolve(ctx context.Context, rt *runtime.Runtime, ins
-- transform the original data, and optionally sample it.
series AS (
SELECT
date_trunc('` + timeGranularity + `', "` + EscapeDoubleQuotes(timestampColumn) + `") as ` + tsAlias + `,` + getExpressionColumnsFromMeasures(measures) + `
date_trunc('` + timeGranularity + `', ` + timestampColumn + `) as ` + tsAlias + `,` + getExpressionColumnsFromMeasures(measures) + `
FROM "` + EscapeDoubleQuotes(tableName) + `" ` + filter + `
GROUP BY ` + tsAlias + ` ORDER BY ` + tsAlias + `
)
Expand Down
9 changes: 5 additions & 4 deletions runtime/queries/metricsview_timeseries.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ func (q *MetricsViewTimeSeries) Resolve(ctx context.Context, rt *runtime.Runtime
}

func (q *MetricsViewTimeSeries) buildMetricsTimeSeriesSQL(mv *runtimev1.MetricsView) (string, []any, error) {
timeCol := fmt.Sprintf("DATE_TRUNC('%s', %s) AS %s", q.TimeGranularity, mv.TimeDimension, mv.TimeDimension)
timestampColumnName := safeName(mv.TimeDimension)
timeCol := fmt.Sprintf("DATE_TRUNC('%s', %s) AS %s", q.TimeGranularity, timestampColumnName, timestampColumnName)
selectCols := []string{timeCol}
Comment on lines -93 to 95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if mv.TimeDimension == ""?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, timeCol and timestampColumnName sound like the same thing. In Google's Go style guide, check out the "Variable names" section here. Maybe timeExpr and timeCol?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just reading the link you posted:

Naming is more art than science.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeCol scope is extra small while timestampColumnName is used many times throughout the function (25+ lines).

for _, n := range q.MeasureNames {
found := false
Expand All @@ -111,11 +112,11 @@ func (q *MetricsViewTimeSeries) buildMetricsTimeSeriesSQL(mv *runtimev1.MetricsV
args := []any{}
if mv.TimeDimension != "" {
if q.TimeStart != nil {
whereClause += fmt.Sprintf(" AND %s >= ?", mv.TimeDimension)
whereClause += fmt.Sprintf(" AND %s >= ?", timestampColumnName)
args = append(args, q.TimeStart.AsTime())
}
if q.TimeEnd != nil {
whereClause += fmt.Sprintf(" AND %s < ?", mv.TimeDimension)
whereClause += fmt.Sprintf(" AND %s < ?", timestampColumnName)
args = append(args, q.TimeEnd.AsTime())
}
}
Expand All @@ -134,7 +135,7 @@ func (q *MetricsViewTimeSeries) buildMetricsTimeSeriesSQL(mv *runtimev1.MetricsV
strings.Join(selectCols, ", "),
mv.Model,
whereClause,
mv.TimeDimension,
timestampColumnName,
)
return sql, args, nil
}
9 changes: 5 additions & 4 deletions runtime/queries/metricsview_toplist.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (q *MetricsViewToplist) Resolve(ctx context.Context, rt *runtime.Runtime, i
}

func (q *MetricsViewToplist) buildMetricsTopListSql(mv *runtimev1.MetricsView) (string, []any, error) {
dimName := quoteName(q.DimensionName)
dimName := safeName(q.DimensionName)
selectCols := []string{dimName}
for _, n := range q.MeasureNames {
found := false
Expand All @@ -108,13 +108,14 @@ func (q *MetricsViewToplist) buildMetricsTopListSql(mv *runtimev1.MetricsView) (

args := []any{}
whereClause := "1=1"
timestampColumnName := safeName(mv.TimeDimension)
if mv.TimeDimension != "" {
if q.TimeStart != nil {
whereClause += fmt.Sprintf(" AND %s >= ?", mv.TimeDimension)
whereClause += fmt.Sprintf(" AND %s >= ?", timestampColumnName)
args = append(args, q.TimeStart.AsTime())
}
if q.TimeEnd != nil {
whereClause += fmt.Sprintf(" AND %s < ?", mv.TimeDimension)
whereClause += fmt.Sprintf(" AND %s < ?", timestampColumnName)
args = append(args, q.TimeEnd.AsTime())
}
}
Expand All @@ -131,7 +132,7 @@ func (q *MetricsViewToplist) buildMetricsTopListSql(mv *runtimev1.MetricsView) (
orderClause := "true"
for _, s := range q.Sort {
orderClause += ", "
orderClause += s.Name
orderClause += safeName(s.Name)
if !s.Ascending {
orderClause += " DESC"
}
Expand Down
5 changes: 3 additions & 2 deletions runtime/queries/metricsview_totals.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,14 @@ func (q *MetricsViewTotals) buildMetricsTotalsSql(mv *runtimev1.MetricsView) (st

whereClause := "1=1"
args := []any{}
timestampColumnName := safeName(mv.TimeDimension)
if mv.TimeDimension != "" {
if q.TimeStart != nil {
whereClause += fmt.Sprintf(" AND %s >= ?", mv.TimeDimension)
whereClause += fmt.Sprintf(" AND %s >= ?", timestampColumnName)
args = append(args, q.TimeStart.AsTime())
}
if q.TimeEnd != nil {
whereClause += fmt.Sprintf(" AND %s < ?", mv.TimeDimension)
whereClause += fmt.Sprintf(" AND %s < ?", timestampColumnName)
args = append(args, q.TimeEnd.AsTime())
}
}
Expand Down
38 changes: 38 additions & 0 deletions runtime/queries/sqlutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package queries

import (
"context"
"strings"

"github.com/google/uuid"
"github.com/rilldata/rill/runtime/drivers"
)

func escapeSingleQuotes(value string) string {
return strings.ReplaceAll(value, "'", "''")
}

func escapeDoubleQuotes(column string) string {
return strings.ReplaceAll(column, "\"", "\"\"")
}

func safeName(name string) string {
if name == "" {
return name
}
return quoteName(escapeDoubleQuotes(name))
}

func dropTempTable(olap drivers.OLAPStore, priority int, tableName string) {
rs, er := olap.Execute(context.Background(), &drivers.Statement{
Query: `DROP TABLE "` + tableName + `"`,
Priority: priority,
})
if er == nil {
rs.Close()
}
}

func tempName(prefix string) string {
return prefix + strings.ReplaceAll(uuid.New().String(), "-", "")
}
14 changes: 14 additions & 0 deletions runtime/server/queries_metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ func TestServer_MetricsViewTotals(t *testing.T) {
require.Equal(t, 2.0, tr.Data.Fields["measure_0"].GetNumberValue())
}

func TestServer_MetricsViewTotals_timestamp_name_with_spaces(t *testing.T) {
server, instanceId := getMetricsTestServer(t, "ad_bids_2rows")

tr, err := server.MetricsViewTotals(context.Background(), &runtimev1.MetricsViewTotalsRequest{
InstanceId: instanceId,
MetricsViewName: "ad_bids_metrics_garbled",
MeasureNames: []string{"measure_0"},
TimeEnd: parseTime(t, "2022-01-02T00:00:00Z"),
})
require.NoError(t, err)
require.Equal(t, 1, len(tr.Data.Fields))
require.Equal(t, 1.0, tr.Data.Fields["measure_0"].GetNumberValue())
}

func TestServer_MetricsViewTotals_EmptyModel(t *testing.T) {
server, instanceId := getMetricsTestServer(t, "ad_bids_2rows")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
model: ad_bids_garbled
display_name: Ad bids
description:

timeseries: timestamp name with spaces
default_timegrain: ""
timegrains:
- 1 day
- 1 month

dimensions:
- label: Publisher
property: publisher
description: ""
- label: Domain
property: domain
description: ""
- label: Id
property: id

measures:
- label: "Number of bids"
expression: count(*)
description: ""
format_preset: ""
- label: "Total volume"
expression: sum(volume)
description: ""
format_preset: ""
- label: "Total impressions"
expression: sum(impressions)
- label: "Total clicks"
expression: sum(clicks)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SELECT
(id::HUGEINT + 170141183460469231731687303715884105726)::HUGEINT as id,
timestamp as "timestamp name with spaces",
publisher,
domain,
bid_price,
volume,
impressions,
"ad words",
clicks
FROM ad_bids_source