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

Add GetOrderBy and RemoveOrderBy to get and remove the OrderByParts from the query #369

Open
Cofgren opened this issue Nov 5, 2023 · 1 comment

Comments

@Cofgren
Copy link

Cofgren commented Nov 5, 2023

It is useful to be able to reset the order-by in some situations, or retrieve the order by. Our case is simple enough, we have a generic function that executes the query and returns a slice of objects, the total number of rows and an error object:

func QueryRowsPaginatedSq[T any](db Dbi, limit, offset uint64, builder squirrel.SelectBuilder) ([]T, int64, error)

It performs a count on the rows returned by the query, before applying the limit and offset. It does this by way of a cte wrapper over the original query: with count_cte as ( ... original query with order-by ) select count(*) from count_cte;

It then applies the limit and offset, and executes the query again, this time paginated.

Saving the order-by parts, then removing the order-by will allow the count(*) to execute faster, since its not concerned with ordering rows. Then on the second execution, I can apply the order-by, limit and offset. It's unfortunate that Postgresql does not perform this optimisation itself.

Why not use a windowing such as count(*) over() as total_rows? Because this performs worse in most situations (which could be related to the order-by again). Further, as I am using a Go generic function, I cannot create a new struct to scan into, that embeds to type T and TotalRows, as this is forbidden in Go, so we do the count and query as two steps.

This request is a very simple change.

@alanwgt
Copy link

alanwgt commented Jan 16, 2025

I came across this older issue and faced a similar challenge. If I understood correctly, the OP wanted to reset the ORDER BY clause in their query builder. For future reference, here's a potential approach to achieve that:

If this is indeed op's case, to reset the order by, you can do the following:

s := builder.Delete(sq.SelectBuilder{}, "OrderByParts").(sq.SelectBuilder)

This solution is inspired by the Delete method from the ithub.com/lann/builder package, which is a dependency of Squirrel.

By removing the OrderByParts, you effectively reset the ORDER BY clause, allowing for more optimized COUNT(*) operations as the OP intended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants