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

[Queries] Respect maxResults parameter when fetching query results #263

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion internal/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type (
GetQueryResultsResponse struct {
JobReference *bigqueryv2.JobReference `json:"jobReference"`
Schema *bigqueryv2.TableSchema `json:"schema"`
Rows []*TableRow `json:"rows"`
Rows []*TableRow `json:"rows,omitempty"`
TotalRows uint64 `json:"totalRows,string"`
JobComplete bool `json:"jobComplete"`
TotalBytes uint64 `json:"-"`
Expand Down
33 changes: 33 additions & 0 deletions server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@
const (
formatOptionsUseInt64TimestampParam = "formatOptions.useInt64Timestamp"
deleteContentsParam = "deleteContents"
maxResults = "maxResults"
maxResultsDefaultValue = -1
)

func isDeleteContents(r *http.Request) bool {
Expand All @@ -581,6 +583,22 @@
return b
}

func parseQueryValueAsInt64(r *http.Request, key string, defaultValue int64) int64 {
Copy link
Owner

Choose a reason for hiding this comment

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

If we don't need to parse other int64 values, you can use a dedicated MaxResults function. e.g.) parseMaxResultValue

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems likely that there may be other int64 values that we need to parse in the future, so it seems fine to leave as is

Copy link
Owner

Choose a reason for hiding this comment

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

Then I think it's ok to leave the function, just do the maxResults's validation somewhere else.

queryValues := r.URL.Query()
values, exists := queryValues[key]
if !exists {
return defaultValue
}
if len(values) != 1 {
return defaultValue
}
parsed, err := strconv.ParseInt(values[0], 10, 64)
if err != nil {
return defaultValue
}
return parsed
ohaibbq marked this conversation as resolved.
Show resolved Hide resolved
}

func (h *datasetsDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
server := serverFromContext(ctx)
Expand Down Expand Up @@ -966,6 +984,7 @@
server: server,
project: project,
job: job,
maxResults: parseQueryValueAsInt64(r, maxResults, maxResultsDefaultValue),
useInt64Timestamp: isFormatOptionsUseInt64Timestamp(r),
})
if err != nil {
Expand All @@ -980,6 +999,7 @@
project *metadata.Project
job *metadata.Job
useInt64Timestamp bool
maxResults int64
}

func (h *jobsGetQueryResultsHandler) Handle(ctx context.Context, r *jobsGetQueryResultsRequest) (*internaltypes.GetQueryResultsResponse, error) {
Expand All @@ -988,6 +1008,19 @@
return nil, err
}
rows := internaltypes.Format(response.Schema, response.Rows, r.useInt64Timestamp)

if r.maxResults == 0 {
rows = nil
}

if r.maxResults < -1 {
return nil, fmt.Errorf("invalid maxResults parameter; must be greater than or equal to [-1], got [%i]", r.maxResults)

Check failure on line 1017 in server/handler.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, 1.21.5)

fmt.Errorf format %i has unknown verb i
}

if r.maxResults != maxResultsDefaultValue {
rows = rows[:min(int64(len(rows)), r.maxResults)]
Copy link
Owner

Choose a reason for hiding this comment

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

If -1 is set as maxResults, I think panic may occur here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

-1 is the maxResultsDefaultValue. I can add a validation for < -1

}

return &internaltypes.GetQueryResultsResponse{
JobReference: &bigqueryv2.JobReference{
ProjectId: r.project.ID,
Expand Down
Loading