Merge branch 'main' into circleci-gha-migration

pull/7154/head
Gokhan Gulbiz 2023-09-20 10:31:34 +03:00 committed by GitHub
commit 2700fb9ea3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1049 additions and 189 deletions

View File

@ -6,7 +6,7 @@ orbs:
parameters: parameters:
image_suffix: image_suffix:
type: string type: string
default: '-v641cdcd' default: '-v87fd773'
pg14_version: pg14_version:
type: string type: string
default: '14.9' default: '14.9'
@ -15,10 +15,10 @@ parameters:
default: '15.4' default: '15.4'
pg16_version: pg16_version:
type: string type: string
default: '16rc1' default: '16.0'
upgrade_pg_versions: upgrade_pg_versions:
type: string type: string
default: '14.9-15.4-16rc1' default: '14.9-15.4-16.0'
style_checker_tools_version: style_checker_tools_version:
type: string type: string
default: '0.8.18' default: '0.8.18'

View File

@ -44,12 +44,22 @@ jobs:
# For this reason, we need to use a "matrix" to generate names of # For this reason, we need to use a "matrix" to generate names of
# rpm images, e.g. citus/packaging:centos-7-pg12 # rpm images, e.g. citus/packaging:centos-7-pg12
packaging_docker_image: packaging_docker_image:
- oraclelinux-7
- oraclelinux-8 - oraclelinux-8
- centos-7
- almalinux-8 - almalinux-8
- almalinux-9 - almalinux-9
POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }} 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: container:
image: citus/packaging:${{ matrix.packaging_docker_image }}-pg${{ matrix.POSTGRES_VERSION }} image: citus/packaging:${{ matrix.packaging_docker_image }}-pg${{ matrix.POSTGRES_VERSION }}
@ -125,7 +135,6 @@ jobs:
- debian-bullseye-all - debian-bullseye-all
- ubuntu-focal-all - ubuntu-focal-all
- ubuntu-jammy-all - ubuntu-jammy-all
- ubuntu-kinetic-all
POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }} POSTGRES_VERSION: ${{ fromJson(needs.get_postgres_versions_from_file.outputs.pg_versions) }}

View File

@ -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) ### ### citus v12.0.0 (July 11, 2023) ###
* Adds support for schema-based sharding. * Adds support for schema-based sharding.

18
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # 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. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='Citus' PACKAGE_NAME='Citus'
PACKAGE_TARNAME='citus' PACKAGE_TARNAME='citus'
PACKAGE_VERSION='12.1devel' PACKAGE_VERSION='12.2devel'
PACKAGE_STRING='Citus 12.1devel' PACKAGE_STRING='Citus 12.2devel'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' 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. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF 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]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1324,7 +1324,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of Citus 12.1devel:";; short | recursive ) echo "Configuration of Citus 12.2devel:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1429,7 +1429,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
Citus configure 12.1devel Citus configure 12.2devel
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -1912,7 +1912,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. 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 generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -5393,7 +5393,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" 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 generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -5455,7 +5455,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
Citus config.status 12.1devel Citus config.status 12.2devel
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -5,7 +5,7 @@
# everyone needing autoconf installed, the resulting files are checked # everyone needing autoconf installed, the resulting files are checked
# into the SCM. # into the SCM.
AC_INIT([Citus], [12.1devel]) AC_INIT([Citus], [12.2devel])
AC_COPYRIGHT([Copyright (c) Citus Data, Inc.]) AC_COPYRIGHT([Copyright (c) Citus Data, Inc.])
# we'll need sed and awk for some of the version commands # we'll need sed and awk for some of the version commands

View File

@ -1,6 +1,6 @@
# Columnar extension # Columnar extension
comment = 'Citus Columnar extension' comment = 'Citus Columnar extension'
default_version = '11.3-1' default_version = '12.2-1'
module_pathname = '$libdir/citus_columnar' module_pathname = '$libdir/citus_columnar'
relocatable = false relocatable = false
schema = pg_catalog schema = pg_catalog

View File

@ -0,0 +1 @@
-- citus_columnar--11.3-1--12.2-1

View File

@ -0,0 +1 @@
-- citus_columnar--12.2-1--11.3-1

View File

@ -1,6 +1,6 @@
# Citus extension # Citus extension
comment = 'Citus distributed database' comment = 'Citus distributed database'
default_version = '12.1-1' default_version = '12.2-1'
module_pathname = '$libdir/citus' module_pathname = '$libdir/citus'
relocatable = false relocatable = false
schema = pg_catalog schema = pg_catalog

View File

@ -147,3 +147,98 @@ PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); 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);
}

View File

