-
Notifications
You must be signed in to change notification settings - Fork 3
[DNM] An experimental branch to try to push down aggregate functions #22
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
base: REL_11_CARTO
Are you sure you want to change the base?
Conversation
What this does: - it adds a ton of traces, that are more suitable to follow certain aspects of the code that raw gdb on the foreign_expr_walker recursive exploration of the parse tree. - it modifies the code related to checking of collations. I don't really understand if it is a bug or if there's actually a conflict with collations and it is unsafe to push, but I tend to think it is indeed a bug as no collation should affect it. - it allows for Row Expressions node push downs (T_RowExpr) in a very hacky way. Chances are that to do it properly it needs to continue with a recursive exploration of the tree from that node. This was preventing the whole aggregate function ST_AsMVt to be pushed down to the foreign server. - it provides a crappy implementation of deparseRowExpr. It makes the planner happy to ship some SQL but it is not really valid and fails with an error on the remote end. It shall not confuse the representation in the EXPLAIN of ROW() with the SQL ROW() row constructor. In short this just half-works, and we really need both halfs for it to do something interesting. Nevertheless I think it is good to share, to give an idea of the type of work to accomplish to finish this and similar cases.
Here an example without the patch: explain (verbose) SELECT ((SELECT ST_AsMVT(geometries, 'layer0', 2048, 'the_geom_webmercator')
FROM (
SELECT ST_AsMVTGeom(
the_geom_webmercator,
ST_MakeEnvelope(-13638811.830980570083, 4539747.98391318832, -13629027.891360067522, 4549531.923533690881, 3857),
2048,
8,
true
) as the_geom_webmercator, "st_type", "cartodb_id"
FROM (
SELECT
"st_type","cartodb_id","the_geom_webmercator"
FROM
(SELECT "st_type","cartodb_id","the_geom_webmercator" FROM cdb_fdw_example.sf_stclines ) _cdb_epoch_transformation ) AS cdbq
WHERE the_geom_webmercator && ST_Expand(ST_MakeEnvelope(-13638811.830980570083, 4539747.98391318832, -13629027.891360067522, 4549531.923533690881, 3857), 38.21851414258813)
) AS geometries
)) AS st_asmvt; and the resulting query plan:
so the The same query with the patch:
so, the whole thing is sent to the foreign end, which is what I originally intended. However, the row expression is not "deparsed" correctly, producing an error:
indeed the query shipped to the foreign end is not correct because of the way the
|
contrib/postgres_fdw/deparse.c
Outdated
bool first; | ||
ListCell *lc; | ||
|
||
appendStringInfoString(buf, "("); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
originally it read like appendStringInfoString(buf, "ROW(");
. I read somewhere that ROW
is "syntax noise" when there are more than one columns in the row and forgot to get it back to its original, generic form.
The structure of a |
The transformation from what it gets and what it should be, done manually should be something like this: --ROW(public.st_asmvtgeom(the_geom_webmercator, 'BOX(-9862211.13746658 5165920.11962535,-9705668.10353854 5322463.15355339)'::public.box2d, 2048, 8, true), pct_higher_edu, cartodb_id)
SELECT public.st_asmvt(some_arbitrary_alias, 'layer0'::text, 2048, 'the_geom_webmercator'::text)
FROM (
SELECT public.st_asmvtgeom(the_geom_webmercator, 'BOX(-9862211.13746658 5165920.11962535,-9705668.10353854 5322463.15355339)'::public.box2d, 2048, 8, true) the_geom_webmercator, pct_higher_edu, cartodb_id
FROM carto_lite.higher_edu_by_county WHERE ((the_geom_webmercator OPERATOR(public.&&) '0103000020110F00000100000005000000413647D4D4CF62C137C5E5273FB45341413647D4D4CF62C17DFD95A9504E54411F1A6F13CC8262C17DFD95A9504E54411F1A6F13CC8262C137C5E5273FB45341413647D4D4CF62C137C5E5273FB45341'::public.geometry))
) some_arbitrary_alias; I think it is doable, but not trivial at all. |
A small trick I learned today from https://wiki.postgresql.org/wiki/Developer_FAQ#Why_do_we_use_Node_and_List_to_make_data_structures.3F
|
What this does:
it adds a ton of traces, that are more suitable to follow certain
aspects of the code that raw gdb on the foreign_expr_walker
recursive exploration of the parse tree.
it modifies the code related to checking of collations. I don't
really understand if it is a bug or if there's actually a conflict
with collations and it is unsafe to push, but I tend to think it is
indeed a bug as no collation should affect it.
it allows for Row Expressions node push downs (T_RowExpr) in a very
hacky way. Chances are that to do it properly it needs to continue
with a recursive exploration of the tree from that node. This was
preventing the whole aggregate function ST_AsMVt to be pushed down
to the foreign server.
it provides a crappy implementation of deparseRowExpr. It makes the
planner happy to ship some SQL but it is not really valid and fails
with an error on the remote end. It shall not confuse the
representation in the EXPLAIN of ROW() with the SQL ROW() row
constructor.
In short this just half-works, and we really need both halfs for it to
do something interesting. Nevertheless I think it is good to share, to
give an idea of the type of work to accomplish to finish this and
similar cases.