mirror of https://github.com/citusdata/citus.git
Merge branch 'main' into circleci-gha-migration
commit
2700fb9ea3
|
@ -6,7 +6,7 @@ orbs:
|
|||
parameters:
|
||||
image_suffix:
|
||||
type: string
|
||||
default: '-v641cdcd'
|
||||
default: '-v87fd773'
|
||||
pg14_version:
|
||||
type: string
|
||||
default: '14.9'
|
||||
|
@ -15,10 +15,10 @@ parameters:
|
|||
default: '15.4'
|
||||
pg16_version:
|
||||
type: string
|
||||
default: '16rc1'
|
||||
default: '16.0'
|
||||
upgrade_pg_versions:
|
||||
type: string
|
||||
default: '14.9-15.4-16rc1'
|
||||
default: '14.9-15.4-16.0'
|
||||
style_checker_tools_version:
|
||||
type: string
|
||||
default: '0.8.18'
|
||||
|
|
|
@ -44,12 +44,22 @@ jobs:
|
|||
# For this reason, we need to use a "matrix" to generate names of
|
||||
# rpm images, e.g. citus/packaging:centos-7-pg12
|
||||
packaging_docker_image:
|
||||
- oraclelinux-7
|
||||
- oraclelinux-8
|
||||
- centos-7
|
||||
- almalinux-8
|
||||
- almalinux-9
|
||||
POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }}
|
||||
# Postgres removed support for CentOS 7 in PG 16. Below block is needed to
|
||||
# keep the build for CentOS 7 working for PG 14 and PG 15.
|
||||
# Once dependent systems drop support for Centos 7, we can remove this block.
|
||||
include:
|
||||
- packaging_docker_image: centos-7
|
||||
POSTGRES_VERSION: 14
|
||||
- packaging_docker_image: centos-7
|
||||
POSTGRES_VERSION: 15
|
||||
- packaging_docker_image: oraclelinux-7
|
||||
POSTGRES_VERSION: 14
|
||||
- packaging_docker_image: oraclelinux-7
|
||||
POSTGRES_VERSION: 15
|
||||
|
||||
container:
|
||||
image: citus/packaging:${{ matrix.packaging_docker_image }}-pg${{ matrix.POSTGRES_VERSION }}
|
||||
|
@ -125,7 +135,6 @@ jobs:
|
|||
- debian-bullseye-all
|
||||
- ubuntu-focal-all
|
||||
- ubuntu-jammy-all
|
||||
- ubuntu-kinetic-all
|
||||
|
||||
POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }}
|
||||
|
||||
|
|
52
CHANGELOG.md
52
CHANGELOG.md
|
@ -1,3 +1,55 @@
|
|||
### citus v12.1.0 (September 12, 2023) ###
|
||||
|
||||
* Adds support for PostgreSQL 16.0 (#7173)
|
||||
|
||||
* Add `citus_schema_move()` function which moves tables within a
|
||||
distributed schema to another node (#7180)
|
||||
|
||||
* Adds `citus_pause_node()` UDF that allows pausing the node with given id
|
||||
(#7089)
|
||||
|
||||
* Makes sure to enforce shard level colocation with the GUC
|
||||
`citus.enable_non_colocated_router_query_pushdown` (#7076)
|
||||
|
||||
* Allows creating reference / distributed-schema tables from local tables added
|
||||
to metadata and that use identity columns (#7131)
|
||||
|
||||
* Propagates `BUFFER_USAGE_LIMIT` option in `VACUUM` and `ANALYZE` (#7114)
|
||||
|
||||
* Propagates `PROCESS_MAIN`, `SKIP_DATABASE_STATS`, `ONLY_DATABASE_STATS`
|
||||
options in `VACUUM` (#7114)
|
||||
|
||||
* Propagates `GENERIC_PLAN` option in `EXPLAIN` (#7141)
|
||||
|
||||
* Propagates "rules" option in `CREATE COLLATION` (#7185)
|
||||
|
||||
* Propagates `GRANT`/ `REVOKE` for database privileges (#7109)
|
||||
|
||||
* Adds TRUNCATE trigger support on Citus foreign tables (#7170)
|
||||
|
||||
* Removes `pg_send_cancellation` (#7135)
|
||||
|
||||
* Prevents unnecessarily pulling the data into coordinator for some
|
||||
`INSERT .. SELECT` queries that target a single-shard group (#7077)
|
||||
|
||||
* Makes sure that rebalancer throws an error if replication factor is greater
|
||||
than the shard allowed node count. Also makes sure to avoid moving a shard
|
||||
to a node that it already exists on. (#7074)
|
||||
|
||||
* Fixes a bug that may appear during 2PC recovery when there are multiple
|
||||
databases (#7174)
|
||||
|
||||
* Fixes a bug that could cause `COPY` logic to skip data in case of
|
||||
out-of-memory (#7152)
|
||||
|
||||
* Fixes a bug that causes an unexpected error when adding a column with
|
||||
a `NULL` constraint (#7093)
|
||||
|
||||
* Fixes `PROCESS_TOAST` default value to `true` (#7122)
|
||||
|
||||
* Improves the error thrown when there is datatype mismatch in `MERGE ON`
|
||||
(#7081)
|
||||
|
||||
### citus v12.0.0 (July 11, 2023) ###
|
||||
|
||||
* Adds support for schema-based sharding.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for Citus 12.1devel.
|
||||
# Generated by GNU Autoconf 2.69 for Citus 12.2devel.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
|
@ -579,8 +579,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='Citus'
|
||||
PACKAGE_TARNAME='citus'
|
||||
PACKAGE_VERSION='12.1devel'
|
||||
PACKAGE_STRING='Citus 12.1devel'
|
||||
PACKAGE_VERSION='12.2devel'
|
||||
PACKAGE_STRING='Citus 12.2devel'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
@ -1262,7 +1262,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures Citus 12.1devel to adapt to many kinds of systems.
|
||||
\`configure' configures Citus 12.2devel to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1324,7 +1324,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of Citus 12.1devel:";;
|
||||
short | recursive ) echo "Configuration of Citus 12.2devel:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1429,7 +1429,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
Citus configure 12.1devel
|
||||
Citus configure 12.2devel
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -1912,7 +1912,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by Citus $as_me 12.1devel, which was
|
||||
It was created by Citus $as_me 12.2devel, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -5393,7 +5393,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by Citus $as_me 12.1devel, which was
|
||||
This file was extended by Citus $as_me 12.2devel, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -5455,7 +5455,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
Citus config.status 12.1devel
|
||||
Citus config.status 12.2devel
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# everyone needing autoconf installed, the resulting files are checked
|
||||
# into the SCM.
|
||||
|
||||
AC_INIT([Citus], [12.1devel])
|
||||
AC_INIT([Citus], [12.2devel])
|
||||
AC_COPYRIGHT([Copyright (c) Citus Data, Inc.])
|
||||
|
||||
# we'll need sed and awk for some of the version commands
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Columnar extension
|
||||
comment = 'Citus Columnar extension'
|
||||
default_version = '11.3-1'
|
||||
default_version = '12.2-1'
|
||||
module_pathname = '$libdir/citus_columnar'
|
||||
relocatable = false
|
||||
schema = pg_catalog
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
-- citus_columnar--11.3-1--12.2-1
|
|
@ -0,0 +1 @@
|
|||
-- citus_columnar--12.2-1--11.3-1
|
|
@ -1,6 +1,6 @@
|
|||
# Citus extension
|
||||
comment = 'Citus distributed database'
|
||||
default_version = '12.1-1'
|
||||
default_version = '12.2-1'
|
||||
module_pathname = '$libdir/citus'
|
||||
relocatable = false
|
||||
schema = pg_catalog
|
||||
|
|
|
@ -147,3 +147,98 @@ PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
|
|||
|
||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PreprocessAlterDatabaseStmt is executed before the statement is applied to the local
|
||||
* postgres instance.
|
||||
*
|
||||
* In this stage we can prepare the commands that need to be run on all workers to grant
|
||||
* on databases.
|
||||
*/
|
||||
List *
|
||||
PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext)
|
||||
{
|
||||
if (!ShouldPropagate())
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
|
||||
|
||||
EnsureCoordinator();
|
||||
|
||||
char *sql = DeparseTreeNode((Node *) stmt);
|
||||
|
||||
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||
(void *) sql,
|
||||
ENABLE_DDL_PROPAGATION);
|
||||
|
||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||
}
|
||||
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||
|
||||
/*
|
||||
* PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local
|
||||
* postgres instance.
|
||||
*
|
||||
* In this stage we can prepare the commands that need to be run on all workers to grant
|
||||
* on databases.
|
||||
*/
|
||||
List *
|
||||
PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext)
|
||||
{
|
||||
if (!ShouldPropagate())
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
AlterDatabaseRefreshCollStmt *stmt = castNode(AlterDatabaseRefreshCollStmt, node);
|
||||
|
||||
EnsureCoordinator();
|
||||
|
||||
char *sql = DeparseTreeNode((Node *) stmt);
|
||||
|
||||
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||
(void *) sql,
|
||||
ENABLE_DDL_PROPAGATION);
|
||||
|
||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local
|
||||
* postgres instance.
|
||||
*
|
||||
* In this stage we can prepare the commands that need to be run on all workers to grant
|
||||
* on databases.
|
||||
*/
|
||||
List *
|
||||
PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext)
|
||||
{
|
||||
if (!ShouldPropagate())
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
AlterDatabaseSetStmt *stmt = castNode(AlterDatabaseSetStmt, node);
|
||||
|
||||
EnsureCoordinator();
|
||||
|
||||
char *sql = DeparseTreeNode((Node *) stmt);
|
||||
|
||||
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||
(void *) sql,
|
||||
ENABLE_DDL_PROPAGATION);
|
||||
|
||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||
}
|
||||
|
|
|
@ -444,6 +444,42 @@ static DistributeObjectOps Database_Grant = {
|
|||
.markDistributed = false,
|
||||
};
|
||||
|
||||
static DistributeObjectOps Database_Alter = {
|
||||
.deparse = DeparseAlterDatabaseStmt,
|
||||
.qualify = NULL,
|
||||
.preprocess = PreprocessAlterDatabaseStmt,
|
||||
.postprocess = NULL,
|
||||
.objectType = OBJECT_DATABASE,
|
||||
.operationType = DIST_OPS_ALTER,
|
||||
.address = NULL,
|
||||
.markDistributed = false,
|
||||
};
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||
static DistributeObjectOps Database_RefreshColl = {
|
||||
.deparse = DeparseAlterDatabaseRefreshCollStmt,
|
||||
.qualify = NULL,
|
||||
.preprocess = PreprocessAlterDatabaseRefreshCollStmt,
|
||||
.postprocess = NULL,
|
||||
.objectType = OBJECT_DATABASE,
|
||||
.operationType = DIST_OPS_ALTER,
|
||||
.address = NULL,
|
||||
.markDistributed = false,
|
||||
};
|
||||
#endif
|
||||
|
||||
static DistributeObjectOps Database_Set = {
|
||||
.deparse = DeparseAlterDatabaseSetStmt,
|
||||
.qualify = NULL,
|
||||
.preprocess = PreprocessAlterDatabaseSetStmt,
|
||||
.postprocess = NULL,
|
||||
.objectType = OBJECT_DATABASE,
|
||||
.operationType = DIST_OPS_ALTER,
|
||||
.address = NULL,
|
||||
.markDistributed = false,
|
||||
};
|
||||
|
||||
|
||||
static DistributeObjectOps Domain_Alter = {
|
||||
.deparse = DeparseAlterDomainStmt,
|
||||
.qualify = QualifyAlterDomainStmt,
|
||||
|
@ -1272,7 +1308,6 @@ static DistributeObjectOps Trigger_Rename = {
|
|||
.markDistributed = false,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GetDistributeObjectOps looks up the DistributeObjectOps which handles the node.
|
||||
*
|
||||
|
@ -1283,6 +1318,25 @@ GetDistributeObjectOps(Node *node)
|
|||
{
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
case T_AlterDatabaseStmt:
|
||||
{
|
||||
return &Database_Alter;
|
||||
}
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||
case T_AlterDatabaseRefreshCollStmt:
|
||||
{
|
||||
return &Database_RefreshColl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
case T_AlterDatabaseSetStmt:
|
||||
{
|
||||
return &Database_Set;
|
||||
}
|
||||
|
||||
|
||||
case T_AlterDomainStmt:
|
||||
{
|
||||
return &Domain_Alter;
|
||||
|
|
|
@ -78,6 +78,7 @@ static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec
|
|||
static VariableSetStmt * MakeVariableSetStmt(const char *config);
|
||||
static int ConfigGenericNameCompare(const void *lhs, const void *rhs);
|
||||
static List * RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok);
|
||||
static bool IsGrantRoleWithInheritOrSetOption(GrantRoleStmt *stmt);
|
||||
|
||||
/* controlled via GUC */
|
||||
bool EnableCreateRolePropagation = true;
|
||||
|
@ -1141,6 +1142,19 @@ PreprocessGrantRoleStmt(Node *node, const char *queryString,
|
|||
return NIL;
|
||||
}
|
||||
|
||||
if (IsGrantRoleWithInheritOrSetOption(stmt))
|
||||
{
|
||||
if (EnableUnsupportedFeatureMessages)
|
||||
{
|
||||
ereport(NOTICE, (errmsg("not propagating GRANT/REVOKE commands with specified"
|
||||
" INHERIT/SET options to worker nodes"),
|
||||
errhint(
|
||||
"Connect to worker nodes directly to manually run the same"
|
||||
" GRANT/REVOKE command after disabling DDL propagation.")));
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Postgres don't seem to use the grantor. Even dropping the grantor doesn't
|
||||
* seem to affect the membership. If this changes, we might need to add grantors
|
||||
|
@ -1190,6 +1204,27 @@ PostprocessGrantRoleStmt(Node *node, const char *queryString)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsGrantRoleWithInheritOrSetOption returns true if the given
|
||||
* GrantRoleStmt has inherit or set option specified in its options
|
||||
*/
|
||||
static bool
|
||||
IsGrantRoleWithInheritOrSetOption(GrantRoleStmt *stmt)
|
||||
{
|
||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||
DefElem *opt = NULL;
|
||||
foreach_ptr(opt, stmt->opt)
|
||||
{
|
||||
if (strcmp(opt->defname, "inherit") == 0 || strcmp(opt->defname, "set") == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ConfigGenericNameCompare compares two config_generic structs based on their
|
||||
* name fields. If the name fields contain the same strings two structs are
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
#include "postgres.h"
|
||||
|
||||
#include "pg_version_compat.h"
|
||||
|
||||
#include "catalog/namespace.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
#include "distributed/deparser.h"
|
||||
#include "distributed/citus_ruleutils.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "distributed/log_utils.h"
|
||||
#include "parser/parse_type.h"
|
||||
#include "nodes/print.h"
|
||||
|
||||
|
||||
void AppendVarSetValue(StringInfo buf, VariableSetStmt *setStmt);
|
||||
|
||||
/*
|
||||
* AppendVarSetValueDb deparses a VariableSetStmt with VAR_SET_VALUE kind.
|
||||
* It takes from flatten_set_variable_args in postgres's utils/misc/guc.c,
|
||||
* however flatten_set_variable_args does not apply correct quoting.
|
||||
*/
|
||||
void
|
||||
AppendVarSetValue(StringInfo buf, VariableSetStmt *setStmt)
|
||||
{
|
||||
ListCell *varArgCell = NULL;
|
||||
ListCell *firstCell = list_head(setStmt->args);
|
||||
|
||||
Assert(setStmt->kind == VAR_SET_VALUE);
|
||||
|
||||
foreach(varArgCell, setStmt->args)
|
||||
{
|
||||
Node *varArgNode = lfirst(varArgCell);
|
||||
A_Const *varArgConst = NULL;
|
||||
TypeName *typeName = NULL;
|
||||
|
||||
if (IsA(varArgNode, A_Const))
|
||||
{
|
||||
varArgConst = (A_Const *) varArgNode;
|
||||
}
|
||||
else if (IsA(varArgNode, TypeCast))
|
||||
{
|
||||
TypeCast *varArgTypeCast = (TypeCast *) varArgNode;
|
||||
|
||||
varArgConst = castNode(A_Const, varArgTypeCast->arg);
|
||||
typeName = varArgTypeCast->typeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "unrecognized node type: %d", varArgNode->type);
|
||||
}
|
||||
|
||||
/* don't know how to start SET until we inspect first arg */
|
||||
if (varArgCell != firstCell)
|
||||
{
|
||||
appendStringInfoChar(buf, ',');
|
||||
}
|
||||
else if (typeName != NULL)
|
||||
{
|
||||
appendStringInfoString(buf, " SET TIME ZONE");
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(buf, " SET %s =", quote_identifier(setStmt->name));
|
||||
}
|
||||
|
||||
Node *value = (Node *) &varArgConst->val;
|
||||
switch (value->type)
|
||||
{
|
||||
case T_Integer:
|
||||
{
|
||||
appendStringInfo(buf, " %d", intVal(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case T_Float:
|
||||
{
|
||||
appendStringInfo(buf, " %s", nodeToString(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case T_String:
|
||||
{
|
||||
if (typeName != NULL)
|
||||
{
|
||||
/*
|
||||
* Must be a ConstInterval argument for TIME ZONE. Coerce
|
||||
* to interval and back to normalize the value and account
|
||||
* for any typmod.
|
||||
*/
|
||||
Oid typoid = InvalidOid;
|
||||
int32 typmod = -1;
|
||||
|
||||
typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
|
||||
Assert(typoid == INTERVALOID);
|
||||
|
||||
Datum interval =
|
||||
DirectFunctionCall3(interval_in,
|
||||
CStringGetDatum(strVal(value)),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(typmod));
|
||||
|
||||
char *intervalout =
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
interval));
|
||||
appendStringInfo(buf, " INTERVAL '%s'", intervalout);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(buf, " %s", quote_literal_cstr(strVal(value)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
elog(ERROR, "Unexpected Value type in VAR_SET_VALUE arguments.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AppendVariableSetDb appends a string representing the VariableSetStmt to a buffer
|
||||
*/
|
||||
void
|
||||
AppendVariableSet(StringInfo buf, VariableSetStmt *setStmt)
|
||||
{
|
||||
switch (setStmt->kind)
|
||||
{
|
||||
case VAR_SET_VALUE:
|
||||
{
|
||||
AppendVarSetValue(buf, setStmt);
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_SET_CURRENT:
|
||||
{
|
||||
appendStringInfo(buf, " SET %s FROM CURRENT", quote_identifier(
|
||||
setStmt->name));
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_SET_DEFAULT:
|
||||
{
|
||||
appendStringInfo(buf, " SET %s TO DEFAULT", quote_identifier(setStmt->name));
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_RESET:
|
||||
{
|
||||
appendStringInfo(buf, " RESET %s", quote_identifier(setStmt->name));
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_RESET_ALL:
|
||||
{
|
||||
appendStringInfoString(buf, " RESET ALL");
|
||||
break;
|
||||
}
|
||||
|
||||
/* VAR_SET_MULTI is a special case for SET TRANSACTION that should not occur here */
|
||||
case VAR_SET_MULTI:
|
||||
default:
|
||||
{
|
||||
ereport(ERROR, (errmsg("Unable to deparse SET statement")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,9 +20,15 @@
|
|||
|
||||
#include "distributed/deparser.h"
|
||||
#include "distributed/citus_ruleutils.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "distributed/deparser.h"
|
||||
#include "distributed/log_utils.h"
|
||||
#include "parser/parse_type.h"
|
||||
|
||||
|
||||
static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
|
||||
|
||||
static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt);
|
||||
static void AppendDefElemConnLimit(StringInfo buf, DefElem *def);
|
||||
|
||||
char *
|
||||
DeparseAlterDatabaseOwnerStmt(Node *node)
|
||||
|
@ -82,6 +88,52 @@ AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
AppendDefElemConnLimit(StringInfo buf, DefElem *def)
|
||||
{
|
||||
appendStringInfo(buf, " CONNECTION LIMIT %ld", (long int) defGetNumeric(def));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt)
|
||||
{
|
||||
appendStringInfo(buf, "ALTER DATABASE %s ", quote_identifier(stmt->dbname));
|
||||
|
||||
if (stmt->options)
|
||||
{
|
||||
ListCell *cell = NULL;
|
||||
appendStringInfo(buf, "WITH ");
|
||||
foreach(cell, stmt->options)
|
||||
{
|
||||
DefElem *def = castNode(DefElem, lfirst(cell));
|
||||
if (strcmp(def->defname, "is_template") == 0)
|
||||
{
|
||||
appendStringInfo(buf, "IS_TEMPLATE %s",
|
||||
quote_literal_cstr(strVal(def->arg)));
|
||||
}
|
||||
else if (strcmp(def->defname, "connection_limit") == 0)
|
||||
{
|
||||
AppendDefElemConnLimit(buf, def);
|
||||
}
|
||||
else if (strcmp(def->defname, "allow_connections") == 0)
|
||||
{
|
||||
ereport(ERROR,
|
||||
errmsg("ALLOW_CONNECTIONS is not supported"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport(ERROR,
|
||||
errmsg("unrecognized ALTER DATABASE option: %s",
|
||||
def->defname));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appendStringInfo(buf, ";");
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
DeparseGrantOnDatabaseStmt(Node *node)
|
||||
{
|
||||
|
@ -95,3 +147,61 @@ DeparseGrantOnDatabaseStmt(Node *node)
|
|||
|
||||
return str.data;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
DeparseAlterDatabaseStmt(Node *node)
|
||||
{
|
||||
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
|
||||
|
||||
StringInfoData str = { 0 };
|
||||
initStringInfo(&str);
|
||||
|
||||
AppendAlterDatabaseStmt(&str, stmt);
|
||||
|
||||
return str.data;
|
||||
}
|
||||
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||
char *
|
||||
DeparseAlterDatabaseRefreshCollStmt(Node *node)
|
||||
{
|
||||
AlterDatabaseRefreshCollStmt *stmt = (AlterDatabaseRefreshCollStmt *) node;
|
||||
|
||||
StringInfoData str;
|
||||
initStringInfo(&str);
|
||||
|
||||
appendStringInfo(&str, "ALTER DATABASE %s REFRESH COLLATION VERSION;",
|
||||
quote_identifier(
|
||||
stmt->dbname));
|
||||
|
||||
return str.data;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
AppendAlterDatabaseSetStmt(StringInfo buf, AlterDatabaseSetStmt *stmt)
|
||||
{
|
||||
appendStringInfo(buf, "ALTER DATABASE %s", quote_identifier(stmt->dbname));
|
||||
|
||||
VariableSetStmt *varSetStmt = castNode(VariableSetStmt, stmt->setstmt);
|
||||
|
||||
AppendVariableSet(buf, varSetStmt);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
DeparseAlterDatabaseSetStmt(Node *node)
|
||||
{
|
||||
AlterDatabaseSetStmt *stmt = castNode(AlterDatabaseSetStmt, node);
|
||||
|
||||
StringInfoData str = { 0 };
|
||||
initStringInfo(&str);
|
||||
|
||||
AppendAlterDatabaseSetStmt(&str, stmt);
|
||||
|
||||
return str.data;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ static void AppendDefElemRows(StringInfo buf, DefElem *def);
|
|||
static void AppendDefElemSet(StringInfo buf, DefElem *def);
|
||||
static void AppendDefElemSupport(StringInfo buf, DefElem *def);
|
||||
|
||||
static void AppendVarSetValue(StringInfo buf, VariableSetStmt *setStmt);
|
||||
static void AppendRenameFunctionStmt(StringInfo buf, RenameStmt *stmt);
|
||||
static void AppendAlterFunctionSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
|
||||
static void AppendAlterFunctionOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
|
||||
|
@ -300,164 +299,6 @@ AppendDefElemSupport(StringInfo buf, DefElem *def)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* AppendVariableSet appends a string representing the VariableSetStmt to a buffer
|
||||
*/
|
||||
void
|
||||
AppendVariableSet(StringInfo buf, VariableSetStmt *setStmt)
|
||||
{
|
||||
switch (setStmt->kind)
|
||||
{
|
||||
case VAR_SET_VALUE:
|
||||
{
|
||||
AppendVarSetValue(buf, setStmt);
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_SET_CURRENT:
|
||||
{
|
||||
appendStringInfo(buf, " SET %s FROM CURRENT", quote_identifier(
|
||||
setStmt->name));
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_SET_DEFAULT:
|
||||
{
|
||||
appendStringInfo(buf, " SET %s TO DEFAULT", quote_identifier(setStmt->name));
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_RESET:
|
||||
{
|
||||
appendStringInfo(buf, " RESET %s", quote_identifier(setStmt->name));
|
||||
break;
|
||||
}
|
||||
|
||||
case VAR_RESET_ALL:
|
||||
{
|
||||
appendStringInfoString(buf, " RESET ALL");
|
||||
break;
|
||||
}
|
||||
|
||||
/* VAR_SET_MULTI is a special case for SET TRANSACTION that should not occur here */
|
||||
case VAR_SET_MULTI:
|
||||
default:
|
||||
{
|
||||
ereport(ERROR, (errmsg("Unable to deparse SET statement")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AppendVarSetValue deparses a VariableSetStmt with VAR_SET_VALUE kind.
|
||||
* It takes from flatten_set_variable_args in postgres's utils/misc/guc.c,
|
||||
* however flatten_set_variable_args does not apply correct quoting.
|
||||
*/
|
||||
static void
|
||||
AppendVarSetValue(StringInfo buf, VariableSetStmt *setStmt)
|
||||
{
|
||||
ListCell *varArgCell = NULL;
|
||||
ListCell *firstCell = list_head(setStmt->args);
|
||||
|
||||
Assert(setStmt->kind == VAR_SET_VALUE);
|
||||
|
||||
foreach(varArgCell, setStmt->args)
|
||||
{
|
||||
Node *varArgNode = lfirst(varArgCell);
|
||||
A_Const *varArgConst = NULL;
|
||||
TypeName *typeName = NULL;
|
||||
|
||||
if (IsA(varArgNode, A_Const))
|
||||
{
|
||||
varArgConst = (A_Const *) varArgNode;
|
||||
}
|
||||
else if (IsA(varArgNode, TypeCast))
|
||||
{
|
||||
TypeCast *varArgTypeCast = (TypeCast *) varArgNode;
|
||||
|
||||
varArgConst = castNode(A_Const, varArgTypeCast->arg);
|
||||
typeName = varArgTypeCast->typeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "unrecognized node type: %d", varArgNode->type);
|
||||
}
|
||||
|
||||
/* don't know how to start SET until we inspect first arg */
|
||||
if (varArgCell != firstCell)
|
||||
{
|
||||
appendStringInfoChar(buf, ',');
|
||||
}
|
||||
else if (typeName != NULL)
|
||||
{
|
||||
appendStringInfoString(buf, " SET TIME ZONE");
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(buf, " SET %s =", quote_identifier(setStmt->name));
|
||||
}
|
||||
|
||||
Node *value = (Node *) &varArgConst->val;
|
||||
switch (value->type)
|
||||
{
|
||||
case T_Integer:
|
||||
{
|
||||
appendStringInfo(buf, " %d", intVal(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case T_Float:
|
||||
{
|
||||
appendStringInfo(buf, " %s", strVal(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case T_String:
|
||||
{
|
||||
if (typeName != NULL)
|
||||
{
|
||||
/*
|
||||
* Must be a ConstInterval argument for TIME ZONE. Coerce
|
||||
* to interval and back to normalize the value and account
|
||||
* for any typmod.
|
||||
*/
|
||||
Oid typoid = InvalidOid;
|
||||
int32 typmod = -1;
|
||||
|
||||
typenameTypeIdAndMod(NULL, typeName, &typoid, &typmod);
|
||||
Assert(typoid == INTERVALOID);
|
||||
|
||||
Datum interval =
|
||||
DirectFunctionCall3(interval_in,
|
||||
CStringGetDatum(strVal(value)),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(typmod));
|
||||
|
||||
char *intervalout =
|
||||
DatumGetCString(DirectFunctionCall1(interval_out,
|
||||
interval));
|
||||
appendStringInfo(buf, " INTERVAL '%s'", intervalout);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(buf, " %s", quote_literal_cstr(strVal(
|
||||
value)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
elog(ERROR, "Unexpected Value type in VAR_SET_VALUE arguments.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DeparseRenameFunctionStmt builds and returns a string representing the RenameStmt
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "pg_version_compat.h"
|
||||
|
||||
#include "commands/defrem.h"
|
||||
#include "distributed/citus_ruleutils.h"
|
||||
#include "distributed/deparser.h"
|
||||
#include "distributed/listutils.h"
|
||||
|
@ -384,7 +385,10 @@ AppendGrantWithAdminOption(StringInfo buf, GrantRoleStmt *stmt)
|
|||
DefElem *opt = NULL;
|
||||
foreach_ptr(opt, stmt->opt)
|
||||
{
|
||||
if (strcmp(opt->defname, "admin") == 0)
|
||||
bool admin_option = false;
|
||||
char *optval = defGetString(opt);
|
||||
if (strcmp(opt->defname, "admin") == 0 &&
|
||||
parse_bool(optval, &admin_option) && admin_option)
|
||||
{
|
||||
appendStringInfo(buf, " WITH ADMIN OPTION");
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
-- citus--12.1-1--12.2-1
|
||||
|
||||
-- bump version to 12.2-1
|
|
@ -0,0 +1,2 @@
|
|||
-- citus--12.2-1--12.1-1
|
||||
-- this is an empty downgrade path since citus--12.2-1--12.1-1.sql is empty for now
|
|
@ -223,6 +223,18 @@ extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address);
|
|||
extern List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext);
|
||||
|
||||
extern List * PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext);
|
||||
|
||||
extern List * PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext
|
||||
processUtilityContext);
|
||||
|
||||
|
||||
extern List * PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext);
|
||||
|
||||
|
||||
/* domain.c - forward declarations */
|
||||
extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool
|
||||
isPostprocess);
|
||||
|
|
|
@ -223,6 +223,10 @@ extern char * DeparseAlterExtensionStmt(Node *stmt);
|
|||
/* forward declarations for deparse_database_stmts.c */
|
||||
extern char * DeparseAlterDatabaseOwnerStmt(Node *node);
|
||||
extern char * DeparseGrantOnDatabaseStmt(Node *node);
|
||||
extern char * DeparseAlterDatabaseStmt(Node *node);
|
||||
extern char * DeparseAlterDatabaseRefreshCollStmt(Node *node);
|
||||
extern char * DeparseAlterDatabaseSetStmt(Node *node);
|
||||
|
||||
|
||||
/* forward declaration for deparse_publication_stmts.c */
|
||||
extern char * DeparseCreatePublicationStmt(Node *stmt);
|
||||
|
|
|
@ -46,6 +46,8 @@ get_guc_variables_compat(int *gucCount)
|
|||
#define object_ownercheck(a, b, c) object_ownercheck(a, b, c)
|
||||
#define object_aclcheck(a, b, c, d) object_aclcheck(a, b, c, d)
|
||||
|
||||
#define pgstat_fetch_stat_local_beentry(a) pgstat_get_local_beentry_by_index(a)
|
||||
|
||||
#else
|
||||
|
||||
#include "catalog/pg_class_d.h"
|
||||
|
|
|
@ -43,7 +43,7 @@ CITUS_ARBITRARY_TEST_DIR = "./tmp_citus_test"
|
|||
|
||||
MASTER = "master"
|
||||
# This should be updated when citus version changes
|
||||
MASTER_VERSION = "12.1"
|
||||
MASTER_VERSION = "12.2"
|
||||
|
||||
HOME = expanduser("~")
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
set citus.log_remote_commands = true;
|
||||
set citus.grep_remote_commands = '%ALTER DATABASE%';
|
||||
-- since ALLOW_CONNECTIONS alter option should be executed in a different database
|
||||
-- and since we don't have a multiple database support for now,
|
||||
-- this statement will get error
|
||||
alter database regression ALLOW_CONNECTIONS false;
|
||||
ERROR: ALLOW_CONNECTIONS is not supported
|
||||
alter database regression with CONNECTION LIMIT 100;
|
||||
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT 100;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT 100;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression with IS_TEMPLATE true CONNECTION LIMIT 50;
|
||||
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true' CONNECTION LIMIT 50;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true' CONNECTION LIMIT 50;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression with CONNECTION LIMIT -1;
|
||||
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT -1;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT -1;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression with IS_TEMPLATE true;
|
||||
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true';
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true';
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression with IS_TEMPLATE false;
|
||||
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'false';
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'false';
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
-- this statement will get error since we don't have a multiple database support for now
|
||||
alter database regression rename to regression2;
|
||||
ERROR: current database cannot be renamed
|
||||
alter database regression set default_transaction_read_only = true;
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only = 'true'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only = 'true'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set default_transaction_read_only = false;
|
||||
alter database regression set default_transaction_read_only from current;
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set default_transaction_read_only to DEFAULT;
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression RESET default_transaction_read_only;
|
||||
NOTICE: issuing ALTER DATABASE regression RESET default_transaction_read_only
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression RESET default_transaction_read_only
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression SET TIME ZONE '-7';
|
||||
NOTICE: issuing ALTER DATABASE regression SET timezone = '-7'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET timezone = '-7'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set TIME ZONE LOCAL;
|
||||
NOTICE: issuing ALTER DATABASE regression SET timezone TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET timezone TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set TIME ZONE DEFAULT;
|
||||
NOTICE: issuing ALTER DATABASE regression SET timezone TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET timezone TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression RESET TIME ZONE;
|
||||
NOTICE: issuing ALTER DATABASE regression RESET timezone
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression RESET timezone
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression SET TIME ZONE INTERVAL '-08:00' HOUR TO MINUTE;
|
||||
NOTICE: issuing ALTER DATABASE regression SET TIME ZONE INTERVAL '@ 8 hours ago'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET TIME ZONE INTERVAL '@ 8 hours ago'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression RESET TIME ZONE;
|
||||
NOTICE: issuing ALTER DATABASE regression RESET timezone
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression RESET timezone
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set default_transaction_isolation = 'serializable';
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_isolation = 'serializable'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_isolation = 'serializable'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set default_transaction_isolation = 'read committed';
|
||||
alter database regression set default_transaction_isolation from current;
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_isolation FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_isolation FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set default_transaction_isolation to DEFAULT;
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_isolation TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET default_transaction_isolation TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression RESET default_transaction_isolation;
|
||||
NOTICE: issuing ALTER DATABASE regression RESET default_transaction_isolation
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression RESET default_transaction_isolation
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set statement_timeout = 1000;
|
||||
NOTICE: issuing ALTER DATABASE regression SET statement_timeout = 1000
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET statement_timeout = 1000
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set statement_timeout = 2000;
|
||||
alter database regression set statement_timeout from current;
|
||||
NOTICE: issuing ALTER DATABASE regression SET statement_timeout FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET statement_timeout FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set statement_timeout to DEFAULT;
|
||||
NOTICE: issuing ALTER DATABASE regression SET statement_timeout TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET statement_timeout TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression RESET statement_timeout;
|
||||
NOTICE: issuing ALTER DATABASE regression RESET statement_timeout
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression RESET statement_timeout
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set lock_timeout = 1201.5;
|
||||
NOTICE: issuing ALTER DATABASE regression SET lock_timeout = 1201.5
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET lock_timeout = 1201.5
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set lock_timeout = 1202.5;
|
||||
alter database regression set lock_timeout from current;
|
||||
NOTICE: issuing ALTER DATABASE regression SET lock_timeout FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET lock_timeout FROM CURRENT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression set lock_timeout to DEFAULT;
|
||||
NOTICE: issuing ALTER DATABASE regression SET lock_timeout TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression SET lock_timeout TO DEFAULT
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
alter database regression RESET lock_timeout;
|
||||
NOTICE: issuing ALTER DATABASE regression RESET lock_timeout
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing ALTER DATABASE regression RESET lock_timeout
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set citus.log_remote_commands = false;
|
|
@ -639,11 +639,7 @@ SELECT pg_reload_conf();
|
|||
t
|
||||
(1 row)
|
||||
|
||||
SET client_min_messages TO ERROR;
|
||||
DROP SCHEMA "citus_split_test_schema" CASCADE;
|
||||
NOTICE: drop cascades to 4 other objects
|
||||
DETAIL: drop cascades to table citus_split_test_schema.sensors
|
||||
drop cascades to table citus_split_test_schema.reference_table
|
||||
drop cascades to table citus_split_test_schema.colocated_dist_table
|
||||
drop cascades to table citus_split_test_schema.table_with_index_rep_identity
|
||||
DROP ROLE test_shard_split_role;
|
||||
--END : Cleanup
|
||||
|
|
|
@ -1408,12 +1408,28 @@ SELECT * FROM multi_extension.print_extension_changes();
|
|||
| function citus_schema_move(regnamespace,text,integer,citus.shard_transfer_mode) void
|
||||
(5 rows)
|
||||
|
||||
-- Test downgrade to 12.1-1 from 12.2-1
|
||||
ALTER EXTENSION citus UPDATE TO '12.2-1';
|
||||
ALTER EXTENSION citus UPDATE TO '12.1-1';
|
||||
-- Should be empty result since upgrade+downgrade should be a no-op
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
previous_object | current_object
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
-- Snapshot of state at 12.2-1
|
||||
ALTER EXTENSION citus UPDATE TO '12.2-1';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
previous_object | current_object
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff;
|
||||
-- show running version
|
||||
SHOW citus.version;
|
||||
citus.version
|
||||
---------------------------------------------------------------------
|
||||
12.1devel
|
||||
12.2devel
|
||||
(1 row)
|
||||
|
||||
-- ensure no unexpected objects were created outside pg_catalog
|
||||
|
@ -1447,7 +1463,7 @@ DROP EXTENSION citus;
|
|||
DROP EXTENSION citus_columnar;
|
||||
CREATE EXTENSION citus VERSION '8.0-1';
|
||||
ERROR: specified version incompatible with loaded Citus library
|
||||
DETAIL: Loaded library requires 12.1, but 8.0-1 was specified.
|
||||
DETAIL: Loaded library requires 12.2, but 8.0-1 was specified.
|
||||
HINT: If a newer library is present, restart the database and try the command again.
|
||||
-- Test non-distributed queries work even in version mismatch
|
||||
SET citus.enable_version_checks TO 'false';
|
||||
|
@ -1492,7 +1508,7 @@ ORDER BY 1;
|
|||
-- We should not distribute table in version mistmatch
|
||||
SELECT create_distributed_table('version_mismatch_table', 'column1');
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
DETAIL: Loaded library requires 12.1, but the installed extension version is 8.1-1.
|
||||
DETAIL: Loaded library requires 12.2, but the installed extension version is 8.1-1.
|
||||
HINT: Run ALTER EXTENSION citus UPDATE and try again.
|
||||
-- This function will cause fail in next ALTER EXTENSION
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.relation_is_a_known_shard(regclass)
|
||||
|
|
|
@ -1523,6 +1523,13 @@ ORDER BY is_coordinator DESC, result;
|
|||
f | [{"indexdefs": ["CREATE UNIQUE INDEX referencing__key ON pg15.referencing USING btree (test_2)"], "indexnames": ["referencing__key"]}, {"indexdefs": ["CREATE UNIQUE INDEX referencing__key1 ON pg15.referencing USING btree (test_3) NULLS NOT DISTINCT"], "indexnames": ["referencing__key1"]}]
|
||||
(3 rows)
|
||||
|
||||
set citus.log_remote_commands = true;
|
||||
set citus.grep_remote_commands = '%ALTER DATABASE%';
|
||||
alter database regression REFRESH COLLATION VERSION;
|
||||
NOTICE: version has not changed
|
||||
NOTICE: issuing ALTER DATABASE regression REFRESH COLLATION VERSION;
|
||||
NOTICE: issuing ALTER DATABASE regression REFRESH COLLATION VERSION;
|
||||
set citus.log_remote_commands = false;
|
||||
-- Clean up
|
||||
\set VERBOSITY terse
|
||||
SET client_min_messages TO ERROR;
|
||||
|
|
|
@ -971,6 +971,133 @@ LEFT JOIN ref_table ON TRUE;
|
|||
1.19
|
||||
(1 row)
|
||||
|
||||
--
|
||||
-- PG16 added WITH ADMIN FALSE option to GRANT ROLE
|
||||
-- WITH ADMIN FALSE is the default, make sure we propagate correctly in Citus
|
||||
-- Relevant PG commit: https://github.com/postgres/postgres/commit/e3ce2de
|
||||
--
|
||||
CREATE ROLE role1;
|
||||
CREATE ROLE role2;
|
||||
SET citus.log_remote_commands TO on;
|
||||
SET citus.grep_remote_commands = '%GRANT%';
|
||||
-- default admin option is false
|
||||
GRANT role1 TO role2;
|
||||
NOTICE: issuing GRANT role1 TO role2;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing GRANT role1 TO role2;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
REVOKE role1 FROM role2;
|
||||
-- should behave same as default
|
||||
GRANT role1 TO role2 WITH ADMIN FALSE;
|
||||
NOTICE: issuing GRANT role1 TO role2;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing GRANT role1 TO role2;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
REVOKE role1 FROM role2;
|
||||
-- with admin option and with admin true are the same
|
||||
GRANT role1 TO role2 WITH ADMIN OPTION;
|
||||
NOTICE: issuing GRANT role1 TO role2 WITH ADMIN OPTION;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing GRANT role1 TO role2 WITH ADMIN OPTION;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH ADMIN TRUE;
|
||||
NOTICE: issuing GRANT role1 TO role2 WITH ADMIN OPTION;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing GRANT role1 TO role2 WITH ADMIN OPTION;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
REVOKE role1 FROM role2;
|
||||
RESET citus.log_remote_commands;
|
||||
RESET citus.grep_remote_commands;
|
||||
--
|
||||
-- PG16 added new options to GRANT ROLE
|
||||
-- inherit: https://github.com/postgres/postgres/commit/e3ce2de
|
||||
-- set: https://github.com/postgres/postgres/commit/3d14e17
|
||||
-- We don't propagate for now in Citus
|
||||
--
|
||||
GRANT role1 TO role2 WITH INHERIT FALSE;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH INHERIT TRUE;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH INHERIT OPTION;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH SET FALSE;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH SET TRUE;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH SET OPTION;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE role1 FROM role2;
|
||||
-- connect to worker node
|
||||
GRANT role1 TO role2 WITH ADMIN OPTION, INHERIT FALSE, SET FALSE;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text,
|
||||
admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
||||
role | member | admin_option | inherit_option | set_option
|
||||
---------------------------------------------------------------------
|
||||
role1 | role2 | t | f | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text,
|
||||
admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
||||
role | member | admin_option | inherit_option | set_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SET citus.enable_ddl_propagation TO off;
|
||||
GRANT role1 TO role2 WITH ADMIN OPTION, INHERIT FALSE, SET FALSE;
|
||||
RESET citus.enable_ddl_propagation;
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text,
|
||||
admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
||||
role | member | admin_option | inherit_option | set_option
|
||||
---------------------------------------------------------------------
|
||||
role1 | role2 | t | f | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
REVOKE role1 FROM role2;
|
||||
-- test REVOKES as well
|
||||
GRANT role1 TO role2;
|
||||
REVOKE SET OPTION FOR role1 FROM role2;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
REVOKE INHERIT OPTION FOR role1 FROM role2;
|
||||
NOTICE: not propagating GRANT/REVOKE commands with specified INHERIT/SET options to worker nodes
|
||||
HINT: Connect to worker nodes directly to manually run the same GRANT/REVOKE command after disabling DDL propagation.
|
||||
DROP ROLE role1, role2;
|
||||
-- test that everything works fine for roles that are not propagated
|
||||
SET citus.enable_ddl_propagation TO off;
|
||||
CREATE ROLE role3;
|
||||
CREATE ROLE role4;
|
||||
CREATE ROLE role5;
|
||||
RESET citus.enable_ddl_propagation;
|
||||
-- by default, admin option is false, inherit is true, set is true
|
||||
GRANT role3 TO role4;
|
||||
GRANT role3 TO role5 WITH ADMIN TRUE, INHERIT FALSE, SET FALSE;
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, admin_option, inherit_option, set_option FROM pg_auth_members WHERE roleid::regrole::text = 'role3' ORDER BY 1, 2;
|
||||
role | member | admin_option | inherit_option | set_option
|
||||
---------------------------------------------------------------------
|
||||
role3 | role4 | f | t | t
|
||||
role3 | role5 | t | f | f
|
||||
(2 rows)
|
||||
|
||||
DROP ROLE role3, role4, role5;
|
||||
\set VERBOSITY terse
|
||||
SET client_min_messages TO ERROR;
|
||||
DROP EXTENSION postgres_fdw CASCADE;
|
||||
|
|
|
@ -51,6 +51,7 @@ test: multi_metadata_attributes
|
|||
test: multi_read_from_secondaries
|
||||
|
||||
test: grant_on_database_propagation
|
||||
test: alter_database_propagation
|
||||
|
||||
# ----------
|
||||
# multi_citus_tools tests utility functions written for citus tools
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
set citus.log_remote_commands = true;
|
||||
set citus.grep_remote_commands = '%ALTER DATABASE%';
|
||||
|
||||
|
||||
-- since ALLOW_CONNECTIONS alter option should be executed in a different database
|
||||
-- and since we don't have a multiple database support for now,
|
||||
-- this statement will get error
|
||||
alter database regression ALLOW_CONNECTIONS false;
|
||||
|
||||
|
||||
alter database regression with CONNECTION LIMIT 100;
|
||||
alter database regression with IS_TEMPLATE true CONNECTION LIMIT 50;
|
||||
alter database regression with CONNECTION LIMIT -1;
|
||||
alter database regression with IS_TEMPLATE true;
|
||||
alter database regression with IS_TEMPLATE false;
|
||||
-- this statement will get error since we don't have a multiple database support for now
|
||||
alter database regression rename to regression2;
|
||||
|
||||
alter database regression set default_transaction_read_only = true;
|
||||
|
||||
set default_transaction_read_only = false;
|
||||
|
||||
alter database regression set default_transaction_read_only from current;
|
||||
alter database regression set default_transaction_read_only to DEFAULT;
|
||||
alter database regression RESET default_transaction_read_only;
|
||||
|
||||
alter database regression SET TIME ZONE '-7';
|
||||
|
||||
alter database regression set TIME ZONE LOCAL;
|
||||
alter database regression set TIME ZONE DEFAULT;
|
||||
alter database regression RESET TIME ZONE;
|
||||
|
||||
alter database regression SET TIME ZONE INTERVAL '-08:00' HOUR TO MINUTE;
|
||||
|
||||
alter database regression RESET TIME ZONE;
|
||||
|
||||
|
||||
alter database regression set default_transaction_isolation = 'serializable';
|
||||
set default_transaction_isolation = 'read committed';
|
||||
|
||||
alter database regression set default_transaction_isolation from current;
|
||||
alter database regression set default_transaction_isolation to DEFAULT;
|
||||
alter database regression RESET default_transaction_isolation;
|
||||
|
||||
alter database regression set statement_timeout = 1000;
|
||||
set statement_timeout = 2000;
|
||||
|
||||
alter database regression set statement_timeout from current;
|
||||
alter database regression set statement_timeout to DEFAULT;
|
||||
alter database regression RESET statement_timeout;
|
||||
|
||||
alter database regression set lock_timeout = 1201.5;
|
||||
set lock_timeout = 1202.5;
|
||||
|
||||
alter database regression set lock_timeout from current;
|
||||
alter database regression set lock_timeout to DEFAULT;
|
||||
alter database regression RESET lock_timeout;
|
||||
|
||||
set citus.log_remote_commands = false;
|
|
@ -317,6 +317,7 @@ SELECT run_command_on_workers($$SELECT count(*) FROM pg_subscription$$);
|
|||
|
||||
ALTER SYSTEM RESET citus.defer_shard_delete_interval;
|
||||
SELECT pg_reload_conf();
|
||||
SET client_min_messages TO ERROR;
|
||||
DROP SCHEMA "citus_split_test_schema" CASCADE;
|
||||
DROP ROLE test_shard_split_role;
|
||||
--END : Cleanup
|
||||
|
|
|
@ -634,6 +634,16 @@ SELECT * FROM multi_extension.print_extension_changes();
|
|||
ALTER EXTENSION citus UPDATE TO '12.1-1';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
-- Test downgrade to 12.1-1 from 12.2-1
|
||||
ALTER EXTENSION citus UPDATE TO '12.2-1';
|
||||
ALTER EXTENSION citus UPDATE TO '12.1-1';
|
||||
-- Should be empty result since upgrade+downgrade should be a no-op
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
-- Snapshot of state at 12.2-1
|
||||
ALTER EXTENSION citus UPDATE TO '12.2-1';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff;
|
||||
|
||||
-- show running version
|
||||
|
|
|
@ -965,6 +965,11 @@ SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
|
|||
JOIN pg_dist_node USING (nodeid)
|
||||
ORDER BY is_coordinator DESC, result;
|
||||
|
||||
set citus.log_remote_commands = true;
|
||||
set citus.grep_remote_commands = '%ALTER DATABASE%';
|
||||
alter database regression REFRESH COLLATION VERSION;
|
||||
set citus.log_remote_commands = false;
|
||||
|
||||
-- Clean up
|
||||
\set VERBOSITY terse
|
||||
SET client_min_messages TO ERROR;
|
||||
|
|
|
@ -565,6 +565,95 @@ SELECT PERCENTILE_DISC((2 > random_normal(stddev => 1, mean => 0))::int::numeric
|
|||
FROM dist_table
|
||||
LEFT JOIN ref_table ON TRUE;
|
||||
|
||||
--
|
||||
-- PG16 added WITH ADMIN FALSE option to GRANT ROLE
|
||||
-- WITH ADMIN FALSE is the default, make sure we propagate correctly in Citus
|
||||
-- Relevant PG commit: https://github.com/postgres/postgres/commit/e3ce2de
|
||||
--
|
||||
|
||||
CREATE ROLE role1;
|
||||
CREATE ROLE role2;
|
||||
|
||||
SET citus.log_remote_commands TO on;
|
||||
SET citus.grep_remote_commands = '%GRANT%';
|
||||
-- default admin option is false
|
||||
GRANT role1 TO role2;
|
||||
REVOKE role1 FROM role2;
|
||||
-- should behave same as default
|
||||
GRANT role1 TO role2 WITH ADMIN FALSE;
|
||||
REVOKE role1 FROM role2;
|
||||
-- with admin option and with admin true are the same
|
||||
GRANT role1 TO role2 WITH ADMIN OPTION;
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH ADMIN TRUE;
|
||||
REVOKE role1 FROM role2;
|
||||
|
||||
RESET citus.log_remote_commands;
|
||||
RESET citus.grep_remote_commands;
|
||||
|
||||
--
|
||||
-- PG16 added new options to GRANT ROLE
|
||||
-- inherit: https://github.com/postgres/postgres/commit/e3ce2de
|
||||
-- set: https://github.com/postgres/postgres/commit/3d14e17
|
||||
-- We don't propagate for now in Citus
|
||||
--
|
||||
GRANT role1 TO role2 WITH INHERIT FALSE;
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH INHERIT TRUE;
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH INHERIT OPTION;
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH SET FALSE;
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH SET TRUE;
|
||||
REVOKE role1 FROM role2;
|
||||
GRANT role1 TO role2 WITH SET OPTION;
|
||||
REVOKE role1 FROM role2;
|
||||
|
||||
-- connect to worker node
|
||||
GRANT role1 TO role2 WITH ADMIN OPTION, INHERIT FALSE, SET FALSE;
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text,
|
||||
admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text,
|
||||
admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
||||
|
||||
SET citus.enable_ddl_propagation TO off;
|
||||
GRANT role1 TO role2 WITH ADMIN OPTION, INHERIT FALSE, SET FALSE;
|
||||
RESET citus.enable_ddl_propagation;
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text,
|
||||
admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
||||
|
||||
\c - - - :master_port
|
||||
REVOKE role1 FROM role2;
|
||||
|
||||
-- test REVOKES as well
|
||||
GRANT role1 TO role2;
|
||||
REVOKE SET OPTION FOR role1 FROM role2;
|
||||
REVOKE INHERIT OPTION FOR role1 FROM role2;
|
||||
|
||||
DROP ROLE role1, role2;
|
||||
|
||||
-- test that everything works fine for roles that are not propagated
|
||||
SET citus.enable_ddl_propagation TO off;
|
||||
CREATE ROLE role3;
|
||||
CREATE ROLE role4;
|
||||
CREATE ROLE role5;
|
||||
RESET citus.enable_ddl_propagation;
|
||||
-- by default, admin option is false, inherit is true, set is true
|
||||
GRANT role3 TO role4;
|
||||
GRANT role3 TO role5 WITH ADMIN TRUE, INHERIT FALSE, SET FALSE;
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, admin_option, inherit_option, set_option FROM pg_auth_members WHERE roleid::regrole::text = 'role3' ORDER BY 1, 2;
|
||||
|
||||
DROP ROLE role3, role4, role5;
|
||||
|
||||
\set VERBOSITY terse
|
||||
SET client_min_messages TO ERROR;
|
||||
DROP EXTENSION postgres_fdw CASCADE;
|
||||
|
|
Loading…
Reference in New Issue