gpdb
gpdb copied to clipboard
[6X] Support Query Parameters in Orca
(backported from https://github.com/greenplum-db/gpdb/commit/e747b2e1c2a67fd84a8213ccd5c261869c77d772)
Differences between this and 7X:
- Merge conflicts due to clang-format/nullptr
- Disabling this feature by default, use
optimizer_enable_query_parameterto enable - Addition in plancache.c to not even try to generate generic plans in Orca unless guc is enabled
- Modified CTranslatorDXLToPlStmt.cpp to not attempt static partition elimination if filter expr is a parameter. This might be possible to support, but it'd be very different from 7X, and we should get it working on 7X first.
This commit adds support for Query Parameters and parameterized queries to Orca. These come in 2 forms:
- As functions, eg:
CREATE FUNCTION somefunc(INT, INT) RETURNS INT
AS $$ SELECT $1+$2 $$ LANGUAGE SQL STABLE; SELECT * FROM somefunc(3,8);
2.And as parameterized queries:
PREPARE qry as SELECT * from foo
where a=$1; EXECUTE qry(2);
To accomplish this, Orca now parses and passes through a scalar param as a scalar operator, and then translate this as a Param that GPDB can understand. This Param is a scalar op just like a CScalarConst, a ScalarIdent, or any other scalar operator, and fits very nicely into the Orca framework. The logic works whether the param is in a qual, targetlist, limit, subquery, etc., and is why there aren't many major logic changes here--it's mostly just translation.
Some notes:
-
Static partition elimination currently is NOT done with parameters in Orca. We will likely do this in 7X in the future, but not in 6X.
-
When using parameterized queries (eg: PREPARE..EXECUTE), Orca will almost always choose a custom plan by default. If plan_cache_mode is set to force_generic_plan, then it will choose the generic (parameterized) plan. This is because the cardinality estimates in Orca are using a more conservative estimate (40%) of the base table. Additionally, Orca's cost model is not accounting for the planning cost--so the cost of the generic plan will typically be more than the custom plan and the optimizer will choose to use the custom plan.
-
Cardinality estimates with query parameters must make assumptions since we don't know what we're actually comparing against. For example in
select * from foo where a=$1, the optimizer must generate an estimate without knowing the value of $1. In Orca, we currently use the default unsupported operator value of 40% of the underlying cardinality. We can make better estimates, for example this should simply be 1/NDV.