You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudberry.apache.org by re...@apache.org on 2025/02/20 08:48:19 UTC
(cloudberry) branch main updated (6c03bf0c54 -> 17e6c8b122)
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
from 6c03bf0c54 Fix pg_hint_plan test cases
new a83c0f841b CreateStmt: Introduce notion of origin
new 0716b61413 Rename the resource group parameter 'memory_limit' to 'memory_quota' (#17378)
new 0bb637ef48 Add update path for gp_toolkit to version "1.6"
new c69821feef Fix result is wrong when outer query has order by after LATERAL subquery (#17228)
new d42418a345 Run REFRESH MATERIALIZED VIEW CONCURRENTLY in right security context
new 17e6c8b122 Fix performance regression caused by upstream materialized view changes
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
doc/src/sgml/ref/alter_resource_group.sgml | 1 +
doc/src/sgml/ref/create_resource_group.sgml | 1 +
gpcontrib/gp_toolkit/Makefile | 2 +-
gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql | 2 +-
gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql | 6 ++
gpcontrib/gp_toolkit/gp_toolkit.control | 2 +-
src/backend/cdb/cdbllize.c | 16 +++-
src/backend/commands/createas.c | 2 +-
src/backend/commands/exttablecmds.c | 2 +-
src/backend/commands/matview.c | 71 +++++++++++++----
src/backend/commands/resgroupcmds.c | 42 +++++-----
src/backend/commands/sequence.c | 2 +-
src/backend/commands/tablecmds.c | 11 +--
src/backend/commands/tablecmds_gp.c | 6 +-
src/backend/commands/typecmds.c | 2 +-
src/backend/commands/view.c | 2 +-
src/backend/nodes/copyfuncs.c | 2 +-
src/backend/nodes/equalfuncs.c | 2 +-
src/backend/nodes/outfuncs.c | 2 +-
src/backend/nodes/readfast.c | 2 +-
src/backend/optimizer/plan/createplan.c | 20 ++---
src/backend/parser/gram.y | 26 +++---
src/backend/parser/parse_partition_gp.c | 48 ++++++-----
src/backend/tcop/utility.c | 5 +-
src/backend/utils/resgroup/resgroup.c | 6 +-
src/bin/psql/tab-complete.c | 2 +-
src/include/catalog/pg_resgroup.h | 2 +-
src/include/nodes/parsenodes.h | 19 ++++-
src/include/optimizer/planmain.h | 3 +
src/include/parser/kwlist.h | 2 +-
src/include/parser/parse_utilcmd.h | 8 +-
src/include/utils/resgroup.h | 2 +-
.../expected/resgroup_current_1_queue.out | 6 +-
.../expected/resgroup_current_3_group.out | 2 +-
.../expected/resgroup_current_3_queue.out | 2 +-
.../expected/resgroup_other_2_group.out | 2 +-
.../expected/resgroup_other_2_queue.out | 2 +-
.../binary_swap/sql/resgroup_current_1_group.sql | 2 +-
.../binary_swap/sql/resgroup_current_1_queue.sql | 6 +-
.../binary_swap/sql/resgroup_current_3_group.sql | 2 +-
.../binary_swap/sql/resgroup_current_3_queue.sql | 2 +-
.../binary_swap/sql/resgroup_other_2_group.sql | 2 +-
.../binary_swap/sql/resgroup_other_2_queue.sql | 2 +-
.../resgroup/resgroup_auxiliary_tools_v1.out | 2 +-
.../resgroup/resgroup_auxiliary_tools_v2.out | 2 +-
.../expected/resgroup/resgroup_memory_limit.out | 14 ++--
.../resgroup/resgroup_memory_limit_resgroup_v2.out | 4 +-
.../expected/resgroup/resgroup_syntax.out | 2 +-
.../expected/resgroup/resgroup_views.out | 2 +-
.../sql/resgroup/resgroup_memory_limit.sql | 13 +--
.../resgroup/resgroup_memory_limit_resgroup_v2.sql | 4 +-
src/test/regress/expected/subselect_gp.out | 92 ++++++++++++++++++++++
.../regress/expected/subselect_gp_optimizer.out | 92 ++++++++++++++++++++++
src/test/regress/sql/subselect_gp.sql | 22 +++++-
54 files changed, 451 insertions(+), 149 deletions(-)
create mode 100644 gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org
(cloudberry) 03/06: Add update path for gp_toolkit to version "1.6"
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 0bb637ef488a1f342f03a14c39d4658ece72479c
Author: Adam Lee <ad...@gmail.com>
AuthorDate: Thu May 16 14:27:18 2024 +0800
Add update path for gp_toolkit to version "1.6"
And use it to rename the column of view gp_toolkit.gp_resgroup_config.
```
gpadmin=# select * from gp_toolkit.gp_resgroup_config;
groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_limit | min_cost | io_limit
---------+---------------+-------------+-----------------+------------+--------+--------------+----------+----------
6437 | default_group | 20 | 20 | 100 | -1 | -1 | 500 | -1
6438 | admin_group | 10 | 10 | 100 | -1 | -1 | 500 | -1
6441 | system_group | 0 | 10 | 100 | -1 | -1 | 500 | -1
(3 rows)
gpadmin=# ALTER EXTENSION gp_toolkit UPDATE TO '1.6';
ALTER EXTENSION
gpadmin=# select * from gp_toolkit.gp_resgroup_config;
groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_quota | min_cost | io_limit
---------+---------------+-------------+-----------------+------------+--------+--------------+----------+----------
6437 | default_group | 20 | 20 | 100 | -1 | -1 | 500 | -1
6438 | admin_group | 10 | 10 | 100 | -1 | -1 | 500 | -1
6441 | system_group | 0 | 10 | 100 | -1 | -1 | 500 | -1
(3 rows)
```
Reference:
commit 931a31414d7ea60f6a0559741fb40a60d04c944e
Author: Zhenglong Li <lz...@vmware.com>
Date: Wed May 8 14:24:48 2024 +0800
Rename the resource group parameter 'memory_limit' to 'memory_quota' (#17378)
---
gpcontrib/gp_toolkit/Makefile | 2 +-
gpcontrib/gp_toolkit/gp_toolkit--1.3.sql | 2 +-
gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql | 2 +-
gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql | 6 ++++++
gpcontrib/gp_toolkit/gp_toolkit.control | 2 +-
5 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/gpcontrib/gp_toolkit/Makefile b/gpcontrib/gp_toolkit/Makefile
index baa96cf1ea..82fc7f7dee 100644
--- a/gpcontrib/gp_toolkit/Makefile
+++ b/gpcontrib/gp_toolkit/Makefile
@@ -1,7 +1,7 @@
EXTENSION = gp_toolkit
DATA = gp_toolkit--1.1--1.2.sql gp_toolkit--1.0--1.1.sql gp_toolkit--1.0.sql \
gp_toolkit--1.2--1.3.sql gp_toolkit--1.3.sql gp_toolkit--1.3--1.4.sql \
- gp_toolkit--1.4--1.5.sql
+ gp_toolkit--1.4--1.5.sql gp_toolkit--1.5--1.6.sql
MODULE_big = gp_toolkit
ifeq ($(shell uname -s), Linux)
OBJS = resgroup.o gp_partition_maint.o
diff --git a/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql b/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql
index b0b180e184..415d6df2d9 100644
--- a/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql
+++ b/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql
@@ -1729,7 +1729,7 @@ CREATE VIEW gp_toolkit.gp_resgroup_config AS
, T2.value AS cpu_max_percent
, T3.value AS cpu_weight
, T4.value AS cpuset
- , T5.value AS memory_quota
+ , T5.value AS memory_limit
, T6.value AS min_cost
, T7.value AS io_limit
FROM pg_resgroup G
diff --git a/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql b/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql
index d7d5c7256c..55f39deda1 100644
--- a/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql
+++ b/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql
@@ -1,7 +1,7 @@
/* gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql */
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
-\echo Use "ALTER EXTENSION gp_toolkit UPDATE TO '1.5" to load this file. \quit
+\echo Use "ALTER EXTENSION gp_toolkit UPDATE TO '1.5'" to load this file. \quit
-- Function to check orphaned files.
-- Compared to the previous version, adjust the SELECT ... FROM __check_orphaned_files since we added new column to it.
diff --git a/gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql b/gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql
new file mode 100644
index 0000000000..e42f3c124e
--- /dev/null
+++ b/gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql
@@ -0,0 +1,6 @@
+/* gpcontrib/gp_toolkit/gp_toolkit--1.5--1.6.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION gp_toolkit UPDATE TO '1.6'" to load this file. \quit
+
+ALTER TABLE gp_toolkit.gp_resgroup_config RENAME COLUMN memory_limit TO memory_quota;
diff --git a/gpcontrib/gp_toolkit/gp_toolkit.control b/gpcontrib/gp_toolkit/gp_toolkit.control
index 8cd45c172d..0d9b47e7e6 100644
--- a/gpcontrib/gp_toolkit/gp_toolkit.control
+++ b/gpcontrib/gp_toolkit/gp_toolkit.control
@@ -1,5 +1,5 @@
# gp_toolkit extension
comment = 'various GPDB administrative views/functions'
-default_version = '1.5'
+default_version = '1.6'
schema = gp_toolkit
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org
(cloudberry) 05/06: Run REFRESH MATERIALIZED VIEW CONCURRENTLY in right security context
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit d42418a3457e7e968d4358faa5949536cc3c2410
Author: Heikki Linnakangas <he...@iki.fi>
AuthorDate: Mon Feb 5 11:01:23 2024 +0200
Run REFRESH MATERIALIZED VIEW CONCURRENTLY in right security context
The internal commands in REFRESH MATERIALIZED VIEW CONCURRENTLY are
correctly executed in SECURITY_RESTRICTED_OPERATION mode, except for
creating the temporary "diff" table, because you cannot create
temporary tables in SRO mode. But creating the temporary "diff" table
is a pretty complex CTAS command that selects from another temporary
table created earlier in the command. If you can cajole that CTAS
command to execute code defined by the table owner, the table owner
can run code with the privileges of the user running the REFRESH
command.
The proof-of-concept reported to the security team relied on CREATE
RULE to convert the internally-built temp table to a view. That's not
possible since commit b23cd185fd, and I was not able to find a
different way to turn the SELECT on the temp table into code
execution, so as far as I know this is only exploitable in v15 and
below. That's a fiddly assumption though, so apply this patch to
master and all stable versions.
Thanks to Pedro Gallegos for the report.
Security: CVE-2024-0985 (not CVE-2023-5869 as claimed in original commit msg)
Reviewed-by: Noah Misch
(cherry picked from commit 2699fc035a75d0774c1f013e9320882287f78adb)
---
src/backend/commands/matview.c | 38 +++++++++++++++++++++++++++++---------
1 file changed, 29 insertions(+), 9 deletions(-)
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 0d3e9f407d..7a4d0a77c8 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -1189,17 +1189,40 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1))));
}
+ /*
+ * Create the temporary "diff" table.
+ *
+ * Temporarily switch out of the SECURITY_RESTRICTED_OPERATION context,
+ * because you cannot create temp tables in SRO context. For extra
+ * paranoia, add the composite type column only after switching back to
+ * SRO context.
+ */
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
- /* Start building the query for creating the diff table. */
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
- "CREATE TEMP TABLE %s AS "
- "SELECT mv.ctid AS tid, mv.gp_segment_id as sid, newdata.*::%s AS newdata "
+ "CREATE TEMP TABLE %s (tid pg_catalog.tid)",
+ diffname);
+ if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+ elog(ERROR, "SPI_exec failed: %s", querybuf.data);
+ SetUserIdAndSecContext(relowner,
+ save_sec_context | SECURITY_RESTRICTED_OPERATION);
+ resetStringInfo(&querybuf);
+ appendStringInfo(&querybuf,
+ "ALTER TABLE %s ADD COLUMN newdata %s",
+ diffname, tempname);
+ if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+ elog(ERROR, "SPI_exec failed: %s", querybuf.data);
+
+ /* Start building the query for populating the diff table. */
+ resetStringInfo(&querybuf);
+ appendStringInfo(&querybuf,
+ "INSERT INTO %s "
+ "SELECT mv.ctid AS tid, mv.gp_segment_id as sid, newdata.* "
"FROM %s mv FULL JOIN %s newdata ON (",
- diffname, tempname, matviewname, tempname);
+ diffname, matviewname, tempname);
/*
* Get the list of index OIDs for the table from the relcache, and look up
@@ -1327,13 +1350,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
"WHERE newdata.* IS NULL OR mv.* IS NULL "
"ORDER BY tid");
- /* Create the temporary "diff" table. */
- if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+ /* Populate the temporary "diff" table. */
+ if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
- SetUserIdAndSecContext(relowner,
- save_sec_context | SECURITY_RESTRICTED_OPERATION);
-
/*
* We have no further use for data from the "full-data" temp table, but we
* must keep it around because its type is referenced from the diff table.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org
(cloudberry) 06/06: Fix performance regression caused by upstream materialized view changes
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 17e6c8b122c0e694f2946c704b9c58806cc852c0
Author: Adam Lee <ad...@gmail.com>
AuthorDate: Tue Feb 20 11:13:12 2024 +0800
Fix performance regression caused by upstream materialized view changes
Upstream's security changes break Greenplum's materialized view
performance improvement, which doesn't store diffs in a composite type
column but creates a similar table with the same distribution to avoid
unnecessary motions.
This commit creates the temp table just like the matview then add
special columns at the end to fix it.
---
src/backend/commands/matview.c | 45 +++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 7a4d0a77c8..9e540ac8cc 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -1123,6 +1123,7 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
char *tempname;
char *diffname;
TupleDesc tupdesc;
+ TupleDesc newHeapDesc;
bool foundUniqueIndex;
List *indexoidlist;
ListCell *indexoidscan;
@@ -1167,8 +1168,8 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
"(SELECT 1 FROM %s newdata2 WHERE newdata2.* IS NOT NULL "
"AND newdata2.* OPERATOR(pg_catalog.*=) newdata.* "
"AND newdata2.ctid OPERATOR(pg_catalog.<>) "
- "newdata.ctid and newdata2.gp_segment_id = "
- "newdata.gp_segment_id)",
+ "newdata.ctid AND newdata2.gp_segment_id "
+ "OPERATOR(pg_catalog.=) newdata.gp_segment_id)",
tempname, tempname, tempname);
if (SPI_execute(querybuf.data, false, 1) != SPI_OK_SELECT)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
@@ -1196,23 +1197,33 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
* because you cannot create temp tables in SRO context. For extra
* paranoia, add the composite type column only after switching back to
* SRO context.
+ *
+ * Greenplum doesn't store diffs in a composite type column, instead it
+ * creates a similar table with the same distribution for performance
+ * considerations.
*/
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
-
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
- "CREATE TEMP TABLE %s (tid pg_catalog.tid)",
- diffname);
+ "CREATE TEMP TABLE %s (LIKE %s)",
+ diffname, tempname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
- "ALTER TABLE %s ADD COLUMN newdata %s",
- diffname, tempname);
+ "ALTER TABLE %s ADD COLUMN tid pg_catalog.tid",
+ diffname);
+ if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+ elog(ERROR, "SPI_exec failed: %s", querybuf.data);
+
+ resetStringInfo(&querybuf);
+ appendStringInfo(&querybuf,
+ "ALTER TABLE %s ADD COLUMN sid pg_catalog.int4",
+ diffname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
@@ -1220,7 +1231,7 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
resetStringInfo(&querybuf);
appendStringInfo(&querybuf,
"INSERT INTO %s "
- "SELECT mv.ctid AS tid, mv.gp_segment_id as sid, newdata.* "
+ "SELECT newdata.*, mv.ctid AS tid, mv.gp_segment_id as sid "
"FROM %s mv FULL JOIN %s newdata ON (",
diffname, matviewname, tempname);
@@ -1231,6 +1242,7 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
* include all rows.
*/
tupdesc = matviewRel->rd_att;
+ newHeapDesc = tempRel->rd_att;
opUsedForQual = (Oid *) palloc0(sizeof(Oid) * relnatts);
foundUniqueIndex = false;
@@ -1372,18 +1384,27 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
appendStringInfo(&querybuf,
"DELETE FROM %s mv WHERE ctid OPERATOR(pg_catalog.=) ANY "
"(SELECT diff.tid FROM %s diff "
- "WHERE diff.tid = mv.ctid and diff.sid = mv.gp_segment_id and"
- " diff.tid IS NOT NULL)",
+ "WHERE diff.tid IS NOT NULL "
+ "AND diff.tid OPERATOR(pg_catalog.=) mv.ctid AND diff.sid "
+ "OPERATOR(pg_catalog.=) mv.gp_segment_id)",
matviewname, diffname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_DELETE)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
/* Inserts go last. */
resetStringInfo(&querybuf);
+ appendStringInfo(&querybuf, "INSERT INTO %s SELECT", matviewname);
+ for (int i = 0; i < newHeapDesc->natts; ++i)
+ {
+ Form_pg_attribute attr = TupleDescAttr(newHeapDesc, i);
+ if (i == newHeapDesc->natts - 1)
+ appendStringInfo(&querybuf, " %s", NameStr(attr->attname));
+ else
+ appendStringInfo(&querybuf, " %s,", NameStr(attr->attname));
+ }
appendStringInfo(&querybuf,
- "INSERT INTO %s SELECT (diff.newdata).* "
" FROM %s diff WHERE tid IS NULL",
- matviewname, diffname);
+ diffname);
if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT)
elog(ERROR, "SPI_exec failed: %s", querybuf.data);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org
(cloudberry) 01/06: CreateStmt: Introduce notion of origin
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit a83c0f841bf1e7f0008c1952fc7f1b42357a6679
Author: Soumyadeep Chakraborty <so...@gmail.com>
AuthorDate: Wed Dec 13 14:36:25 2023 -0800
CreateStmt: Introduce notion of origin
This struct member describes the provenance of the CreateStmt, namely
whether it was generated or not as part of GP style classic partitioning
syntax.
Also, it fixes a slight inconsistency where in makePartitionCreateStmt,
we would always indicate that we are part of a GP style alter.
---
src/backend/commands/createas.c | 2 +-
src/backend/commands/exttablecmds.c | 2 +-
src/backend/commands/sequence.c | 2 +-
src/backend/commands/tablecmds.c | 11 ++++----
src/backend/commands/tablecmds_gp.c | 6 ++---
src/backend/commands/typecmds.c | 2 +-
src/backend/commands/view.c | 2 +-
src/backend/nodes/copyfuncs.c | 2 +-
src/backend/nodes/equalfuncs.c | 2 +-
src/backend/nodes/outfuncs.c | 2 +-
src/backend/nodes/readfast.c | 2 +-
src/backend/parser/gram.y | 12 ++++-----
src/backend/parser/parse_partition_gp.c | 48 ++++++++++++++++++++-------------
src/backend/tcop/utility.c | 5 ++--
src/include/nodes/parsenodes.h | 19 ++++++++++++-
src/include/parser/parse_utilcmd.h | 8 ++++--
16 files changed, 80 insertions(+), 47 deletions(-)
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 72cc4ffc03..f3694a2534 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -167,7 +167,7 @@ create_ctas_internal(List *attrList, IntoClause *into, QueryDesc *queryDesc, boo
create->oncommit = into->onCommit;
create->tablespacename = into->tableSpaceName;
create->if_not_exists = false;
- create->gp_style_alter_part = false;
+ create->origin = ORIGIN_NO_GEN;
create->distributedBy = NULL; /* We will pass a pre-made intoPolicy instead */
create->partitionBy = NULL; /* CTAS does not not support partition. */
diff --git a/src/backend/commands/exttablecmds.c b/src/backend/commands/exttablecmds.c
index c48abe700d..fed0598cd4 100644
--- a/src/backend/commands/exttablecmds.c
+++ b/src/backend/commands/exttablecmds.c
@@ -120,7 +120,7 @@ DefineExternalRelation(CreateExternalStmt *createExtStmt)
createStmt->distributedBy = createExtStmt->distributedBy; /* policy was set in transform */
createStmt->ownerid = userid;
createStmt->tags = createExtStmt->tags;
- createStmt->gp_style_alter_part = false;
+ createStmt->origin = ORIGIN_NO_GEN;
switch (exttypeDesc->exttabletype)
{
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index b5aad4b328..344b0d0926 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -260,7 +260,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
stmt->if_not_exists = seq->if_not_exists;
stmt->relKind = RELKIND_SEQUENCE;
stmt->ownerid = GetUserId();
- stmt->gp_style_alter_part = false;
+ stmt->origin = ORIGIN_NO_GEN;
address = DefineRelation(stmt, RELKIND_SEQUENCE, seq->ownerId, NULL, NULL,
false, /* dispatch */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 08ead599fb..c715525316 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -299,7 +299,8 @@ static void truncate_check_activity(Relation rel);
static void RangeVarCallbackForTruncate(const RangeVar *relation,
Oid relId, Oid oldRelId, void *arg);
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
- bool is_partition, List **supconstr, bool gp_alter_part);
+ bool is_partition, List **supconstr,
+ CreateStmtOrigin origin);
static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
@@ -1006,7 +1007,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
stmt->relation->relpersistence,
stmt->partbound != NULL,
&old_constraints,
- stmt->gp_style_alter_part);
+ stmt->origin);
}
else
{
@@ -2963,7 +2964,7 @@ storage_name(char c)
*/
List *
MergeAttributes(List *schema, List *supers, char relpersistence,
- bool is_partition, List **supconstr, bool gp_style_alter_part)
+ bool is_partition, List **supconstr, CreateStmtOrigin origin)
{
List *inhSchema = NIL;
List *constraints = NIL;
@@ -3095,7 +3096,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
* already held by alter command, and when we generate CREATE
* STMT and execute them we have 2 reference instead on 1 here.
*/
- if (is_partition && ((Gp_role != GP_ROLE_DISPATCH && !IS_SINGLENODE()) || !gp_style_alter_part))
+ if (is_partition && ((Gp_role != GP_ROLE_DISPATCH && !IS_SINGLENODE()) || origin != ORIGIN_GP_CLASSIC_ALTER_GEN))
CheckTableNotInUse(relation, "CREATE TABLE .. PARTITION OF");
/*
@@ -18165,7 +18166,7 @@ prebuild_temp_table(Relation rel, RangeVar *tmpname, DistributedBy *distro,
cs->ownerid = rel->rd_rel->relowner;
cs->tablespacename = get_tablespace_name(rel->rd_rel->reltablespace);
cs->buildAoBlkdir = false;
- cs->gp_style_alter_part = false;
+ cs->origin = ORIGIN_NO_GEN;
if (isTmpTableAo &&
rel->rd_rel->relhasindex)
diff --git a/src/backend/commands/tablecmds_gp.c b/src/backend/commands/tablecmds_gp.c
index dcd221d694..5fa2e647fa 100644
--- a/src/backend/commands/tablecmds_gp.c
+++ b/src/backend/commands/tablecmds_gp.c
@@ -997,7 +997,7 @@ AtExecGPSplitPartition(Relation rel, AlterTableCmd *cmd)
elem->options = p_reloptions;
/* create first partition stmt */
- stmts = lappend(stmts, makePartitionCreateStmt(rel, partname1, boundspec1, NULL, elem, &partcomp));
+ stmts = lappend(stmts, makePartitionCreateStmt(rel, partname1, boundspec1, NULL, elem, &partcomp, ORIGIN_GP_CLASSIC_ALTER_GEN));
/* create second partition stmt */
if (defaultpartname)
@@ -1005,7 +1005,7 @@ AtExecGPSplitPartition(Relation rel, AlterTableCmd *cmd)
partcomp.tablename = defaultpartname;
partname2 = NULL;
}
- stmts = lappend(stmts, makePartitionCreateStmt(rel, partname2, boundspec2, NULL, elem, &partcomp));
+ stmts = lappend(stmts, makePartitionCreateStmt(rel, partname2, boundspec2, NULL, elem, &partcomp, ORIGIN_GP_CLASSIC_ALTER_GEN));
}
foreach (l, stmts)
@@ -1243,7 +1243,7 @@ ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd)
List *cstmts = generatePartitions(RelationGetRelid(rel),
gpPartDef, subpart, cmd->queryString,
- NIL, NULL, NULL, false);
+ NIL, NULL, NULL, ORIGIN_GP_CLASSIC_ALTER_GEN);
foreach(l, cstmts)
{
Node *stmt = (Node *) lfirst(l);
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index bd38417020..b96e620306 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -2640,7 +2640,7 @@ DefineCompositeType(RangeVar *typevar, List *coldeflist)
createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;
createStmt->if_not_exists = false;
- createStmt->gp_style_alter_part = false;
+ createStmt->origin = ORIGIN_NO_GEN;
/*
* Check for collision with an existing type name. If there is one and
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 49232040b7..500fd690b9 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -255,7 +255,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
createStmt->tablespacename = NULL;
createStmt->relKind = RELKIND_VIEW;
createStmt->if_not_exists = false;
- createStmt->gp_style_alter_part = false;
+ createStmt->origin = ORIGIN_NO_GEN;
/*
* Create the relation (this will error out if there's an existing
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index ced821c52a..af42529e58 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -4224,7 +4224,7 @@ CopyCreateStmtFields(const CreateStmt *from, CreateStmt *newnode)
COPY_STRING_FIELD(tablespacename);
COPY_STRING_FIELD(accessMethod);
COPY_SCALAR_FIELD(if_not_exists);
- COPY_SCALAR_FIELD(gp_style_alter_part);
+ COPY_SCALAR_FIELD(origin);
COPY_NODE_FIELD(distributedBy);
COPY_NODE_FIELD(partitionBy);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index be6433578c..344be96a0a 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1386,7 +1386,7 @@ _equalCreateStmt(const CreateStmt *a, const CreateStmt *b)
COMPARE_STRING_FIELD(tablespacename);
COMPARE_STRING_FIELD(accessMethod);
COMPARE_SCALAR_FIELD(if_not_exists);
- COMPARE_SCALAR_FIELD(gp_style_alter_part);
+ COMPARE_SCALAR_FIELD(origin);
COMPARE_NODE_FIELD(distributedBy);
COMPARE_SCALAR_FIELD(relKind);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 77017999cd..ddb7c1b9a5 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2983,7 +2983,7 @@ _outCreateStmtInfo(StringInfo str, const CreateStmt *node)
WRITE_STRING_FIELD(tablespacename);
WRITE_STRING_FIELD(accessMethod);
WRITE_BOOL_FIELD(if_not_exists);
- WRITE_BOOL_FIELD(gp_style_alter_part);
+ WRITE_ENUM_FIELD(origin, CreateStmtOrigin);
WRITE_NODE_FIELD(distributedBy);
WRITE_NODE_FIELD(partitionBy);
diff --git a/src/backend/nodes/readfast.c b/src/backend/nodes/readfast.c
index 3d080f516a..928a664739 100644
--- a/src/backend/nodes/readfast.c
+++ b/src/backend/nodes/readfast.c
@@ -752,7 +752,7 @@ _readCreateStmt_common(CreateStmt *local_node)
READ_STRING_FIELD(tablespacename);
READ_STRING_FIELD(accessMethod);
READ_BOOL_FIELD(if_not_exists);
- READ_BOOL_FIELD(gp_style_alter_part);
+ READ_ENUM_FIELD(origin, CreateStmtOrigin);
READ_NODE_FIELD(distributedBy);
READ_NODE_FIELD(partitionBy);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 4cc40a5dc7..77ef28983b 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -5104,7 +5104,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->oncommit = $12;
n->tablespacename = $13;
n->if_not_exists = false;
- n->gp_style_alter_part = false;
+ n->origin = ORIGIN_NO_GEN;
n->distributedBy = (DistributedBy *) $14;
n->tags = $16;
n->relKind = RELKIND_RELATION;
@@ -5136,7 +5136,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->oncommit = $15;
n->tablespacename = $16;
n->if_not_exists = true;
- n->gp_style_alter_part = false;
+ n->origin = ORIGIN_NO_GEN;
n->distributedBy = (DistributedBy *) $17;
n->tags = $19;
n->relKind = RELKIND_RELATION;
@@ -5169,7 +5169,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->oncommit = $11;
n->tablespacename = $12;
n->if_not_exists = false;
- n->gp_style_alter_part = false;
+ n->origin = ORIGIN_NO_GEN;
n->distributedBy = (DistributedBy *) $13;
n->tags = $15;
n->relKind = RELKIND_RELATION;
@@ -5202,7 +5202,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->oncommit = $14;
n->tablespacename = $15;
n->if_not_exists = true;
- n->gp_style_alter_part = false;
+ n->origin = ORIGIN_NO_GEN;
n->distributedBy = (DistributedBy *) $16;
n->tags = $18;
n->relKind = RELKIND_RELATION;
@@ -5235,7 +5235,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->oncommit = $13;
n->tablespacename = $14;
n->if_not_exists = false;
- n->gp_style_alter_part = false;
+ n->origin = ORIGIN_NO_GEN;
n->distributedBy = NULL;
n->tags = $16;
n->relKind = RELKIND_RELATION;
@@ -5268,7 +5268,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->oncommit = $16;
n->tablespacename = $17;
n->if_not_exists = true;
- n->gp_style_alter_part = false;
+ n->origin = ORIGIN_NO_GEN;
n->distributedBy = NULL;
n->tags = $19;
n->relKind = RELKIND_RELATION;
diff --git a/src/backend/parser/parse_partition_gp.c b/src/backend/parser/parse_partition_gp.c
index ba775093dd..d29b2bd5c8 100644
--- a/src/backend/parser/parse_partition_gp.c
+++ b/src/backend/parser/parse_partition_gp.c
@@ -66,17 +66,20 @@ static List *generateRangePartitions(ParseState *pstate,
GpPartDefElem *elem,
PartitionSpec *subPart,
partname_comp *partnamecomp,
- bool *hasImplicitRangeBounds);
+ bool *hasImplicitRangeBounds,
+ CreateStmtOrigin origin);
static List *generateListPartition(ParseState *pstate,
Relation parentrel,
GpPartDefElem *elem,
PartitionSpec *subPart,
- partname_comp *partnamecomp);
+ partname_comp *partnamecomp,
+ CreateStmtOrigin origin);
static List *generateDefaultPartition(ParseState *pstate,
Relation parentrel,
GpPartDefElem *elem,
PartitionSpec *subPart,
- partname_comp *partnamecomp);
+ partname_comp *partnamecomp,
+ CreateStmtOrigin origin);
static char *extract_tablename_from_options(List **options);
@@ -324,7 +327,7 @@ consts_to_datums(PartitionKey partkey, List *consts)
* END, deduce the value and update the corresponding list of CreateStmts.
*/
static void
-deduceImplicitRangeBounds(ParseState *pstate, Relation parentrel, List *stmts)
+deduceImplicitRangeBounds(ParseState *pstate, Relation parentrel, List *stmts, CreateStmtOrigin origin)
{
PartitionKey key = RelationGetPartitionKey(parentrel);
/* GPDB_14_MERGE_FIXEME: most places use true for new api, need to check */
@@ -337,7 +340,7 @@ deduceImplicitRangeBounds(ParseState *pstate, Relation parentrel, List *stmts)
* CREATE TABLE command to create a whole new table, or an ALTER TABLE
* ADD PARTTION to add to an existing table.
*/
- if (desc->nparts == 0)
+ if (origin != ORIGIN_GP_CLASSIC_ALTER_GEN)
{
/*
* CREATE TABLE, there are no existing partitions. We deduce the
@@ -882,10 +885,14 @@ ChoosePartitionName(const char *parentname, int level, Oid naemspaceId,
false);
}
+/*
+ * Construct a CreateStmt representing a single partition to be created as part
+ * of a legacy style CREATE/ALTER statement.
+ */
CreateStmt *
makePartitionCreateStmt(Relation parentrel, char *partname, PartitionBoundSpec *boundspec,
PartitionSpec *subPart, GpPartDefElem *elem,
- partname_comp *partnamecomp)
+ partname_comp *partnamecomp, CreateStmtOrigin origin)
{
CreateStmt *childstmt;
RangeVar *parentrv;
@@ -922,7 +929,7 @@ makePartitionCreateStmt(Relation parentrel, char *partname, PartitionBoundSpec *
childstmt->tablespacename = elem->tablespacename ? pstrdup(elem->tablespacename) : NULL;
childstmt->accessMethod = elem->accessMethod ? pstrdup(elem->accessMethod) : NULL;
childstmt->if_not_exists = false;
- childstmt->gp_style_alter_part = true;
+ childstmt->origin = origin;
childstmt->distributedBy = make_distributedby_for_rel(parentrel);
childstmt->partitionBy = NULL;
childstmt->relKind = 0;
@@ -939,7 +946,8 @@ generateRangePartitions(ParseState *pstate,
GpPartDefElem *elem,
PartitionSpec *subPart,
partname_comp *partnamecomp,
- bool *hasImplicitRangeBounds)
+ bool *hasImplicitRangeBounds,
+ CreateStmtOrigin origin)
{
GpPartitionRangeSpec *boundspec;
List *result = NIL;
@@ -1070,7 +1078,7 @@ generateRangePartitions(ParseState *pstate,
partname = elem->partName;
childstmt = makePartitionCreateStmt(parentrel, partname, boundspec,
- copyObject(subPart), elem, partnamecomp);
+ copyObject(subPart), elem, partnamecomp, origin);
result = lappend(result, childstmt);
}
@@ -1084,7 +1092,8 @@ generateListPartition(ParseState *pstate,
Relation parentrel,
GpPartDefElem *elem,
PartitionSpec *subPart,
- partname_comp *partnamecomp)
+ partname_comp *partnamecomp,
+ CreateStmtOrigin origin)
{
GpPartitionListSpec *gpvaluesspec;
PartitionBoundSpec *boundspec;
@@ -1139,7 +1148,7 @@ generateListPartition(ParseState *pstate,
boundspec = transformPartitionBound(pstate, parentrel, RelationGetPartitionKey(parentrel), boundspec);
childstmt = makePartitionCreateStmt(parentrel, elem->partName, boundspec, subPart,
- elem, partnamecomp);
+ elem, partnamecomp, origin);
return list_make1(childstmt);
}
@@ -1149,7 +1158,8 @@ generateDefaultPartition(ParseState *pstate,
Relation parentrel,
GpPartDefElem *elem,
PartitionSpec *subPart,
- partname_comp *partnamecomp)
+ partname_comp *partnamecomp,
+ CreateStmtOrigin origin)
{
PartitionBoundSpec *boundspec;
CreateStmt *childstmt;
@@ -1161,7 +1171,7 @@ generateDefaultPartition(ParseState *pstate,
/* default partition always needs name to be specified */
Assert(elem->partName != NULL);
childstmt = makePartitionCreateStmt(parentrel, elem->partName, boundspec, subPart,
- elem, partnamecomp);
+ elem, partnamecomp, origin);
return list_make1(childstmt);
}
@@ -1472,7 +1482,7 @@ List *
generatePartitions(Oid parentrelid, GpPartitionDefinition *gpPartSpec,
PartitionSpec *subPartSpec, const char *queryString,
List *parentoptions, const char *parentaccessmethod,
- List *parentattenc, bool forvalidationonly)
+ List *parentattenc, CreateStmtOrigin origin)
{
Relation parentrel;
List *result = NIL;
@@ -1688,7 +1698,7 @@ generatePartitions(Oid parentrelid, GpPartitionDefinition *gpPartSpec,
}
if (elem->isDefault)
- new_parts = generateDefaultPartition(pstate, parentrel, elem, tmpSubPartSpec, &partcomp);
+ new_parts = generateDefaultPartition(pstate, parentrel, elem, tmpSubPartSpec, &partcomp, origin);
else
{
PartitionKey key = RelationGetPartitionKey(parentrel);
@@ -1698,11 +1708,11 @@ generatePartitions(Oid parentrelid, GpPartitionDefinition *gpPartSpec,
case PARTITION_STRATEGY_RANGE:
new_parts = generateRangePartitions(pstate, parentrel,
elem, tmpSubPartSpec, &partcomp,
- &hasImplicitRangeBounds);
+ &hasImplicitRangeBounds, origin);
break;
case PARTITION_STRATEGY_LIST:
- new_parts = generateListPartition(pstate, parentrel, elem, tmpSubPartSpec, &partcomp);
+ new_parts = generateListPartition(pstate, parentrel, elem, tmpSubPartSpec, &partcomp, origin);
break;
default:
elog(ERROR, "Not supported partition strategy");
@@ -1726,8 +1736,8 @@ generatePartitions(Oid parentrelid, GpPartitionDefinition *gpPartSpec,
* or END specification. While that's true for ADD PARTITION, it's not
* while setting template.
*/
- if (hasImplicitRangeBounds && !forvalidationonly)
- deduceImplicitRangeBounds(pstate, parentrel, result);
+ if (hasImplicitRangeBounds)
+ deduceImplicitRangeBounds(pstate, parentrel, result, origin);
free_parsestate(pstate);
table_close(parentrel, NoLock);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 106bf2379d..e6c2f5ab3f 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1537,8 +1537,9 @@ ProcessUtilitySlow(ParseState *pstate,
cstmt->partspec->gpPartDef,
cstmt->partspec->subPartSpec,
queryString, cstmt->options,
- cstmt->accessMethod,
- cstmt->attr_encodings, false);
+ cstmt->accessMethod,
+ cstmt->attr_encodings,
+ ORIGIN_GP_CLASSIC_CREATE_GEN);
stmts = list_concat(stmts, parts);
}
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 5e21e4eaa6..9cae3e2376 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2474,6 +2474,21 @@ typedef struct VariableShowStmt
char *name;
} VariableShowStmt;
+/*
+ * GPDB: Where did the CreateStmt originate? Was it generated and if so, what
+ * type of operation generated it?
+ *
+ * Note: 'classic' syntax refers to the legacy GPDB partitioning syntax that
+ * predates the upstream partitioning syntax that was acquired during the
+ * Postgres 12 merge.
+ */
+typedef enum CreateStmtOrigin
+{
+ ORIGIN_NO_GEN,
+ ORIGIN_GP_CLASSIC_CREATE_GEN,
+ ORIGIN_GP_CLASSIC_ALTER_GEN
+} CreateStmtOrigin;
+
/* ----------------------
* Create Table Statement
*
@@ -2502,7 +2517,7 @@ typedef struct CreateStmt
char *tablespacename; /* table space to use, or NULL */
char *accessMethod; /* table access method */
bool if_not_exists; /* just do nothing if it already exists? */
- bool gp_style_alter_part; /* is this due to a GP-style ALTER on partition tables? */
+ bool gp_style_alter_part; /* unused */
DistributedBy *distributedBy; /* what columns we distribute the data by */
Node *partitionBy; /* what columns we partition the data by */
@@ -2518,6 +2533,8 @@ typedef struct CreateStmt
List *part_idx_oids;
List *part_idx_names;
List *tags; /* List of tags DefElem nodes */
+
+ CreateStmtOrigin origin; /* GPDB: provenance of this CreateStmt */
} CreateStmt;
/* ----------------------
diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h
index 836c283dcd..9fed9ba6d8 100644
--- a/src/include/parser/parse_utilcmd.h
+++ b/src/include/parser/parse_utilcmd.h
@@ -54,7 +54,10 @@ extern List *generatePartitions(Oid parentrelid, GpPartitionDefinition *gpPartSp
PartitionSpec *subPartSpec,
const char *queryString, List *parentoptions,
const char *parentaccessmethod,
- List *parentattenc, bool forvalidationonly);
+ List *parentattenc, CreateStmtOrigin origin);
+GpPartitionDefinition *
+transformGpPartitionDefinition(Oid parentrelid, const char *queryString,
+ GpPartitionDefinition *gpPartDef_orig);
extern void convert_exclusive_start_inclusive_end(Const *constval, Oid part_col_typid,
int32 part_col_typmod, bool is_exclusive_start);
@@ -69,7 +72,8 @@ extern CreateStmt *makePartitionCreateStmt(Relation parentrel, char *partname,
PartitionBoundSpec *boundspec,
PartitionSpec *subPart,
GpPartDefElem *elem,
- partname_comp *partnamecomp);
+ partname_comp *partnamecomp,
+ CreateStmtOrigin origin);
extern char *ChoosePartitionName(const char *parentname, int level,
Oid naemspaceId, const char *partname,
int partnum);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org
(cloudberry) 02/06: Rename the resource group parameter 'memory_limit' to 'memory_quota' (#17378)
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 0716b614136541159f4a480aefd27c79e8001e61
Author: Zhenglong Li <lz...@vmware.com>
AuthorDate: Wed May 8 14:24:48 2024 +0800
Rename the resource group parameter 'memory_limit' to 'memory_quota' (#17378)
`CREATE RESOURCE GROUP` and `ALTER RESOURCE GROUP`, both 6X and 7X have the same
parameter name, though the meaning for them is totally different (7X is an absolute number and
6X is a percentage of memory).
So we rename 7X parameter to `memory_quota` to clearly convey its difference from 6X
and also to convey the units as well for ease of use.
```
CREATE RESOURCE GROUP rg_memory_test WITH(memory_quota=-1, cpu_max_percent=20, concurrency=2);
ALTER RESOURCE GROUP rg_memory_test SET memory_quota 1000;
```
Fix resgroup memory_quota 2
---
doc/src/sgml/ref/alter_resource_group.sgml | 1 +
doc/src/sgml/ref/create_resource_group.sgml | 1 +
gpcontrib/gp_toolkit/gp_toolkit--1.3.sql | 2 +-
src/backend/commands/resgroupcmds.c | 42 +++++++++++-----------
src/backend/parser/gram.y | 14 ++++----
src/backend/utils/resgroup/resgroup.c | 6 ++--
src/bin/psql/tab-complete.c | 2 +-
src/include/catalog/pg_resgroup.h | 2 +-
src/include/parser/kwlist.h | 2 +-
src/include/utils/resgroup.h | 2 +-
.../expected/resgroup_current_1_queue.out | 6 ++--
.../expected/resgroup_current_3_group.out | 2 +-
.../expected/resgroup_current_3_queue.out | 2 +-
.../expected/resgroup_other_2_group.out | 2 +-
.../expected/resgroup_other_2_queue.out | 2 +-
.../binary_swap/sql/resgroup_current_1_group.sql | 2 +-
.../binary_swap/sql/resgroup_current_1_queue.sql | 6 ++--
.../binary_swap/sql/resgroup_current_3_group.sql | 2 +-
.../binary_swap/sql/resgroup_current_3_queue.sql | 2 +-
.../binary_swap/sql/resgroup_other_2_group.sql | 2 +-
.../binary_swap/sql/resgroup_other_2_queue.sql | 2 +-
.../resgroup/resgroup_auxiliary_tools_v1.out | 2 +-
.../resgroup/resgroup_auxiliary_tools_v2.out | 2 +-
.../expected/resgroup/resgroup_memory_limit.out | 14 ++++----
.../resgroup/resgroup_memory_limit_resgroup_v2.out | 4 +--
.../expected/resgroup/resgroup_syntax.out | 2 +-
.../expected/resgroup/resgroup_views.out | 2 +-
.../sql/resgroup/resgroup_memory_limit.sql | 13 +++----
.../resgroup/resgroup_memory_limit_resgroup_v2.sql | 4 +--
29 files changed, 75 insertions(+), 72 deletions(-)
diff --git a/doc/src/sgml/ref/alter_resource_group.sgml b/doc/src/sgml/ref/alter_resource_group.sgml
index e68e449280..d9da6f9676 100755
--- a/doc/src/sgml/ref/alter_resource_group.sgml
+++ b/doc/src/sgml/ref/alter_resource_group.sgml
@@ -28,6 +28,7 @@ where group_attribute is one of:
CPU_MAX_PERCENT integer
CPU_WEIGHT integer
CPUSET tuple
+ MEMORY_QUOTA integer
</synopsis>
</refsynopsisdiv>
diff --git a/doc/src/sgml/ref/create_resource_group.sgml b/doc/src/sgml/ref/create_resource_group.sgml
index 2058e356cb..74542c69e4 100755
--- a/doc/src/sgml/ref/create_resource_group.sgml
+++ b/doc/src/sgml/ref/create_resource_group.sgml
@@ -26,6 +26,7 @@ where group_attribute is:
CPU_MAX_PERCENT=integer | CPUSET=tuple
[ CONCURRENCY=integer ]
[ CPU_WEIGHT=integer ]
+ [ MEMORY_QUOTA=integer ]
</synopsis>
</refsynopsisdiv>
diff --git a/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql b/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql
index 415d6df2d9..b0b180e184 100644
--- a/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql
+++ b/gpcontrib/gp_toolkit/gp_toolkit--1.3.sql
@@ -1729,7 +1729,7 @@ CREATE VIEW gp_toolkit.gp_resgroup_config AS
, T2.value AS cpu_max_percent
, T3.value AS cpu_weight
, T4.value AS cpuset
- , T5.value AS memory_limit
+ , T5.value AS memory_quota
, T6.value AS min_cost
, T7.value AS io_limit
FROM pg_resgroup G
diff --git a/src/backend/commands/resgroupcmds.c b/src/backend/commands/resgroupcmds.c
index 27b9993f5a..5c319e85b1 100644
--- a/src/backend/commands/resgroupcmds.c
+++ b/src/backend/commands/resgroupcmds.c
@@ -59,8 +59,8 @@
#define RESGROUP_MIN_CPU_WEIGHT (1)
#define RESGROUP_MAX_CPU_WEIGHT (500)
-#define RESGROUP_MIN_MEMORY_LIMIT (0)
-#define RESGROUP_DEFAULT_MEMORY_LIMIT (-1)
+#define RESGROUP_MIN_MEMORY_QUOTA (0)
+#define RESGROUP_DEFAULT_MEMORY_QUOTA (-1)
#define RESGROUP_MIN_MIN_COST (0)
static int str2Int(const char *str, const char *prop);
@@ -457,8 +457,8 @@ AlterResourceGroup(AlterResourceGroupStmt *stmt)
caps.cpuMaxPercent = CPU_MAX_PERCENT_DISABLED;
caps.cpuWeight = RESGROUP_DEFAULT_CPU_WEIGHT;
break;
- case RESGROUP_LIMIT_TYPE_MEMORY_LIMIT:
- caps.memory_limit = value;
+ case RESGROUP_LIMIT_TYPE_MEMORY_QUOTA:
+ caps.memory_quota = value;
break;
case RESGROUP_LIMIT_TYPE_MIN_COST:
caps.min_cost = value;
@@ -623,9 +623,9 @@ GetResGroupCapabilities(Relation rel, Oid groupId, ResGroupCaps *resgroupCaps)
case RESGROUP_LIMIT_TYPE_CPUSET:
strlcpy(resgroupCaps->cpuset, value, sizeof(resgroupCaps->cpuset));
break;
- case RESGROUP_LIMIT_TYPE_MEMORY_LIMIT:
- resgroupCaps->memory_limit = str2Int(value,
- getResgroupOptionName(type));
+ case RESGROUP_LIMIT_TYPE_MEMORY_QUOTA:
+ resgroupCaps->memory_quota = str2Int(value,
+ getResgroupOptionName(type));
break;
case RESGROUP_LIMIT_TYPE_MIN_COST:
resgroupCaps->min_cost = str2Int(value,
@@ -817,8 +817,8 @@ getResgroupOptionType(const char* defname)
return RESGROUP_LIMIT_TYPE_CPUSET;
else if (strcmp(defname, "cpu_weight") == 0)
return RESGROUP_LIMIT_TYPE_CPU_SHARES;
- else if (strcmp(defname, "memory_limit") == 0)
- return RESGROUP_LIMIT_TYPE_MEMORY_LIMIT;
+ else if (strcmp(defname, "memory_quota") == 0)
+ return RESGROUP_LIMIT_TYPE_MEMORY_QUOTA;
else if (strcmp(defname, "min_cost") == 0)
return RESGROUP_LIMIT_TYPE_MIN_COST;
else if (strcmp(defname, "io_limit") == 0)
@@ -864,8 +864,8 @@ getResgroupOptionName(ResGroupLimitType type)
return "cpuset";
case RESGROUP_LIMIT_TYPE_CPU_SHARES:
return "cpu_weight";
- case RESGROUP_LIMIT_TYPE_MEMORY_LIMIT:
- return "memory_limit";
+ case RESGROUP_LIMIT_TYPE_MEMORY_QUOTA:
+ return "memory_quota";
case RESGROUP_LIMIT_TYPE_MIN_COST:
return "min_cost";
default:
@@ -909,12 +909,12 @@ checkResgroupCapLimit(ResGroupLimitType type, int value)
RESGROUP_MIN_CPU_WEIGHT, RESGROUP_MAX_CPU_WEIGHT)));
break;
- case RESGROUP_LIMIT_TYPE_MEMORY_LIMIT:
- if (value < RESGROUP_MIN_MEMORY_LIMIT && value != RESGROUP_DEFAULT_MEMORY_LIMIT)
+ case RESGROUP_LIMIT_TYPE_MEMORY_QUOTA:
+ if (value < RESGROUP_MIN_MEMORY_QUOTA && value != RESGROUP_DEFAULT_MEMORY_QUOTA)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("memory_limit range is [%d, INT_MAX] or equals to %d",
- RESGROUP_MIN_MEMORY_LIMIT, RESGROUP_DEFAULT_MEMORY_LIMIT)));
+ errmsg("memory_quota range is [%d, INT_MAX] or equals to %d",
+ RESGROUP_MIN_MEMORY_QUOTA, RESGROUP_DEFAULT_MEMORY_QUOTA)));
break;
case RESGROUP_LIMIT_TYPE_MIN_COST:
@@ -1002,8 +1002,8 @@ parseStmtOptions(CreateResourceGroupStmt *stmt, ResGroupCaps *caps)
case RESGROUP_LIMIT_TYPE_CPU_SHARES:
caps->cpuWeight = value;
break;
- case RESGROUP_LIMIT_TYPE_MEMORY_LIMIT:
- caps->memory_limit = value;
+ case RESGROUP_LIMIT_TYPE_MEMORY_QUOTA:
+ caps->memory_quota = value;
break;
case RESGROUP_LIMIT_TYPE_MIN_COST:
caps->min_cost = value;
@@ -1032,8 +1032,8 @@ parseStmtOptions(CreateResourceGroupStmt *stmt, ResGroupCaps *caps)
if (!(mask & (1 << RESGROUP_LIMIT_TYPE_CONCURRENCY)))
caps->concurrency = RESGROUP_DEFAULT_CONCURRENCY;
- if (!(mask & (1 << RESGROUP_LIMIT_TYPE_MEMORY_LIMIT)))
- caps->memory_limit = -1;
+ if (!(mask & (1 << RESGROUP_LIMIT_TYPE_MEMORY_QUOTA)))
+ caps->memory_quota = -1;
if (!(mask & (1 << RESGROUP_LIMIT_TYPE_MIN_COST)))
caps->min_cost = 0;
@@ -1136,9 +1136,9 @@ insertResgroupCapabilities(Relation rel, Oid groupId, ResGroupCaps *caps)
insertResgroupCapabilityEntry(rel, groupId,
RESGROUP_LIMIT_TYPE_CPUSET, caps->cpuset);
- snprintf(value, sizeof(value), "%d", caps->memory_limit);
+ snprintf(value, sizeof(value), "%d", caps->memory_quota);
insertResgroupCapabilityEntry(rel, groupId,
- RESGROUP_LIMIT_TYPE_MEMORY_LIMIT, value);
+ RESGROUP_LIMIT_TYPE_MEMORY_QUOTA, value);
snprintf(value, sizeof(value), "%d", caps->min_cost);
insertResgroupCapabilityEntry(rel, groupId,
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 77ef28983b..bb60e8129c 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -795,7 +795,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_
LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOCUS LOGGED
- MAPPING MATCH MATERIALIZED MAXVALUE MEMORY_LIMIT
+ MAPPING MATCH MATERIALIZED MAXVALUE MEMORY_QUOTA
METHOD MINUTE_P MINVALUE MIN_COST MODE MONTH_P MOVE
NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NFC NFD NFKC NFKD NO NONE
@@ -1114,7 +1114,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_
%nonassoc MASTER
%nonassoc MATCH
%nonassoc MAXVALUE
- %nonassoc MEMORY_LIMIT
+ %nonassoc MEMORY_QUOTA
%nonassoc METHOD
%nonassoc MIN_COST
%nonassoc MINUTE_P
@@ -1784,9 +1784,9 @@ OptResourceGroupElem:
{
$$ = makeDefElem("cpuset", (Node *) makeString($2), @1);
}
- | MEMORY_LIMIT SignedIconst
+ | MEMORY_QUOTA SignedIconst
{
- $$ = makeDefElem("memory_limit", (Node *) makeInteger($2), @1);
+ $$ = makeDefElem("memory_quota", (Node *) makeInteger($2), @1);
}
| MIN_COST SignedIconst
{
@@ -19767,7 +19767,7 @@ unreserved_keyword:
| MATCH
| MATERIALIZED
| MAXVALUE
- | MEMORY_LIMIT
+ | MEMORY_QUOTA
| METHOD
| MINUTE_P
| MINVALUE
@@ -20125,7 +20125,7 @@ PartitionIdentKeyword: ABORT_P
| MASTER
| MATCH
| MAXVALUE
- | MEMORY_LIMIT
+ | MEMORY_QUOTA
| METHOD
| MINVALUE
| MISSING
@@ -20759,7 +20759,7 @@ bare_label_keyword:
| MATERIALIZED
| MAXVALUE
| MEDIAN
- | MEMORY_LIMIT
+ | MEMORY_QUOTA
| METHOD
| MINVALUE
| MIN_COST
diff --git a/src/backend/utils/resgroup/resgroup.c b/src/backend/utils/resgroup/resgroup.c
index 2a6b36246e..930aece4cb 100644
--- a/src/backend/utils/resgroup/resgroup.c
+++ b/src/backend/utils/resgroup/resgroup.c
@@ -1426,7 +1426,7 @@ SerializeResGroupInfo(StringInfo str)
appendBinaryStringInfo(str, (char *) &itmp, sizeof(int32));
itmp = htonl(caps->cpuWeight);
appendBinaryStringInfo(str, (char *) &itmp, sizeof(int32));
- itmp = htonl(caps->memory_limit);
+ itmp = htonl(caps->memory_quota);
appendBinaryStringInfo(str, (char *) &itmp, sizeof(int32));
itmp = htonl(caps->min_cost);
appendBinaryStringInfo(str, (char *) &itmp, sizeof(int32));
@@ -1467,7 +1467,7 @@ DeserializeResGroupInfo(struct ResGroupCaps *capsOut,
memcpy(&itmp, ptr, sizeof(int32)); ptr += sizeof(int32);
capsOut->cpuWeight = ntohl(itmp);
memcpy(&itmp, ptr, sizeof(int32)); ptr += sizeof(int32);
- capsOut->memory_limit = ntohl(itmp);
+ capsOut->memory_quota = ntohl(itmp);
memcpy(&itmp, ptr, sizeof(int32)); ptr += sizeof(int32);
capsOut->min_cost = ntohl(itmp);
@@ -3625,7 +3625,7 @@ ResourceGroupGetQueryMemoryLimit(void)
LWLockAcquire(ResGroupLock, LW_SHARED);
caps = &self->group->caps;
- resgLimit = caps->memory_limit;
+ resgLimit = caps->memory_quota;
AssertImply(resgLimit < 0, resgLimit == -1);
if (resgLimit == -1)
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 5407e47642..db7aa47bdf 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3140,7 +3140,7 @@ psql_completion(const char *text, int start, int end)
else if (TailMatches("RESOURCE", "GROUP", MatchAny, "WITH", "("))
{
static const char *const list_CREATERESOURCEGROUP[] =
- {"CONCURRENCY", "cpu_max_percent", "MEMORY_LIMIT", "MEMORY_REDZONE_LIMIT", NULL};
+ {"CONCURRENCY", "CPU_MAX_PERCENT", "CPUSET", "CPU_WEIGHT", "MEMORY_QUOTA", "MIN_COST", "IO_LIMIT", NULL};
COMPLETE_WITH_LIST(list_CREATERESOURCEGROUP);
}
diff --git a/src/include/catalog/pg_resgroup.h b/src/include/catalog/pg_resgroup.h
index cd2d55aa48..4dd603f8f8 100644
--- a/src/include/catalog/pg_resgroup.h
+++ b/src/include/catalog/pg_resgroup.h
@@ -55,7 +55,7 @@ typedef enum ResGroupLimitType
RESGROUP_LIMIT_TYPE_CPU, /* cpu_max_percent */
RESGROUP_LIMIT_TYPE_CPU_SHARES, /* cpu_weight */
RESGROUP_LIMIT_TYPE_CPUSET, /* cpuset */
- RESGROUP_LIMIT_TYPE_MEMORY_LIMIT, /* memory_limit */
+ RESGROUP_LIMIT_TYPE_MEMORY_QUOTA, /* memory_quota */
RESGROUP_LIMIT_TYPE_MIN_COST, /* min_cost */
RESGROUP_LIMIT_TYPE_IO_LIMIT, /* io_limit */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index f4862691f2..f05bab4f6b 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -293,7 +293,7 @@ PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("median", MEDIAN, COL_NAME_KEYWORD, BARE_LABEL)
-PG_KEYWORD("memory_limit", MEMORY_LIMIT, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("memory_quota", MEMORY_QUOTA, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("min_cost", MIN_COST, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD, AS_LABEL)
diff --git a/src/include/utils/resgroup.h b/src/include/utils/resgroup.h
index af787fe50e..6db5a10a0e 100644
--- a/src/include/utils/resgroup.h
+++ b/src/include/utils/resgroup.h
@@ -74,7 +74,7 @@ typedef struct ResGroupCaps
ResGroupCap concurrency;
ResGroupCap cpuMaxPercent;
ResGroupCap cpuWeight;
- ResGroupCap memory_limit;
+ ResGroupCap memory_quota;
volatile ResGroupCap min_cost;
/*
diff --git a/src/test/binary_swap/expected/resgroup_current_1_queue.out b/src/test/binary_swap/expected/resgroup_current_1_queue.out
index a4c555a4d6..3cf6ed598e 100644
--- a/src/test/binary_swap/expected/resgroup_current_1_queue.out
+++ b/src/test/binary_swap/expected/resgroup_current_1_queue.out
@@ -39,15 +39,15 @@ select rsgname from gp_toolkit.gp_resgroup_status
---------
(0 rows)
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
WARNING: resource group is disabled
HINT: To enable set gp_resource_manager=group
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
WARNING: resource group is disabled
HINT: To enable set gp_resource_manager=group
-create resource group rg2 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg2 with (cpu_max_percent=10, memory_quota=10);
WARNING: resource group is disabled
HINT: To enable set gp_resource_manager=group
diff --git a/src/test/binary_swap/expected/resgroup_current_3_group.out b/src/test/binary_swap/expected/resgroup_current_3_group.out
index d1a39839ae..2a879b6b52 100644
--- a/src/test/binary_swap/expected/resgroup_current_3_group.out
+++ b/src/test/binary_swap/expected/resgroup_current_3_group.out
@@ -48,7 +48,7 @@ select rsgname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
-- TODO: change to the resgroup
diff --git a/src/test/binary_swap/expected/resgroup_current_3_queue.out b/src/test/binary_swap/expected/resgroup_current_3_queue.out
index d1add58d83..da059eec14 100644
--- a/src/test/binary_swap/expected/resgroup_current_3_queue.out
+++ b/src/test/binary_swap/expected/resgroup_current_3_queue.out
@@ -46,7 +46,7 @@ select rsgname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
WARNING: resource group is disabled
HINT: To enable set gp_resource_manager=group
alter resource group rg2 set cpu_max_percent 20;
diff --git a/src/test/binary_swap/expected/resgroup_other_2_group.out b/src/test/binary_swap/expected/resgroup_other_2_group.out
index e24486f235..8ce74005e3 100644
--- a/src/test/binary_swap/expected/resgroup_other_2_group.out
+++ b/src/test/binary_swap/expected/resgroup_other_2_group.out
@@ -48,7 +48,7 @@ select rsgname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
-- TODO: change to the resgroup
diff --git a/src/test/binary_swap/expected/resgroup_other_2_queue.out b/src/test/binary_swap/expected/resgroup_other_2_queue.out
index 85f710786d..d6e39e8178 100644
--- a/src/test/binary_swap/expected/resgroup_other_2_queue.out
+++ b/src/test/binary_swap/expected/resgroup_other_2_queue.out
@@ -46,7 +46,7 @@ select rsgname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
WARNING: resource group is disabled
HINT: To enable set gp_resource_manager=group
alter resource group rg2 set cpu_max_percent 20;
diff --git a/src/test/binary_swap/sql/resgroup_current_1_group.sql b/src/test/binary_swap/sql/resgroup_current_1_group.sql
index b42e491a0a..af7c7da851 100644
--- a/src/test/binary_swap/sql/resgroup_current_1_group.sql
+++ b/src/test/binary_swap/sql/resgroup_current_1_group.sql
@@ -16,7 +16,7 @@ select groupname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
diff --git a/src/test/binary_swap/sql/resgroup_current_1_queue.sql b/src/test/binary_swap/sql/resgroup_current_1_queue.sql
index a3f18dcab7..dae1e15efc 100644
--- a/src/test/binary_swap/sql/resgroup_current_1_queue.sql
+++ b/src/test/binary_swap/sql/resgroup_current_1_queue.sql
@@ -13,10 +13,10 @@ select groupname from gp_toolkit.gp_resgroup_status
where groupname not like 'rg_dump_test%'
order by groupid;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
-create resource group rg2 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg2 with (cpu_max_percent=10, memory_quota=10);
diff --git a/src/test/binary_swap/sql/resgroup_current_3_group.sql b/src/test/binary_swap/sql/resgroup_current_3_group.sql
index b42e491a0a..af7c7da851 100644
--- a/src/test/binary_swap/sql/resgroup_current_3_group.sql
+++ b/src/test/binary_swap/sql/resgroup_current_3_group.sql
@@ -16,7 +16,7 @@ select groupname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
diff --git a/src/test/binary_swap/sql/resgroup_current_3_queue.sql b/src/test/binary_swap/sql/resgroup_current_3_queue.sql
index 42f91fff1c..08b2533ec6 100644
--- a/src/test/binary_swap/sql/resgroup_current_3_queue.sql
+++ b/src/test/binary_swap/sql/resgroup_current_3_queue.sql
@@ -16,7 +16,7 @@ select groupname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
diff --git a/src/test/binary_swap/sql/resgroup_other_2_group.sql b/src/test/binary_swap/sql/resgroup_other_2_group.sql
index b42e491a0a..af7c7da851 100644
--- a/src/test/binary_swap/sql/resgroup_other_2_group.sql
+++ b/src/test/binary_swap/sql/resgroup_other_2_group.sql
@@ -16,7 +16,7 @@ select groupname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
diff --git a/src/test/binary_swap/sql/resgroup_other_2_queue.sql b/src/test/binary_swap/sql/resgroup_other_2_queue.sql
index 42f91fff1c..08b2533ec6 100644
--- a/src/test/binary_swap/sql/resgroup_other_2_queue.sql
+++ b/src/test/binary_swap/sql/resgroup_other_2_queue.sql
@@ -16,7 +16,7 @@ select groupname from gp_toolkit.gp_resgroup_status
alter resource group rg1 set cpu_max_percent 20;
alter resource group rg1 set cpu_max_percent 10;
drop resource group rg1;
-create resource group rg1 with (cpu_max_percent=10, memory_limit=10);
+create resource group rg1 with (cpu_max_percent=10, memory_quota=10);
alter resource group rg2 set cpu_max_percent 20;
alter resource group rg2 set cpu_max_percent 10;
diff --git a/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v1.out b/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v1.out
index 2aee9ee3b8..1120930c15 100644
--- a/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v1.out
+++ b/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v1.out
@@ -54,7 +54,7 @@ ERROR: language "plpython3u" already exists
-- verify the default settings
0: SELECT * from gp_toolkit.gp_resgroup_config;
- groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_limit | min_cost | io_limit
+ groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_quota | min_cost | io_limit
---------+---------------+-------------+-----------------+------------+--------+--------------+----------+----------
6437 | default_group | 20 | 20 | 100 | -1 | -1 | 500 | -1
6438 | admin_group | 10 | 10 | 100 | -1 | -1 | 500 | -1
diff --git a/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v2.out b/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v2.out
index 8790853160..779e4dd1bc 100644
--- a/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v2.out
+++ b/src/test/isolation2/expected/resgroup/resgroup_auxiliary_tools_v2.out
@@ -54,7 +54,7 @@ ERROR: language "plpython3u" already exists
-- verify the default settings
0: SELECT * from gp_toolkit.gp_resgroup_config;
- groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_limit | min_cost | io_limit
+ groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_quota | min_cost | io_limit
---------+---------------+-------------+-----------------+------------+--------+--------------+----------+----------
6437 | default_group | 20 | 20 | 100 | -1 | -1 | 500 | -1
6438 | admin_group | 10 | 10 | 100 | -1 | -1 | 500 | -1
diff --git a/src/test/isolation2/expected/resgroup/resgroup_memory_limit.out b/src/test/isolation2/expected/resgroup/resgroup_memory_limit.out
index 04ae26049f..41a568503e 100644
--- a/src/test/isolation2/expected/resgroup/resgroup_memory_limit.out
+++ b/src/test/isolation2/expected/resgroup/resgroup_memory_limit.out
@@ -9,16 +9,16 @@ DROP RESOURCE GROUP rg_memory_test;
CREATE OR REPLACE FUNCTION func_memory_test (text) RETURNS text as /*in func*/ $$ /*in func*/ DECLARE /*in func*/ ln text; /*in func*/ tmp text[]; /*in func*/ match bool := false; /*in func*/ BEGIN /*in func*/ FOR ln IN execute format('explain analyze %s', $1) LOOP /*in func*/ IF NOT match THEN /*in func*/ tmp := regexp_match(ln, 'Memory used: (.*)'); /*in func*/ IF tmp IS NOT null THEN /*in func*/ match := true; /*in func*/ END IF; /*in func*/ END IF; /*in func*/ END LOOP; /*in fu [...]
CREATE
--- memory_limit range is [0, INT_MAX] or equals to -1
-CREATE RESOURCE GROUP rg_memory_range WITH(memory_limit=-100, cpu_max_percent=20, concurrency=2);
-ERROR: memory_limit range is [0, INT_MAX] or equals to -1
-CREATE RESOURCE GROUP rg_memory_range WITH(memory_limit=-1, cpu_max_percent=20, concurrency=2);
+-- memory_quota range is [0, INT_MAX] or equals to -1
+CREATE RESOURCE GROUP rg_memory_range WITH(memory_quota=-100, cpu_max_percent=20, concurrency=2);
+ERROR: memory_quota range is [0, INT_MAX] or equals to -1
+CREATE RESOURCE GROUP rg_memory_range WITH(memory_quota=-1, cpu_max_percent=20, concurrency=2);
CREATE RESOURCE GROUP
DROP RESOURCE GROUP rg_memory_range;
DROP RESOURCE GROUP
-- create a resource group with memory limit 100 Mb
-CREATE RESOURCE GROUP rg_memory_test WITH(memory_limit=100, cpu_max_percent=20, concurrency=2);
+CREATE RESOURCE GROUP rg_memory_test WITH(memory_quota=100, cpu_max_percent=20, concurrency=2);
CREATE
CREATE ROLE role_memory_test RESOURCE GROUP rg_memory_test;
CREATE
@@ -42,8 +42,8 @@ BEGIN
256000kB
(1 row)
--- session2: test alter resource group's memory limit
-2: ALTER RESOURCE GROUP rg_memory_test SET memory_limit 1000;
+-- session2: test alter resource group's memory quota
+2: ALTER RESOURCE GROUP rg_memory_test SET memory_quota 1000;
ALTER
-- memory used will grow up to 500 Mb
diff --git a/src/test/isolation2/expected/resgroup/resgroup_memory_limit_resgroup_v2.out b/src/test/isolation2/expected/resgroup/resgroup_memory_limit_resgroup_v2.out
index 1653733867..31ceaf5da2 100644
--- a/src/test/isolation2/expected/resgroup/resgroup_memory_limit_resgroup_v2.out
+++ b/src/test/isolation2/expected/resgroup/resgroup_memory_limit_resgroup_v2.out
@@ -13,7 +13,7 @@ CREATE OR REPLACE FUNCTION func_memory_test (text) RETURNS text as /*in func*/ $
CREATE
-- create a resource group with memory limit 100 Mb
-CREATE RESOURCE GROUP rg_memory_test WITH(memory_limit=100, cpu_max_percent=20, concurrency=2);
+CREATE RESOURCE GROUP rg_memory_test WITH(memory_quota=100, cpu_max_percent=20, concurrency=2);
CREATE
CREATE ROLE role_memory_test RESOURCE GROUP rg_memory_test;
CREATE
@@ -38,7 +38,7 @@ BEGIN
(1 row)
-- session2: test alter resource group's memory limit
-2: ALTER RESOURCE GROUP rg_memory_test SET memory_limit 1000;
+2: ALTER RESOURCE GROUP rg_memory_test SET memory_quota 1000;
ALTER
-- memory used will grow up to 500 Mb
diff --git a/src/test/isolation2/expected/resgroup/resgroup_syntax.out b/src/test/isolation2/expected/resgroup/resgroup_syntax.out
index 577940f4d2..1b645564f2 100644
--- a/src/test/isolation2/expected/resgroup/resgroup_syntax.out
+++ b/src/test/isolation2/expected/resgroup/resgroup_syntax.out
@@ -104,7 +104,7 @@ ERROR: resource group "rg_test_group" does not exist
--end_ignore
SELECT * FROM gp_toolkit.gp_resgroup_config;
- groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_limit | min_cost | io_limit
+ groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_quota | min_cost | io_limit
---------+---------------+-------------+-----------------+------------+--------+--------------+----------+----------
6437 | default_group | 20 | 20 | 100 | -1 | -1 | 500 | -1
6438 | admin_group | 10 | 10 | 100 | -1 | -1 | 500 | -1
diff --git a/src/test/isolation2/expected/resgroup/resgroup_views.out b/src/test/isolation2/expected/resgroup/resgroup_views.out
index e273df69eb..4cd83ce5d4 100644
--- a/src/test/isolation2/expected/resgroup/resgroup_views.out
+++ b/src/test/isolation2/expected/resgroup/resgroup_views.out
@@ -1,5 +1,5 @@
select * from gp_toolkit.gp_resgroup_config where groupname='default_group';
- groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_limit | min_cost | io_limit
+ groupid | groupname | concurrency | cpu_max_percent | cpu_weight | cpuset | memory_quota | min_cost | io_limit
---------+---------------+-------------+-----------------+------------+--------+--------------+----------+----------
6437 | default_group | 20 | 20 | 100 | -1 | -1 | 500 | -1
(1 row)
diff --git a/src/test/isolation2/sql/resgroup/resgroup_memory_limit.sql b/src/test/isolation2/sql/resgroup/resgroup_memory_limit.sql
index 45deaa10d6..578b0f7386 100644
--- a/src/test/isolation2/sql/resgroup/resgroup_memory_limit.sql
+++ b/src/test/isolation2/sql/resgroup/resgroup_memory_limit.sql
@@ -26,13 +26,13 @@ END; /*in func*/
$$ /*in func*/
LANGUAGE plpgsql;
--- memory_limit range is [0, INT_MAX] or equals to -1
-CREATE RESOURCE GROUP rg_memory_range WITH(memory_limit=-100, cpu_max_percent=20, concurrency=2);
-CREATE RESOURCE GROUP rg_memory_range WITH(memory_limit=-1, cpu_max_percent=20, concurrency=2);
+-- memory_quota range is [0, INT_MAX] or equals to -1
+CREATE RESOURCE GROUP rg_memory_range WITH(memory_quota=-100, cpu_max_percent=20, concurrency=2);
+CREATE RESOURCE GROUP rg_memory_range WITH(memory_quota=-1, cpu_max_percent=20, concurrency=2);
DROP RESOURCE GROUP rg_memory_range;
-- create a resource group with memory limit 100 Mb
-CREATE RESOURCE GROUP rg_memory_test WITH(memory_limit=100, cpu_max_percent=20, concurrency=2);
+CREATE RESOURCE GROUP rg_memory_test WITH(memory_quota=100, cpu_max_percent=20, concurrency=2);
CREATE ROLE role_memory_test RESOURCE GROUP rg_memory_test;
-- session1: explain memory used by query
@@ -43,8 +43,8 @@ CREATE ROLE role_memory_test RESOURCE GROUP rg_memory_test;
1: SHOW statement_mem;
1: SELECT func_memory_test('SELECT * FROM t_memory_limit');
--- session2: test alter resource group's memory limit
-2: ALTER RESOURCE GROUP rg_memory_test SET memory_limit 1000;
+-- session2: test alter resource group's memory quota
+2: ALTER RESOURCE GROUP rg_memory_test SET memory_quota 1000;
-- memory used will grow up to 500 Mb
1: SELECT func_memory_test('SELECT * FROM t_memory_limit');
@@ -65,3 +65,4 @@ DROP FUNCTION func_memory_test(text);
DROP TABLE t_memory_limit;
DROP ROLE IF EXISTS role_memory_test;
DROP RESOURCE GROUP rg_memory_test;
+
diff --git a/src/test/isolation2/sql/resgroup/resgroup_memory_limit_resgroup_v2.sql b/src/test/isolation2/sql/resgroup/resgroup_memory_limit_resgroup_v2.sql
index 4db7eb0995..55bdb07eb2 100644
--- a/src/test/isolation2/sql/resgroup/resgroup_memory_limit_resgroup_v2.sql
+++ b/src/test/isolation2/sql/resgroup/resgroup_memory_limit_resgroup_v2.sql
@@ -27,7 +27,7 @@ $$ /*in func*/
LANGUAGE plpgsql;
-- create a resource group with memory limit 100 Mb
-CREATE RESOURCE GROUP rg_memory_test WITH(memory_limit=100, cpu_max_percent=20, concurrency=2);
+CREATE RESOURCE GROUP rg_memory_test WITH(memory_quota=100, cpu_max_percent=20, concurrency=2);
CREATE ROLE role_memory_test RESOURCE GROUP rg_memory_test;
-- session1: explain memory used by query
@@ -39,7 +39,7 @@ CREATE ROLE role_memory_test RESOURCE GROUP rg_memory_test;
1: SELECT func_memory_test('SELECT * FROM t_memory_limit');
-- session2: test alter resource group's memory limit
-2: ALTER RESOURCE GROUP rg_memory_test SET memory_limit 1000;
+2: ALTER RESOURCE GROUP rg_memory_test SET memory_quota 1000;
-- memory used will grow up to 500 Mb
1: SELECT func_memory_test('SELECT * FROM t_memory_limit');
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org
(cloudberry) 04/06: Fix result is wrong when outer query has order by after LATERAL subquery (#17228)
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit c69821feef4a38c9f50884b42ed2b50b85679022
Author: xuejing zhao <80...@users.noreply.github.com>
AuthorDate: Wed Apr 3 10:15:34 2024 +0800
Fix result is wrong when outer query has order by after LATERAL subquery (#17228)
Fix issue: https://github.com/greenplum-db/gpdb/issues/14682
The following codes in cdbpathtoplan_create_motion_plan will ignore path->path.pathkeys,
Which lead to incorrect results.
```
else if (CdbPathLocus_IsOuterQuery(path->path.locus))
{
motion = make_union_motion(subplan);
motion->motionType = MOTIONTYPE_OUTER_QUERY;
}
```
So use make_sorted_union_motion instead of make_union_motion if path has pathkeys.
---
src/backend/cdb/cdbllize.c | 16 +++-
src/backend/optimizer/plan/createplan.c | 20 ++---
src/include/optimizer/planmain.h | 3 +
src/test/regress/expected/subselect_gp.out | 92 ++++++++++++++++++++++
.../regress/expected/subselect_gp_optimizer.out | 92 ++++++++++++++++++++++
src/test/regress/sql/subselect_gp.sql | 22 +++++-
6 files changed, 232 insertions(+), 13 deletions(-)
diff --git a/src/backend/cdb/cdbllize.c b/src/backend/cdb/cdbllize.c
index 1c752a3fdd..538be03b8c 100644
--- a/src/backend/cdb/cdbllize.c
+++ b/src/backend/cdb/cdbllize.c
@@ -918,8 +918,6 @@ fix_outer_query_motions_mutator(Node *node, decorate_subplans_with_motions_conte
*/
if (motion->motionType == MOTIONTYPE_OUTER_QUERY)
{
- Assert(!motion->sendSorted);
-
if (context->currentPlanFlow->flotype == FLOW_SINGLETON)
{
motion->motionType = MOTIONTYPE_GATHER;
@@ -928,6 +926,20 @@ fix_outer_query_motions_mutator(Node *node, decorate_subplans_with_motions_conte
context->currentPlanFlow->flotype == FLOW_PARTITIONED)
{
motion->motionType = MOTIONTYPE_BROADCAST;
+ /*
+ * In cdbpathtoplan_create_motion_plan if locus is CdbLocusType_OuterQuery
+ * We use make_sorted_union_motion to keep the pathkeys of path.
+ * But, sendSorted of BroadCast motion can not be true.
+ * So make sort plan above broad cast motion to keep pathkeys.
+ */
+ if (motion->sendSorted)
+ {
+ motion->sendSorted = false;
+ newnode = (Node *)make_sort((Plan *)motion, motion->numSortCols,
+ motion->sortColIdx, motion->sortOperators,
+ motion->collations, motion->nullsFirst);
+ return newnode;
+ }
}
else
elog(ERROR, "unexpected Flow type in parent of a SubPlan");
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 55f90a6efc..6bc774e949 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -299,9 +299,6 @@ static MergeJoin *make_mergejoin(List *tlist,
Plan *lefttree, Plan *righttree,
JoinType jointype, bool inner_unique,
bool skip_mark_restore);
-static Sort *make_sort(Plan *lefttree, int numCols,
- AttrNumber *sortColIdx, Oid *sortOperators,
- Oid *collations, bool *nullsFirst);
static IncrementalSort *make_incrementalsort(Plan *lefttree,
int numCols, int nPresortedCols,
AttrNumber *sortColIdx, Oid *sortOperators,
@@ -7280,7 +7277,7 @@ make_mergejoin(List *tlist,
* Caller must have built the sortColIdx, sortOperators, collations, and
* nullsFirst arrays already.
*/
-static Sort *
+Sort *
make_sort(Plan *lefttree, int numCols,
AttrNumber *sortColIdx, Oid *sortOperators,
Oid *collations, bool *nullsFirst)
@@ -8746,13 +8743,9 @@ cdbpathtoplan_create_motion_plan(PlannerInfo *root,
hashOpfamilies,
numHashSegments);
}
- else if (CdbPathLocus_IsOuterQuery(path->path.locus))
- {
- motion = make_union_motion(subplan);
- motion->motionType = MOTIONTYPE_OUTER_QUERY;
- }
/* Send all tuples to a single process? */
- else if (CdbPathLocus_IsBottleneck(path->path.locus))
+ else if (CdbPathLocus_IsBottleneck(path->path.locus)
+ || CdbPathLocus_IsOuterQuery(path->path.locus))
{
if (path->path.pathkeys)
{
@@ -8807,6 +8800,13 @@ cdbpathtoplan_create_motion_plan(PlannerInfo *root,
{
motion = make_union_motion(subplan);
}
+ /*
+ * When path.locus is CdbLocusType_OuterQuery, We will miss the pathkeys
+ * if use make_union_motion. So use make_sorted_union_motion instead of
+ * make_union_motion if path has pathkeys.
+ */
+ if (CdbPathLocus_IsOuterQuery(path->path.locus))
+ motion->motionType = MOTIONTYPE_OUTER_QUERY;
}
/* Send all of the tuples to all of the QEs in gang above... */
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index cc01f0f4e6..b610bda56e 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -85,6 +85,9 @@ extern Plan *offload_entry_to_qe(PlannerInfo *root, Plan *plan, int sendslice_pa
/* External use of these functions is deprecated: */
extern Sort *make_sort_from_sortclauses(List *sortcls,
Plan *lefttree);
+extern Sort *make_sort(Plan *lefttree, int numCols,
+ AttrNumber *sortColIdx, Oid *sortOperators,
+ Oid *collations, bool *nullsFirst);
extern Agg *make_agg(List *tlist, List *qual,
AggStrategy aggstrategy, AggSplit aggsplit,
bool streaming,
diff --git a/src/test/regress/expected/subselect_gp.out b/src/test/regress/expected/subselect_gp.out
index 6c10081be5..67a166dd9c 100644
--- a/src/test/regress/expected/subselect_gp.out
+++ b/src/test/regress/expected/subselect_gp.out
@@ -3908,3 +3908,95 @@ select (select b from bar)[(select 1)][1:3] from bar;
(1 row)
drop table bar;
+create table outer_foo(a int primary key, b int);
+create table inner_bar(a int, b int) distributed randomly;
+insert into outer_foo values (generate_series(1,20), generate_series(11,30));
+insert into inner_bar values (generate_series(1,20), generate_series(25,44));
+set optimizer to off;
+explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Nested Loop
+ -> Gather Motion 3:1 (slice1; segments: 3)
+ Merge Key: t1.a
+ -> Index Scan using outer_foo_pkey on outer_foo t1
+ -> Materialize
+ -> HashAggregate
+ Group Key: t2.a
+ -> Result
+ Filter: (t1.b = t2.b)
+ -> Materialize
+ -> Gather Motion 3:1 (slice2; segments: 3)
+ -> Seq Scan on inner_bar t2
+ Optimizer: Postgres-based planner
+(13 rows)
+
+explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Nested Loop
+ -> Gather Motion 3:1 (slice1; segments: 3)
+ -> Seq Scan on outer_foo t1
+ -> Materialize
+ -> HashAggregate
+ Group Key: t2.a
+ -> Result
+ Filter: (t1.b = t2.b)
+ -> Materialize
+ -> Gather Motion 3:1 (slice2; segments: 3)
+ -> Seq Scan on inner_bar t2
+ Optimizer: Postgres-based planner
+(12 rows)
+
+select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1;
+ a
+----
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+(6 rows)
+
+create table t(a int, b int);
+NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
+HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
+explain (costs off) with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1)
+select * from t where a > (select count(1) from cte where x > t.a + random());
+ QUERY PLAN
+-----------------------------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ -> Seq Scan on t
+ Filter: (a > (SubPlan 1))
+ SubPlan 1
+ -> Aggregate
+ -> Result
+ Filter: ((t1.a)::double precision > ((t.a)::double precision + random()))
+ -> Nested Loop
+ -> Materialize
+ -> Sort
+ Sort Key: t1.a
+ -> Broadcast Motion 3:3 (slice2; segments: 3)
+ -> Index Scan using outer_foo_pkey on outer_foo t1
+ -> Materialize
+ -> HashAggregate
+ Group Key: t2.a
+ -> Result
+ Filter: (t1.b = t2.b)
+ -> Materialize
+ -> Broadcast Motion 3:3 (slice3; segments: 3)
+ -> Seq Scan on inner_bar t2
+ Optimizer: Postgres-based planner
+(22 rows)
+
+with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1)
+select * from t where a > (select count(1) from cte where x > t.a + random());
+ a | b
+---+---
+(0 rows)
+
+reset optimizer;
+drop table outer_foo;
+drop table inner_bar;
+drop table t;
diff --git a/src/test/regress/expected/subselect_gp_optimizer.out b/src/test/regress/expected/subselect_gp_optimizer.out
index d5dd311003..651b506836 100644
--- a/src/test/regress/expected/subselect_gp_optimizer.out
+++ b/src/test/regress/expected/subselect_gp_optimizer.out
@@ -4047,3 +4047,95 @@ select (select b from bar)[(select 1)][1:3] from bar;
(1 row)
drop table bar;
+create table outer_foo(a int primary key, b int);
+create table inner_bar(a int, b int) distributed randomly;
+insert into outer_foo values (generate_series(1,20), generate_series(11,30));
+insert into inner_bar values (generate_series(1,20), generate_series(25,44));
+set optimizer to off;
+explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Nested Loop
+ -> Gather Motion 3:1 (slice1; segments: 3)
+ Merge Key: t1.a
+ -> Index Scan using outer_foo_pkey on outer_foo t1
+ -> Materialize
+ -> HashAggregate
+ Group Key: t2.a
+ -> Result
+ Filter: (t1.b = t2.b)
+ -> Materialize
+ -> Gather Motion 3:1 (slice2; segments: 3)
+ -> Seq Scan on inner_bar t2
+ Optimizer: Postgres-based planner
+(13 rows)
+
+explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Nested Loop
+ -> Gather Motion 3:1 (slice1; segments: 3)
+ -> Seq Scan on outer_foo t1
+ -> Materialize
+ -> HashAggregate
+ Group Key: t2.a
+ -> Result
+ Filter: (t1.b = t2.b)
+ -> Materialize
+ -> Gather Motion 3:1 (slice2; segments: 3)
+ -> Seq Scan on inner_bar t2
+ Optimizer: Postgres-based planner
+(12 rows)
+
+select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1;
+ a
+----
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+(6 rows)
+
+create table t(a int, b int);
+NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
+HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
+explain (costs off) with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1)
+select * from t where a > (select count(1) from cte where x > t.a + random());
+ QUERY PLAN
+-----------------------------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ -> Seq Scan on t
+ Filter: (a > (SubPlan 1))
+ SubPlan 1
+ -> Aggregate
+ -> Result
+ Filter: ((t1.a)::double precision > ((t.a)::double precision + random()))
+ -> Nested Loop
+ -> Materialize
+ -> Sort
+ Sort Key: t1.a
+ -> Broadcast Motion 3:3 (slice2; segments: 3)
+ -> Index Scan using outer_foo_pkey on outer_foo t1
+ -> Materialize
+ -> HashAggregate
+ Group Key: t2.a
+ -> Result
+ Filter: (t1.b = t2.b)
+ -> Materialize
+ -> Broadcast Motion 3:3 (slice3; segments: 3)
+ -> Seq Scan on inner_bar t2
+ Optimizer: Postgres-based planner
+(22 rows)
+
+with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1)
+select * from t where a > (select count(1) from cte where x > t.a + random());
+ a | b
+---+---
+(0 rows)
+
+reset optimizer;
+drop table outer_foo;
+drop table inner_bar;
+drop table t;
diff --git a/src/test/regress/sql/subselect_gp.sql b/src/test/regress/sql/subselect_gp.sql
index 982a6ff88b..7bd2ecbd68 100644
--- a/src/test/regress/sql/subselect_gp.sql
+++ b/src/test/regress/sql/subselect_gp.sql
@@ -1491,5 +1491,25 @@ select (select b from bar)[1][1:3] from bar;
explain (costs off) select (select b from bar)[(select 1)][1:3] from bar;
select (select b from bar)[(select 1)][1:3] from bar;
-
drop table bar;
+
+create table outer_foo(a int primary key, b int);
+create table inner_bar(a int, b int) distributed randomly;
+insert into outer_foo values (generate_series(1,20), generate_series(11,30));
+insert into inner_bar values (generate_series(1,20), generate_series(25,44));
+set optimizer to off;
+explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1;
+explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q;
+select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1;
+
+create table t(a int, b int);
+explain (costs off) with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1)
+select * from t where a > (select count(1) from cte where x > t.a + random());
+
+with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1)
+select * from t where a > (select count(1) from cte where x > t.a + random());
+
+reset optimizer;
+drop table outer_foo;
+drop table inner_bar;
+drop table t;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org