@ -444,6 +444,42 @@ static DistributeObjectOps Database_Grant = {
.markDistributed = false, .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 = { static DistributeObjectOps Domain_Alter = {
.deparse = DeparseAlterDomainStmt, .deparse = DeparseAlterDomainStmt,
.qualify = QualifyAlterDomainStmt, .qualify = QualifyAlterDomainStmt,
@ -1272,7 +1308,6 @@ static DistributeObjectOps Trigger_Rename = {
.markDistributed = false, .markDistributed = false,
}; };
/* /*
* GetDistributeObjectOps looks up the DistributeObjectOps which handles the node. * GetDistributeObjectOps looks up the DistributeObjectOps which handles the node.
* *
@ -1283,6 +1318,25 @@ GetDistributeObjectOps(Node *node)
{ {
switch (nodeTag(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: case T_AlterDomainStmt:
{ {
return &Domain_Alter; return &Domain_Alter;

View File

@ -78,6 +78,7 @@ static const char * WrapQueryInAlterRoleIfExistsCall(const char *query, RoleSpec
static VariableSetStmt * MakeVariableSetStmt(const char *config); static VariableSetStmt * MakeVariableSetStmt(const char *config);
static int ConfigGenericNameCompare(const void *lhs, const void *rhs); static int ConfigGenericNameCompare(const void *lhs, const void *rhs);
static List * RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok); static List * RoleSpecToObjectAddress(RoleSpec *role, bool missing_ok);
static bool IsGrantRoleWithInheritOrSetOption(GrantRoleStmt *stmt);
/* controlled via GUC */ /* controlled via GUC */
bool EnableCreateRolePropagation = true; bool EnableCreateRolePropagation = true;
@ -1141,6 +1142,19 @@ PreprocessGrantRoleStmt(Node *node, const char *queryString,
return NIL; 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 * 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 * 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 * ConfigGenericNameCompare compares two config_generic structs based on their
* name fields. If the name fields contain the same strings two structs are * name fields. If the name fields contain the same strings two structs are

View File

@ -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;
}
}
}

View File

@ -20,9 +20,15 @@
#include "distributed/deparser.h" #include "distributed/deparser.h"
#include "distributed/citus_ruleutils.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 AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt);
static void AppendDefElemConnLimit(StringInfo buf, DefElem *def);
char * char *
DeparseAlterDatabaseOwnerStmt(Node *node) 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 * char *
DeparseGrantOnDatabaseStmt(Node *node) DeparseGrantOnDatabaseStmt(Node *node)
{ {
@ -95,3 +147,61 @@ DeparseGrantOnDatabaseStmt(Node *node)
return str.data; 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;
}

View File

@ -61,7 +61,6 @@ static void AppendDefElemRows(StringInfo buf, DefElem *def);
static void AppendDefElemSet(StringInfo buf, DefElem *def); static void AppendDefElemSet(StringInfo buf, DefElem *def);
static void AppendDefElemSupport(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 AppendRenameFunctionStmt(StringInfo buf, RenameStmt *stmt);
static void AppendAlterFunctionSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt); static void AppendAlterFunctionSchemaStmt(StringInfo buf, AlterObjectSchemaStmt *stmt);
static void AppendAlterFunctionOwnerStmt(StringInfo buf, AlterOwnerStmt *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 * DeparseRenameFunctionStmt builds and returns a string representing the RenameStmt
*/ */

View File

@ -15,6 +15,7 @@
#include "pg_version_compat.h" #include "pg_version_compat.h"
#include "commands/defrem.h"
#include "distributed/citus_ruleutils.h" #include "distributed/citus_ruleutils.h"
#include "distributed/deparser.h" #include "distributed/deparser.h"
#include "distributed/listutils.h" #include "distributed/listutils.h"
@ -384,7 +385,10 @@ AppendGrantWithAdminOption(StringInfo buf, GrantRoleStmt *stmt)
DefElem *opt = NULL; DefElem *opt = NULL;
foreach_ptr(opt, stmt->opt) 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"); appendStringInfo(buf, " WITH ADMIN OPTION");
break; break;

View File

@ -0,0 +1,3 @@
-- citus--12.1-1--12.2-1
-- bump version to 12.2-1

View File

@ -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

View File

@ -223,6 +223,18 @@ extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address);
extern List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, extern List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext); 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 */ /* domain.c - forward declarations */
extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool
isPostprocess); isPostprocess);

View File

@ -223,6 +223,10 @@ extern char * DeparseAlterExtensionStmt(Node *stmt);
/* forward declarations for deparse_database_stmts.c */ /* forward declarations for deparse_database_stmts.c */
extern char * DeparseAlterDatabaseOwnerStmt(Node *node); extern char * DeparseAlterDatabaseOwnerStmt(Node *node);
extern char * DeparseGrantOnDatabaseStmt(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 */ /* forward declaration for deparse_publication_stmts.c */
extern char * DeparseCreatePublicationStmt(Node *stmt); extern char * DeparseCreatePublicationStmt(Node *stmt);

View File

@ -46,6 +46,8 @@ get_guc_variables_compat(int *gucCount)
#define object_ownercheck(a, b, c) object_ownercheck(a, b, c) #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 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 #else
#include "catalog/pg_class_d.h" #include "catalog/pg_class_d.h"

View File

@ -43,7 +43,7 @@ CITUS_ARBITRARY_TEST_DIR = "./tmp_citus_test"
MASTER = "master" MASTER = "master"
# This should be updated when citus version changes # This should be updated when citus version changes
MASTER_VERSION = "12.1" MASTER_VERSION = "12.2"
HOME = expanduser("~") HOME = expanduser("~")

View File

@ -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;

View File

@ -639,11 +639,7 @@ SELECT pg_reload_conf();
t t
(1 row) (1 row)
SET client_min_messages TO ERROR;
DROP SCHEMA "citus_split_test_schema" CASCADE; 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; DROP ROLE test_shard_split_role;
--END : Cleanup --END : Cleanup

View File

@ -1408,12 +1408,28 @@ SELECT * FROM multi_extension.print_extension_changes();
| function citus_schema_move(regnamespace,text,integer,citus.shard_transfer_mode) void | function citus_schema_move(regnamespace,text,integer,citus.shard_transfer_mode) void
(5 rows) (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; DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff;
-- show running version -- show running version
SHOW citus.version; SHOW citus.version;
citus.version citus.version
--------------------------------------------------------------------- ---------------------------------------------------------------------
12.1devel 12.2devel
(1 row) (1 row)
-- ensure no unexpected objects were created outside pg_catalog -- ensure no unexpected objects were created outside pg_catalog
@ -1447,7 +1463,7 @@ DROP EXTENSION citus;
DROP EXTENSION citus_columnar; DROP EXTENSION citus_columnar;
CREATE EXTENSION citus VERSION '8.0-1'; CREATE EXTENSION citus VERSION '8.0-1';
ERROR: specified version incompatible with loaded Citus library 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. HINT: If a newer library is present, restart the database and try the command again.
-- Test non-distributed queries work even in version mismatch -- Test non-distributed queries work even in version mismatch
SET citus.enable_version_checks TO 'false'; SET citus.enable_version_checks TO 'false';
@ -1492,7 +1508,7 @@ ORDER BY 1;
-- We should not distribute table in version mistmatch -- We should not distribute table in version mistmatch
SELECT create_distributed_table('version_mismatch_table', 'column1'); SELECT create_distributed_table('version_mismatch_table', 'column1');
ERROR: loaded Citus library version differs from installed extension version 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. HINT: Run ALTER EXTENSION citus UPDATE and try again.
-- This function will cause fail in next ALTER EXTENSION -- This function will cause fail in next ALTER EXTENSION
CREATE OR REPLACE FUNCTION pg_catalog.relation_is_a_known_shard(regclass) CREATE OR REPLACE FUNCTION pg_catalog.relation_is_a_known_shard(regclass)

View File

@ -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"]}] 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) (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 -- Clean up
\set VERBOSITY terse \set VERBOSITY terse
SET client_min_messages TO ERROR; SET client_min_messages TO ERROR;

View File

@ -971,6 +971,133 @@ LEFT JOIN ref_table ON TRUE;
1.19 1.19
(1 row) (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 VERBOSITY terse
SET client_min_messages TO ERROR; SET client_min_messages TO ERROR;
DROP EXTENSION postgres_fdw CASCADE; DROP EXTENSION postgres_fdw CASCADE;

View File

@ -51,6 +51,7 @@ test: multi_metadata_attributes
test: multi_read_from_secondaries test: multi_read_from_secondaries
test: grant_on_database_propagation test: grant_on_database_propagation
test: alter_database_propagation
# ---------- # ----------
# multi_citus_tools tests utility functions written for citus tools # multi_citus_tools tests utility functions written for citus tools

View File

@ -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;

View File

@ -317,6 +317,7 @@ SELECT run_command_on_workers($$SELECT count(*) FROM pg_subscription$$);
ALTER SYSTEM RESET citus.defer_shard_delete_interval; ALTER SYSTEM RESET citus.defer_shard_delete_interval;
SELECT pg_reload_conf(); SELECT pg_reload_conf();
SET client_min_messages TO ERROR;
DROP SCHEMA "citus_split_test_schema" CASCADE; DROP SCHEMA "citus_split_test_schema" CASCADE;
DROP ROLE test_shard_split_role; DROP ROLE test_shard_split_role;
--END : Cleanup --END : Cleanup

View File

@ -634,6 +634,16 @@ SELECT * FROM multi_extension.print_extension_changes();
ALTER EXTENSION citus UPDATE TO '12.1-1'; ALTER EXTENSION citus UPDATE TO '12.1-1';
SELECT * FROM multi_extension.print_extension_changes(); 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; DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff;
-- show running version -- show running version

View File

@ -965,6 +965,11 @@ SELECT (groupid = 0) AS is_coordinator, result FROM run_command_on_all_nodes(
JOIN pg_dist_node USING (nodeid) JOIN pg_dist_node USING (nodeid)
ORDER BY is_coordinator DESC, result; 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 -- Clean up
\set VERBOSITY terse \set VERBOSITY terse
SET client_min_messages TO ERROR; SET client_min_messages TO ERROR;

View File

@ -565,6 +565,95 @@ SELECT PERCENTILE_DISC((2 > random_normal(stddev => 1, mean => 0))::int::numeric
FROM dist_table FROM dist_table
LEFT JOIN ref_table ON TRUE; 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 VERBOSITY terse
SET client_min_messages TO ERROR; SET client_min_messages TO ERROR;
DROP EXTENSION postgres_fdw CASCADE; DROP EXTENSION postgres_fdw CASCADE;