From 788e09a39aba40367241d92af4e2ab0d2950f3fd Mon Sep 17 00:00:00 2001 From: Jelte Fennema-Nio Date: Mon, 16 Oct 2023 11:38:24 +0200 Subject: [PATCH 01/63] Add a test for citus_shards where table names have spaces (#7224) There was a bug reported for previous versions of Citus where shard\_size was returning NULL for tables with spaces in them. It works fine on the main branch though, but I'm still adding a test for this to the main branch because it seems a good test to have. --- src/test/regress/citus_tests/run_test.py | 1 + src/test/regress/expected/citus_shards.out | 37 ++++++++++++++++++++++ src/test/regress/multi_1_schedule | 2 ++ src/test/regress/sql/citus_shards.sql | 17 ++++++++++ 4 files changed, 57 insertions(+) create mode 100644 src/test/regress/expected/citus_shards.out create mode 100644 src/test/regress/sql/citus_shards.sql diff --git a/src/test/regress/citus_tests/run_test.py b/src/test/regress/citus_tests/run_test.py index f1e1ec827..6528834ae 100755 --- a/src/test/regress/citus_tests/run_test.py +++ b/src/test/regress/citus_tests/run_test.py @@ -152,6 +152,7 @@ DEPS = { worker_count=6, ), "function_propagation": TestDeps("minimal_schedule"), + "citus_shards": TestDeps("minimal_schedule"), "grant_on_foreign_server_propagation": TestDeps("minimal_schedule"), "multi_modifying_xacts": TestDeps("minimal_schedule"), "multi_mx_modifying_xacts": TestDeps(None, ["multi_mx_create_table"]), diff --git a/src/test/regress/expected/citus_shards.out b/src/test/regress/expected/citus_shards.out new file mode 100644 index 000000000..b434a984b --- /dev/null +++ b/src/test/regress/expected/citus_shards.out @@ -0,0 +1,37 @@ +CREATE SCHEMA citus_shards; +SET search_path TO citus_shards; +SET citus.shard_count TO 4; +SET citus.shard_replication_factor TO 1; +SET citus.next_shard_id TO 99456900; +ALTER SEQUENCE pg_catalog.pg_dist_colocationid_seq RESTART 456900; +CREATE TABLE t1 (i int); +SELECT create_distributed_table('t1', 'i'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE "t with space" (i int); +SELECT create_distributed_table('"t with space"', 'i'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO t1 SELECT generate_series(1, 100); +INSERT INTO "t with space" SELECT generate_series(1, 1000); +SELECT * FROM citus_shards; + table_name | shardid | shard_name | citus_table_type | colocation_id | nodename | nodeport | shard_size +--------------------------------------------------------------------- + "t with space" | 99456904 | citus_shards."t with space_99456904" | distributed | 456900 | localhost | 57637 | 40960 + "t with space" | 99456905 | citus_shards."t with space_99456905" | distributed | 456900 | localhost | 57638 | 40960 + "t with space" | 99456906 | citus_shards."t with space_99456906" | distributed | 456900 | localhost | 57637 | 40960 + "t with space" | 99456907 | citus_shards."t with space_99456907" | distributed | 456900 | localhost | 57638 | 40960 + t1 | 99456900 | citus_shards.t1_99456900 | distributed | 456900 | localhost | 57637 | 8192 + t1 | 99456901 | citus_shards.t1_99456901 | distributed | 456900 | localhost | 57638 | 8192 + t1 | 99456902 | citus_shards.t1_99456902 | distributed | 456900 | localhost | 57637 | 8192 + t1 | 99456903 | citus_shards.t1_99456903 | distributed | 456900 | localhost | 57638 | 8192 +(8 rows) + +SET client_min_messages TO WARNING; +DROP SCHEMA citus_shards CASCADE; diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index 4dead5be3..ad70f136e 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -53,6 +53,8 @@ test: multi_read_from_secondaries test: grant_on_database_propagation test: alter_database_propagation +test: citus_shards + # ---------- # multi_citus_tools tests utility functions written for citus tools # ---------- diff --git a/src/test/regress/sql/citus_shards.sql b/src/test/regress/sql/citus_shards.sql new file mode 100644 index 000000000..9234ffd2e --- /dev/null +++ b/src/test/regress/sql/citus_shards.sql @@ -0,0 +1,17 @@ +CREATE SCHEMA citus_shards; +SET search_path TO citus_shards; +SET citus.shard_count TO 4; +SET citus.shard_replication_factor TO 1; +SET citus.next_shard_id TO 99456900; +ALTER SEQUENCE pg_catalog.pg_dist_colocationid_seq RESTART 456900; + +CREATE TABLE t1 (i int); +SELECT create_distributed_table('t1', 'i'); +CREATE TABLE "t with space" (i int); +SELECT create_distributed_table('"t with space"', 'i'); +INSERT INTO t1 SELECT generate_series(1, 100); +INSERT INTO "t with space" SELECT generate_series(1, 1000); +SELECT * FROM citus_shards; + +SET client_min_messages TO WARNING; +DROP SCHEMA citus_shards CASCADE; From 5eaf6c221e6c13b89c7e85c8d65ca7cd793dda92 Mon Sep 17 00:00:00 2001 From: Onur Tirtir Date: Mon, 16 Oct 2023 14:20:55 +0300 Subject: [PATCH 02/63] Fix flaky test detection job (#7256) We were getting such errors in flaky-test detection job: ``` Unable to process file command 'output' successfully ``` Even though we don't seem to be writing multiple lines to $GITHUB_OUTPUT, this seems to be the right fix. https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings --- .github/workflows/build_and_test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 90a4b1432..5944c38db 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -439,7 +439,10 @@ jobs: else echo "Detected tests " $tests fi - echo tests="$tests" >> "$GITHUB_OUTPUT" + + echo 'tests<> $GITHUB_OUTPUT + echo "$tests" >> "$GITHUB_OUTPUT" + echo 'EOF' >> $GITHUB_OUTPUT test-flakyness: if: ${{ needs.test-flakyness-pre.outputs.tests != ''}} name: Test flakyness From 0d5c2f9350a217494a66e3a4a7451340b00413af Mon Sep 17 00:00:00 2001 From: gindibay Date: Sat, 23 Sep 2023 01:50:23 +0300 Subject: [PATCH 03/63] Adds first commit --- src/backend/distributed/Makefile | 2 +- src/backend/distributed/commands/database.c | 239 ++++++ .../commands/distribute_object_ops.c | 31 + .../distributed/database/database_sharding.h | 53 ++ .../deparser/deparse_database_stmts.c | 208 ++++- .../distributed/sql/citus--12.1-1--12.2-1.sql | 11 + .../sql/downgrades/citus--12.2-1--12.1-1.sql | 1 + src/include/distributed/commands.h | 786 ++++++++---------- src/include/distributed/deparser.h | 3 + src/include/distributed/metadata/distobject.h | 1 + 10 files changed, 891 insertions(+), 444 deletions(-) create mode 100644 src/backend/distributed/database/database_sharding.h diff --git a/src/backend/distributed/Makefile b/src/backend/distributed/Makefile index 8f28b04b0..f4f9ffd86 100644 --- a/src/backend/distributed/Makefile +++ b/src/backend/distributed/Makefile @@ -18,7 +18,7 @@ generated_downgrade_sql_files += $(patsubst %,$(citus_abs_srcdir)/build/sql/%,$( DATA_built = $(generated_sql_files) # directories with source files -SUBDIRS = . commands connection ddl deparser executor metadata operations planner progress relay safeclib shardsplit test transaction utils worker clock +SUBDIRS = . commands connection database ddl deparser executor metadata operations planner progress relay safeclib shardsplit test transaction utils worker clock # enterprise modules SUBDIRS += replication diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 944ff627d..626234434 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -19,6 +19,7 @@ #include "miscadmin.h" #include "nodes/parsenodes.h" #include "utils/syscache.h" +#include "utils/builtins.h" #include "distributed/commands.h" #include "distributed/commands/utility_hook.h" @@ -28,13 +29,42 @@ #include "distributed/multi_executor.h" #include "distributed/relation_access_tracking.h" #include "distributed/worker_transaction.h" +#include "distributed/deparser.h" +#include "distributed/worker_protocol.h" +#include "distributed/metadata/distobject.h" +#include "distributed/database/database_sharding.h" +#include "distributed/deparse_shard_query.h" + + + +/* macros to add DefElems to a list */ +#define DEFELEM_ADD_STRING(options, key, value) { \ + DefElem *elem = makeDefElem(key, (Node *) makeString(value), -1); \ + options = lappend(options, elem); \ +} + +#define DEFELEM_ADD_BOOL(options, key, value) { \ + DefElem *elem = makeDefElem(key, (Node *) makeBoolean(value), -1); \ + options = lappend(options, elem); \ +} + +#define DEFELEM_ADD_INT(options, key, value) { \ + DefElem *elem = makeDefElem(key, (Node *) makeInteger(value), -1); \ + options = lappend(options, elem); \ +} static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid); + +static List * CreateDDLTaskList(char *command, List *workerNodeList, + bool outsideTransaction); + +PG_FUNCTION_INFO_V1(citus_internal_database_command); static Oid get_database_owner(Oid db_oid); List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); /* controlled via GUC */ +bool EnableCreateDatabasePropagation = true; bool EnableAlterDatabaseOwner = true; @@ -148,6 +178,78 @@ PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } +/* + * citus_internal_database_command is an internal UDF to + * create/drop a database in an idempotent maner without + * transaction block restrictions. + */ +Datum +citus_internal_database_command(PG_FUNCTION_ARGS) +{ + text *commandText = PG_GETARG_TEXT_P(0); + char *command = text_to_cstring(commandText); + Node *parseTree = ParseTreeNode(command); + + set_config_option("citus.enable_ddl_propagation", "off", + (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, + GUC_ACTION_LOCAL, true, 0, false); + + set_config_option("citus.enable_create_database_propagation", "off", + (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, + GUC_ACTION_LOCAL, true, 0, false); + + if (IsA(parseTree, CreatedbStmt)) + { + CreatedbStmt *stmt = castNode(CreatedbStmt, parseTree); + + bool missingOk = true; + Oid databaseOid = get_database_oid(stmt->dbname, missingOk); + + if (!OidIsValid(databaseOid)) + { + createdb(NULL, (CreatedbStmt *) parseTree); + } + else + { + /* TODO: check database properties */ + } + } + else if (IsA(parseTree, DropdbStmt)) + { + DropdbStmt *stmt = castNode(DropdbStmt, parseTree); + + bool missingOk = true; + Oid databaseOid = get_database_oid(stmt->dbname, missingOk); + + if (!OidIsValid(databaseOid)) + { + /* already dropped? */ + } + else + { + /* remove database from pg_dist_object */ + ObjectAddress dbAddress = { 0 }; + ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); + + if (IsObjectDistributed(&dbAddress)) + { + UnmarkObjectDistributed(&dbAddress); + } + + /* remove database from database shards */ + DeleteDatabaseShardByDatabaseIdLocally(databaseOid); + + DropDatabase(NULL, (DropdbStmt *) parseTree); + } + } + else + { + ereport(ERROR, (errmsg("unsupported command type %d", nodeTag(parseTree)))); + } + + PG_RETURN_VOID(); +} + /* * PreprocessAlterDatabaseStmt is executed before the statement is applied to the local @@ -213,6 +315,35 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString, #endif +/* + * CreateDDLTaskList creates a task list for running a single DDL command. + */ +static List * +CreateDDLTaskList(char *command, List *workerNodeList, bool outsideTransaction) +{ + List *commandList = list_make3(DISABLE_DDL_PROPAGATION, + command, + ENABLE_DDL_PROPAGATION); + + Task *task = CitusMakeNode(Task); + task->taskType = DDL_TASK; + SetTaskQueryStringList(task, commandList); + task->cannotBeExecutedInTransction = outsideTransaction; + + WorkerNode *workerNode = NULL; + foreach_ptr(workerNode, workerNodeList) + { + ShardPlacement *targetPlacement = CitusMakeNode(ShardPlacement); + targetPlacement->nodeName = workerNode->workerName; + targetPlacement->nodePort = workerNode->workerPort; + targetPlacement->groupId = workerNode->groupId; + task->taskPlacementList = lappend(task->taskPlacementList, + targetPlacement); + } + + return list_make1(task); +} + /* * PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local @@ -242,3 +373,111 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } + + +/* + * PostprocessCreatedbStmt creates the plan to synchronize CREATE DATABASE + * across nodes. We use the cannotBeExecutedInTransction option to avoid + * u* sending transaction blocks. + */ +List * +PostprocessCreateDatabaseStmt(Node *node, const char *queryString) +{ + if (!EnableCreateDatabasePropagation || !ShouldPropagate()) + { + return NIL; + } + + CreatedbStmt *stmt = castNode(CreatedbStmt, node); + char *databaseName = stmt->dbname; + bool missingOk = false; + Oid databaseOid = get_database_oid(databaseName, missingOk); + + /* + * TODO: try to reuse regular DDL infrastructure + * + * We do not do this right now because of the AssignDatabaseToShard at the end. + */ + List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, RowShareLock); + if (list_length(workerNodes) > 0) + { + char *createDatabaseCommand = DeparseTreeNode(node); + + StringInfo internalCreateCommand = makeStringInfo(); + appendStringInfo(internalCreateCommand, + "SELECT pg_catalog.citus_internal_database_command(%s)", + quote_literal_cstr(createDatabaseCommand)); + + /* + * For the moment, we run CREATE DATABASE in 2PC, though that prevents + * us from immediately doing a pg_dump | pg_restore when dealing with + * a remote template database. + */ + bool outsideTransaction = false; + + List *taskList = CreateDDLTaskList(internalCreateCommand->data, workerNodes, + outsideTransaction); + + bool localExecutionSupported = false; + ExecuteUtilityTaskList(taskList, localExecutionSupported); + } + + /* synchronize pg_dist_object records */ + ObjectAddress dbAddress = { 0 }; + ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); + MarkObjectDistributed(&dbAddress); + + + return NIL; +} + +List * +PreprocessDropDatabaseStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext) +{ + if (!EnableCreateDatabasePropagation || !ShouldPropagate()) + { + return NIL; + } + + DropdbStmt *stmt = (DropdbStmt *) node; + char *databaseName = stmt->dbname; + bool missingOk = true; + Oid databaseOid = get_database_oid(databaseName, missingOk); + if (databaseOid == InvalidOid) + { + /* let regular ProcessUtility deal with IF NOT EXISTS */ + return NIL; + } + + ObjectAddress dbAddress = { 0 }; + ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); + if (!IsObjectDistributed(&dbAddress)) + { + return NIL; + } + + List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, RowShareLock); + if (list_length(workerNodes) == 0) + { + return NIL; + } + + char *dropDatabaseCommand = DeparseTreeNode(node); + + StringInfo internalDropCommand = makeStringInfo(); + appendStringInfo(internalDropCommand, + "SELECT pg_catalog.citus_internal_database_command(%s)", + quote_literal_cstr(dropDatabaseCommand)); + + + /* we execute here to avoid EnsureCoordinator check in ExecuteDistributedDDLJob */ + bool outsideTransaction = false; + List *taskList = CreateDDLTaskList(internalDropCommand->data, workerNodes, + outsideTransaction); + + bool localExecutionSupported = false; + ExecuteUtilityTaskList(taskList, localExecutionSupported); + + return NIL; +} diff --git a/src/backend/distributed/commands/distribute_object_ops.c b/src/backend/distributed/commands/distribute_object_ops.c index a0a306e8d..7465a58cd 100644 --- a/src/backend/distributed/commands/distribute_object_ops.c +++ b/src/backend/distributed/commands/distribute_object_ops.c @@ -466,6 +466,28 @@ static DistributeObjectOps Database_Alter = { .markDistributed = false, }; +static DistributeObjectOps Database_Create = { + .deparse = DeparseCreateDatabaseStmt, + .qualify = NULL, + .preprocess = NULL, + .postprocess = PostprocessCreateDatabaseStmt, + .objectType = OBJECT_DATABASE, + .operationType = DIST_OPS_CREATE, + .address = NULL, + .markDistributed = false, +}; + +static DistributeObjectOps Database_Drop = { + .deparse = DeparseDropDatabaseStmt, + .qualify = NULL, + .preprocess = PreprocessDropDatabaseStmt, + .postprocess = NULL, + .objectType = OBJECT_DATABASE, + .operationType = DIST_OPS_DROP, + .address = NULL, + .markDistributed = false, +}; + #if PG_VERSION_NUM >= PG_VERSION_15 static DistributeObjectOps Database_RefreshColl = { .deparse = DeparseAlterDatabaseRefreshCollStmt, @@ -1333,6 +1355,15 @@ GetDistributeObjectOps(Node *node) { return &Database_Alter; } + case T_CreatedbStmt: + { + return &Database_Create; + } + + case T_DropdbStmt: + { + return &Database_Drop; + } #if PG_VERSION_NUM >= PG_VERSION_15 case T_AlterDatabaseRefreshCollStmt: diff --git a/src/backend/distributed/database/database_sharding.h b/src/backend/distributed/database/database_sharding.h new file mode 100644 index 000000000..390be1383 --- /dev/null +++ b/src/backend/distributed/database/database_sharding.h @@ -0,0 +1,53 @@ +/* + * database_sharding.h + * + * Data structure definition for managing backend data and related function + * + * Copyright (c) Microsoft, Inc. + */ + +#ifndef DATABASE_SHARDING_H +#define DATABASE_SHARDING_H + + +#include "tcop/utility.h" + + +/* attributes of citus_catalog.database_shard */ +#define Natts_database_shard 3 +#define Anum_database_shard_database_id 1 +#define Anum_database_shard_node_group_id 2 +#define Anum_database_shard_is_available 3 + + +typedef struct DatabaseShard +{ + /* database oid */ + Oid databaseOid; + + /* node group on which the database shard is placed */ + int nodeGroupId; + + /* whether the database shard is available */ + bool isAvailable; +} DatabaseShard; + +/* citus.enable_database_sharding setting */ +extern bool EnableDatabaseSharding; + +void PreProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, + ProcessUtilityContext context, + bool *runPreviousUtilityHook); +void PostProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, + ProcessUtilityContext context); +bool DatabaseShardingEnabled(void); +void AssignDatabaseToShard(Oid databaseOid); +void UpdateDatabaseShard(Oid databaseOid, int targetNodeGroupId); +void DeleteDatabaseShardByDatabaseIdLocally(Oid databaseOid); +DatabaseShard * GetDatabaseShardByOid(Oid databaseOid); +List * ListDatabaseShards(void); +int64 CitusDatabaseSize(Oid databaseId); +char * InsertDatabaseShardAssignmentCommand(Oid databaseOid, int nodeGroupId); + + +#endif diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index d3d3ce633..1247aba43 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -24,7 +24,7 @@ #include "distributed/deparser.h" #include "distributed/log_utils.h" #include "parser/parse_type.h" - +#include "distributed/listutils.h" static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt); static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt); @@ -34,7 +34,7 @@ char * DeparseAlterDatabaseOwnerStmt(Node *node) { AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); - StringInfoData str = { 0 }; + StringInfoData str = {0}; initStringInfo(&str); Assert(stmt->objectType == OBJECT_DATABASE); @@ -44,7 +44,6 @@ DeparseAlterDatabaseOwnerStmt(Node *node) return str.data; } - static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt) { @@ -52,18 +51,17 @@ AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt) appendStringInfo(buf, "ALTER DATABASE %s OWNER TO %s;", - quote_identifier(strVal((String *) stmt->object)), + quote_identifier(strVal((String *)stmt->object)), RoleSpecString(stmt->newowner, true)); } - static void AppendGrantDatabases(StringInfo buf, GrantStmt *stmt) { ListCell *cell = NULL; appendStringInfo(buf, " ON DATABASE "); - foreach(cell, stmt->objects) + foreach (cell, stmt->objects) { char *database = strVal(lfirst(cell)); appendStringInfoString(buf, quote_identifier(database)); @@ -74,7 +72,6 @@ AppendGrantDatabases(StringInfo buf, GrantStmt *stmt) } } - static void AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt) { @@ -87,14 +84,12 @@ AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt) AppendGrantSharedSuffix(buf, stmt); } - static void AppendDefElemConnLimit(StringInfo buf, DefElem *def) { - appendStringInfo(buf, " CONNECTION LIMIT %ld", (long int) defGetNumeric(def)); + appendStringInfo(buf, " CONNECTION LIMIT %ld", (long int)defGetNumeric(def)); } - static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) { @@ -104,7 +99,7 @@ AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) { ListCell *cell = NULL; appendStringInfo(buf, "WITH "); - foreach(cell, stmt->options) + foreach (cell, stmt->options) { DefElem *def = castNode(DefElem, lfirst(cell)); if (strcmp(def->defname, "is_template") == 0) @@ -133,14 +128,13 @@ AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) appendStringInfo(buf, ";"); } - char * DeparseGrantOnDatabaseStmt(Node *node) { GrantStmt *stmt = castNode(GrantStmt, node); Assert(stmt->objtype == OBJECT_DATABASE); - StringInfoData str = { 0 }; + StringInfoData str = {0}; initStringInfo(&str); AppendGrantOnDatabaseStmt(&str, stmt); @@ -148,13 +142,12 @@ DeparseGrantOnDatabaseStmt(Node *node) return str.data; } - char * DeparseAlterDatabaseStmt(Node *node) { AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node); - StringInfoData str = { 0 }; + StringInfoData str = {0}; initStringInfo(&str); AppendAlterDatabaseStmt(&str, stmt); @@ -162,12 +155,11 @@ DeparseAlterDatabaseStmt(Node *node) return str.data; } - #if PG_VERSION_NUM >= PG_VERSION_15 char * DeparseAlterDatabaseRefreshCollStmt(Node *node) { - AlterDatabaseRefreshCollStmt *stmt = (AlterDatabaseRefreshCollStmt *) node; + AlterDatabaseRefreshCollStmt *stmt = (AlterDatabaseRefreshCollStmt *)node; StringInfoData str; initStringInfo(&str); @@ -179,7 +171,6 @@ DeparseAlterDatabaseRefreshCollStmt(Node *node) return str.data; } - #endif static void @@ -192,16 +183,193 @@ AppendAlterDatabaseSetStmt(StringInfo buf, AlterDatabaseSetStmt *stmt) AppendVariableSet(buf, varSetStmt); } - char * DeparseAlterDatabaseSetStmt(Node *node) { AlterDatabaseSetStmt *stmt = castNode(AlterDatabaseSetStmt, node); - StringInfoData str = { 0 }; + StringInfoData str = {0}; initStringInfo(&str); AppendAlterDatabaseSetStmt(&str, stmt); return str.data; } + +char * +DeparseCreateDatabaseSetStmt(Node *node) +{ + CreatedbStmt *stmt = castNode(CreatedbStmt, node); + StringInfoData str = {0}; + initStringInfo(&str); + + AppendCreatedbStmt(&str, stmt); + + return str.data; +} + +static void +AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) +{ + appendStringInfo(buf, + "CREATE DATABASE %s", + quote_identifier(stmt->dbname)); + + DefElem *option = NULL; + + foreach_ptr(option, stmt->options) + { + if (strcmp(option->defname, "tablespace") == 0) + { + char *tablespaceName = defGetString(option); + + appendStringInfo(buf, " TABLESPACE %s", + quote_identifier(tablespaceName)); + } + else if (strcmp(option->defname, "owner") == 0) + { + char *owner = defGetString(option); + + appendStringInfo(buf, " OWNER %s", + quote_identifier(owner)); + } + else if (strcmp(option->defname, "template") == 0) + { + char *template = defGetString(option); + + appendStringInfo(buf, " TEMPLATE %s", + quote_identifier(template)); + } + else if (strcmp(option->defname, "encoding") == 0) + { + char *encoding = defGetString(option); + + appendStringInfo(buf, " ENCODING %s", + quote_literal_cstr(encoding)); + } + else if (strcmp(option->defname, "locale") == 0) + { + char *locale = defGetString(option); + + appendStringInfo(buf, " LOCALE %s", + quote_literal_cstr(locale)); + } + else if (strcmp(option->defname, "lc_collate") == 0) + { + char *lc_collate = defGetString(option); + + appendStringInfo(buf, " LC_COLLATE %s", + quote_literal_cstr(lc_collate)); + } + else if (strcmp(option->defname, "lc_ctype") == 0) + { + char *lc_ctype = defGetString(option); + + appendStringInfo(buf, " LC_CTYPE %s", + quote_literal_cstr(lc_ctype)); + } + else if (strcmp(option->defname, "icu_locale") == 0) + { + char *icuLocale = defGetString(option); + + appendStringInfo(buf, " ICU_LOCALE %s", + quote_literal_cstr(icuLocale)); + } + else if (strcmp(option->defname, "locale_provider") == 0) + { + char *localeProvider = defGetString(option); + + appendStringInfo(buf, " LOCALE_PROVIDER %s", + quote_literal_cstr(localeProvider)); + } + else if (strcmp(option->defname, "is_template") == 0) + { + bool isTemplate = defGetBoolean(option); + + appendStringInfo(buf, " IS_TEMPLATE %s", + isTemplate ? "true" : "false"); + } + else if (strcmp(option->defname, "allow_connections") == 0) + { + bool allowConnections = defGetBoolean(option); + + appendStringInfo(buf, " ALLOW_CONNECTIONS %s", + allowConnections ? "true" : "false"); + } + else if (strcmp(option->defname, "connection_limit") == 0) + { + int connectionLimit = defGetInt32(option); + + appendStringInfo(buf, " CONNECTION_LIMIT %d", connectionLimit); + } +#if PG_VERSION_NUM >= PG_VERSION_15 + else if (strcmp(option->defname, "collation_version") == 0) + { + char *collationVersion = defGetString(option); + + appendStringInfo(buf, " COLLATION_VERSION %s", + quote_literal_cstr(collationVersion)); + } + else if (strcmp(option->defname, "oid") == 0) + { + Oid objectId = defGetObjectId(option); + + appendStringInfo(buf, " OID %d", objectId); + } + else if (strcmp(option->defname, "strategy") == 0) + { + char *strategy = defGetString(option); + + appendStringInfo(buf, " STRATEGY %s", + quote_literal_cstr(strategy)); + } +#endif + else if (strcmp(option->defname, "location") == 0) + { + /* deprecated option */ + } + else + { + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized CREATE DATABASE option \"%s\"", + option->defname))); + } + } +} + +char * +DeparseDropDatabaseStmt(Node *node) +{ + DropdbStmt *stmt = castNode(DropdbStmt, node); + StringInfoData str = { 0 }; + initStringInfo(&str); + + AppendDropDatabaseStmt(&str, stmt); + + return str.data; +} + + +static void +AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt) +{ + appendStringInfo(buf, + "DROP DATABASE %s", + quote_identifier(stmt->dbname)); + + DefElem *option = NULL; + + foreach_ptr(option, stmt->options) + { + if (strcmp(option->defname, "force") == 0) + { + appendStringInfo(buf, " FORCE"); + } + else + { + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized DROP DATABASE option \"%s\"", + option->defname))); + } + } +} diff --git a/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql b/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql index ec4cc7134..94814c48b 100644 --- a/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql +++ b/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql @@ -1,5 +1,16 @@ -- citus--12.1-1--12.2-1 +/* + * citus_internal_database_command creates a database according to the given command. + */ +CREATE OR REPLACE FUNCTION pg_catalog.citus_internal_database_command(command text) + RETURNS void + LANGUAGE C + STRICT +AS 'MODULE_PATHNAME', $$citus_internal_database_command$$; +COMMENT ON FUNCTION pg_catalog.citus_internal_database_command(text) IS + 'run a database command without transaction block restrictions'; + -- bump version to 12.2-1 #include "udfs/citus_add_rebalance_strategy/12.2-1.sql" diff --git a/src/backend/distributed/sql/downgrades/citus--12.2-1--12.1-1.sql b/src/backend/distributed/sql/downgrades/citus--12.2-1--12.1-1.sql index 93d121a12..a8ca092c4 100644 --- a/src/backend/distributed/sql/downgrades/citus--12.2-1--12.1-1.sql +++ b/src/backend/distributed/sql/downgrades/citus--12.2-1--12.1-1.sql @@ -1,3 +1,4 @@ -- citus--12.2-1--12.1-1 +DROP FUNCTION pg_catalog.citus_internal_database_command(text); #include "../udfs/citus_add_rebalance_strategy/10.1-1.sql" diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 43429278f..6b764dfbb 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -22,7 +22,6 @@ #include "tcop/utility.h" #include "utils/acl.h" - extern bool AddAllLocalTablesToMetadata; extern bool EnableSchemaBasedSharding; @@ -43,11 +42,11 @@ extern bool EnforceLocalObjectRestrictions; extern void SwitchToSequentialAndLocalExecutionIfRelationNameTooLong(Oid relationId, char * - finalRelationName); + finalRelationName); extern void SwitchToSequentialAndLocalExecutionIfPartitionNameTooLong(Oid - parentRelationId, + parentRelationId, Oid - partitionRelationId); + partitionRelationId); /* DistOpsOperationType to be used in DistributeObjectOps */ typedef enum DistOpsOperationType @@ -58,7 +57,6 @@ typedef enum DistOpsOperationType DIST_OPS_DROP, } DistOpsOperationType; - /* * DistributeObjectOps specifies handlers for node/object type pairs. * Instances of this type should all be declared in deparse.c. @@ -79,11 +77,11 @@ typedef enum DistOpsOperationType */ typedef struct DistributeObjectOps { - char * (*deparse)(Node *); + char *(*deparse)(Node *); void (*qualify)(Node *); - List * (*preprocess)(Node *, const char *, ProcessUtilityContext); - List * (*postprocess)(Node *, const char *); - List * (*address)(Node *, bool, bool); + List *(*preprocess)(Node *, const char *, ProcessUtilityContext); + List *(*postprocess)(Node *, const char *); + List *(*address)(Node *, bool, bool); bool markDistributed; /* fields used by common implementations, omitted for specialized implementations */ @@ -101,7 +99,7 @@ typedef struct DistributeObjectOps #define CITUS_TRUNCATE_TRIGGER_NAME "citus_truncate_trigger" -const DistributeObjectOps * GetDistributeObjectOps(Node *node); +const DistributeObjectOps *GetDistributeObjectOps(Node *node); /* * Flags that can be passed to GetForeignKeyOids to indicate @@ -140,7 +138,6 @@ typedef enum ExtractForeignKeyConstraintsMode INCLUDE_SINGLE_SHARD_TABLES } ExtractForeignKeyConstraintMode; - /* * Flags that can be passed to GetForeignKeyIdsForColumn to * indicate whether relationId argument should match: @@ -159,7 +156,6 @@ typedef enum SearchForeignKeyColumnFlags /* callers can also pass union of above flags */ } SearchForeignKeyColumnFlags; - typedef enum TenantOperation { TENANT_UNDISTRIBUTE_TABLE = 0, @@ -176,113 +172,101 @@ extern const char *TenantOperationNames[TOTAL_TENANT_OPERATION]; extern void SaveBeginCommandProperties(TransactionStmt *transactionStmt); /* cluster.c - forward declarations */ -extern List * PreprocessClusterStmt(Node *node, const char *clusterCommand, - ProcessUtilityContext processUtilityContext); +extern List *PreprocessClusterStmt(Node *node, const char *clusterCommand, + ProcessUtilityContext processUtilityContext); /* common.c - forward declarations*/ -extern List * PostprocessCreateDistributedObjectFromCatalogStmt(Node *stmt, - const char *queryString); -extern List * PreprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString); -extern List * PreprocessDropDistributedObjectStmt(Node *node, const char *queryString, +extern List *PostprocessCreateDistributedObjectFromCatalogStmt(Node *stmt, + const char *queryString); +extern List *PreprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString, ProcessUtilityContext - processUtilityContext); -extern List * DropTextSearchConfigObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * DropTextSearchDictObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); + processUtilityContext); +extern List *PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString); +extern List *PreprocessDropDistributedObjectStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *DropTextSearchConfigObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *DropTextSearchDictObjectAddress(Node *node, bool missing_ok, bool isPostprocess); /* index.c */ typedef void (*PGIndexProcessor)(Form_pg_index, List **, int); - /* call.c */ extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest); - /* collation.c - forward declarations */ -extern char * CreateCollationDDL(Oid collationId); -extern List * CreateCollationDDLsIdempotent(Oid collationId); -extern List * AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * AlterCollationSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address); -extern List * DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); +extern char *CreateCollationDDL(Oid collationId); +extern List *CreateCollationDDLsIdempotent(Oid collationId); +extern List *AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *AlterCollationSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern char *GenerateBackupNameForCollationCollision(const ObjectAddress *address); +extern List *DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); /* database.c - forward declarations */ -extern List * AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * DatabaseOwnerDDLCommands(const ObjectAddress *address); +extern List *AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *DatabaseOwnerDDLCommands(const ObjectAddress *address); -extern List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, +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); -extern List * PreprocessAlterDatabaseStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List *PostprocessCreateDatabaseStmt(Node *node, const char *queryString); +extern List *PreprocessDropDatabaseStmt(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); -extern List * AlterDomainStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * DomainRenameConstraintStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * RenameDomainStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid); + /* domain.c - forward declarations */ + extern List *CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterDomainStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *DomainRenameConstraintStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *RenameDomainStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern CreateDomainStmt *RecreateDomainStmt(Oid domainOid); extern Oid get_constraint_typid(Oid conoid); - /* extension.c - forward declarations */ extern bool IsDropCitusExtensionStmt(Node *parsetree); -extern List * GetDependentFDWsToExtension(Oid extensionId); +extern List *GetDependentFDWsToExtension(Oid extensionId); extern bool IsCreateAlterExtensionUpdateCitusStmt(Node *parsetree); extern void PreprocessCreateExtensionStmtForCitusColumnar(Node *parsetree); extern void PreprocessAlterExtensionCitusStmtForCitusColumnar(Node *parsetree); extern void PostprocessAlterExtensionCitusStmtForCitusColumnar(Node *parsetree); extern bool ShouldMarkRelationDistributed(Oid relationId); extern void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree); -extern List * PostprocessCreateExtensionStmt(Node *stmt, const char *queryString); -extern List * PreprocessDropExtensionStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessAlterExtensionSchemaStmt(Node *stmt, - const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * PostprocessAlterExtensionSchemaStmt(Node *stmt, - const char *queryString); -extern List * PreprocessAlterExtensionUpdateStmt(Node *stmt, - const char *queryString, - ProcessUtilityContext - processUtilityContext); +extern List *PostprocessCreateExtensionStmt(Node *stmt, const char *queryString); +extern List *PreprocessDropExtensionStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PreprocessAlterExtensionSchemaStmt(Node *stmt, + const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *PostprocessAlterExtensionSchemaStmt(Node *stmt, + const char *queryString); +extern List *PreprocessAlterExtensionUpdateStmt(Node *stmt, + const char *queryString, + ProcessUtilityContext + processUtilityContext); extern void PostprocessAlterExtensionCitusUpdateStmt(Node *node); -extern List * PreprocessAlterExtensionContentsStmt(Node *node, - const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress); -extern List * AlterExtensionSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * AlterExtensionUpdateStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); +extern List *PreprocessAlterExtensionContentsStmt(Node *node, + const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *CreateExtensionDDLCommand(const ObjectAddress *extensionAddress); +extern List *AlterExtensionSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *AlterExtensionUpdateStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); extern void CreateExtensionWithVersion(char *extname, char *extVersion); extern void AlterExtensionUpdateStmt(char *extname, char *extVersion); extern int GetExtensionVersionNumber(char *extVersion); @@ -301,21 +285,21 @@ extern void ErrorOutForFKeyBetweenPostgresAndCitusLocalTable(Oid localTableId); extern bool ColumnReferencedByAnyForeignKey(char *columnName, Oid relationId); extern bool ColumnAppearsInForeignKey(char *columnName, Oid relationId); extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid - relationId); -extern List * GetReferencingForeignConstaintCommands(Oid relationOid); -extern List * GetForeignConstraintToReferenceTablesCommands(Oid relationId); -extern List * GetForeignConstraintFromOtherReferenceTablesCommands(Oid relationId); -extern List * GetForeignConstraintToDistributedTablesCommands(Oid relationId); -extern List * GetForeignConstraintFromDistributedTablesCommands(Oid relationId); -extern List * GetForeignConstraintCommandsInternal(Oid relationId, int flags); + relationId); +extern List *GetReferencingForeignConstaintCommands(Oid relationOid); +extern List *GetForeignConstraintToReferenceTablesCommands(Oid relationId); +extern List *GetForeignConstraintFromOtherReferenceTablesCommands(Oid relationId); +extern List *GetForeignConstraintToDistributedTablesCommands(Oid relationId); +extern List *GetForeignConstraintFromDistributedTablesCommands(Oid relationId); +extern List *GetForeignConstraintCommandsInternal(Oid relationId, int flags); extern Oid DropFKeysAndUndistributeTable(Oid relationId); extern void DropFKeysRelationInvolvedWithTableType(Oid relationId, int tableTypeFlag); -extern List * GetFKeyCreationCommandsRelationInvolvedWithTableType(Oid relationId, - int tableTypeFlag); +extern List *GetFKeyCreationCommandsRelationInvolvedWithTableType(Oid relationId, + int tableTypeFlag); extern bool AnyForeignKeyDependsOnIndex(Oid indexId); extern bool HasForeignKeyWithLocalTable(Oid relationId); extern bool HasForeignKeyToReferenceTable(Oid relationOid); -extern List * GetForeignKeysFromLocalTables(Oid relationId); +extern List *GetForeignKeysFromLocalTables(Oid relationId); extern bool TableReferenced(Oid relationOid); extern bool TableReferencing(Oid relationOid); extern bool ConstraintIsAUniquenessConstraint(char *inputConstaintName, Oid relationId); @@ -324,297 +308,269 @@ extern bool ConstraintWithNameIsOfType(char *inputConstaintName, Oid relationId, char targetConstraintType); extern bool ConstraintWithIdIsOfType(Oid constraintId, char targetConstraintType); extern bool TableHasExternalForeignKeys(Oid relationId); -extern List * GetForeignKeyOids(Oid relationId, int flags); +extern List *GetForeignKeyOids(Oid relationId, int flags); extern Oid GetReferencedTableId(Oid foreignKeyId); extern Oid GetReferencingTableId(Oid foreignKeyId); extern bool RelationInvolvedInAnyNonInheritedForeignKeys(Oid relationId); - /* foreign_data_wrapper.c - forward declarations */ -extern List * PreprocessGrantOnFDWStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern Acl * GetPrivilegesForFDW(Oid FDWOid); - +extern List *PreprocessGrantOnFDWStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern Acl *GetPrivilegesForFDW(Oid FDWOid); /* foreign_server.c - forward declarations */ -extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * AlterForeignServerOwnerStmtObjectAddress(Node *node, bool - missing_ok, bool isPostprocess); -extern List * GetForeignServerCreateDDLCommand(Oid serverId); - +extern List *PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *GetForeignServerCreateDDLCommand(Oid serverId); /* foreign_table.c - forward declarations */ -extern List * PreprocessAlterForeignTableSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); - +extern List *PreprocessAlterForeignTableSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); /* function.c - forward declarations */ -extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessCreateFunctionStmt(Node *stmt, - const char *queryString); -extern List * CreateFunctionStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * DefineAggregateStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString, +extern List *PreprocessCreateFunctionStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List * AlterFunctionStmtObjectAddress(Node *stmt, +extern List *PostprocessCreateFunctionStmt(Node *stmt, + const char *queryString); +extern List *CreateFunctionStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List * RenameFunctionStmtObjectAddress(Node *stmt, +extern List *DefineAggregateStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List * AlterFunctionOwnerObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * AlterFunctionSchemaStmtObjectAddress(Node *stmt, +extern List *PreprocessAlterFunctionStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *AlterFunctionStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *RenameFunctionStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *AlterFunctionOwnerObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *AlterFunctionSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *PreprocessAlterFunctionDependsStmt(Node *stmt, + const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *AlterFunctionDependsStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List * PreprocessAlterFunctionDependsStmt(Node *stmt, - const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * AlterFunctionDependsStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessGrantOnFunctionStmt(Node *node, const char *queryString); - +extern List *PreprocessGrantOnFunctionStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessGrantOnFunctionStmt(Node *node, const char *queryString); /* grant.c - forward declarations */ -extern List * PreprocessGrantStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List *PreprocessGrantStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void deparsePrivileges(StringInfo privsString, GrantStmt *grantStmt); extern void deparseGrantees(StringInfo granteesString, GrantStmt *grantStmt); - /* index.c - forward declarations */ extern bool IsIndexRenameStmt(RenameStmt *renameStmt); -extern List * PreprocessIndexStmt(Node *createIndexStatement, - const char *createIndexCommand, - ProcessUtilityContext processUtilityContext); -extern char * ChooseIndexName(const char *tabname, Oid namespaceId, - List *colnames, List *exclusionOpNames, - bool primary, bool isconstraint); -extern char * ChooseIndexNameAddition(List *colnames); -extern List * ChooseIndexColumnNames(List *indexElems); +extern List *PreprocessIndexStmt(Node *createIndexStatement, + const char *createIndexCommand, + ProcessUtilityContext processUtilityContext); +extern char *ChooseIndexName(const char *tabname, Oid namespaceId, + List *colnames, List *exclusionOpNames, + bool primary, bool isconstraint); +extern char *ChooseIndexNameAddition(List *colnames); +extern List *ChooseIndexColumnNames(List *indexElems); extern LOCKMODE GetCreateIndexRelationLockMode(IndexStmt *createIndexStatement); -extern List * PreprocessReindexStmt(Node *ReindexStatement, - const char *ReindexCommand, - ProcessUtilityContext processUtilityContext); -extern List * ReindexStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List * PreprocessDropIndexStmt(Node *dropIndexStatement, - const char *dropIndexCommand, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessIndexStmt(Node *node, - const char *queryString); +extern List *PreprocessReindexStmt(Node *ReindexStatement, + const char *ReindexCommand, + ProcessUtilityContext processUtilityContext); +extern List *ReindexStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *PreprocessDropIndexStmt(Node *dropIndexStatement, + const char *dropIndexCommand, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessIndexStmt(Node *node, + const char *queryString); extern void ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement); extern void MarkIndexValid(IndexStmt *indexStmt); -extern List * ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor - pgIndexProcessor, int flags); +extern List *ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor pgIndexProcessor, int flags); extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName); /* objectaddress.c - forward declarations */ -extern List * CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); +extern List *CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); /* owned.c - forward declarations */ -extern List * PreprocessDropOwnedStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List *PreprocessDropOwnedStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); /* policy.c - forward declarations */ -extern List * CreatePolicyCommands(Oid relationId); +extern List *CreatePolicyCommands(Oid relationId); extern void ErrorIfUnsupportedPolicy(Relation relation); extern void ErrorIfUnsupportedPolicyExpr(Node *expr); -extern List * PostprocessCreatePolicyStmt(Node *node, const char *queryString); -extern List * PreprocessAlterPolicyStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessDropPolicyStmt(Node *stmt, const char *queryString, +extern List *PostprocessCreatePolicyStmt(Node *node, const char *queryString); +extern List *PreprocessAlterPolicyStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); +extern List *PreprocessDropPolicyStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); extern bool IsPolicyRenameStmt(RenameStmt *stmt); extern void CreatePolicyEventExtendNames(CreatePolicyStmt *stmt, const char *schemaName, uint64 shardId); extern void AlterPolicyEventExtendNames(AlterPolicyStmt *stmt, const char *schemaName, uint64 shardId); -extern void RenamePolicyEventExtendNames(RenameStmt *stmt, const char *schemaName, uint64 - shardId); -extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, uint64 - shardId); +extern void RenamePolicyEventExtendNames(RenameStmt *stmt, const char *schemaName, uint64 shardId); +extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, uint64 shardId); extern void AddRangeTableEntryToQueryCompat(ParseState *parseState, Relation relation); /* publication.c - forward declarations */ -extern List * PostProcessCreatePublicationStmt(Node *node, const char *queryString); -extern List * CreatePublicationDDLCommandsIdempotent(const ObjectAddress *address); -extern char * CreatePublicationDDLCommand(Oid publicationId); -extern List * PreprocessAlterPublicationStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityCtx); -extern List * GetAlterPublicationDDLCommandsForTable(Oid relationId, bool isAdd); -extern char * GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId, - bool isAdd); -extern List * AlterPublicationOwnerStmtObjectAddress(Node *node, bool missingOk, - bool isPostProcess); -extern List * AlterPublicationStmtObjectAddress(Node *node, bool missingOk, +extern List *PostProcessCreatePublicationStmt(Node *node, const char *queryString); +extern List *CreatePublicationDDLCommandsIdempotent(const ObjectAddress *address); +extern char *CreatePublicationDDLCommand(Oid publicationId); +extern List *PreprocessAlterPublicationStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityCtx); +extern List *GetAlterPublicationDDLCommandsForTable(Oid relationId, bool isAdd); +extern char *GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId, + bool isAdd); +extern List *AlterPublicationOwnerStmtObjectAddress(Node *node, bool missingOk, + bool isPostProcess); +extern List *AlterPublicationStmtObjectAddress(Node *node, bool missingOk, + bool isPostProcess); +extern List *CreatePublicationStmtObjectAddress(Node *node, bool missingOk, + bool isPostProcess); +extern List *RenamePublicationStmtObjectAddress(Node *node, bool missingOk, bool isPostProcess); -extern List * CreatePublicationStmtObjectAddress(Node *node, bool missingOk, - bool isPostProcess); -extern List * RenamePublicationStmtObjectAddress(Node *node, bool missingOk, - bool isPostProcess); /* rename.c - forward declarations*/ -extern List * PreprocessRenameStmt(Node *renameStmt, const char *renameCommand, - ProcessUtilityContext processUtilityContext); +extern List *PreprocessRenameStmt(Node *renameStmt, const char *renameCommand, + ProcessUtilityContext processUtilityContext); extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt); -extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); - +extern List *PreprocessRenameAttributeStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); /* role.c - forward declarations*/ -extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString); -extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List *PostprocessAlterRoleStmt(Node *stmt, const char *queryString); +extern List *PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); extern List * PreprocessAlterRoleRenameStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List * GenerateAlterRoleSetCommandForRole(Oid roleid); -extern List * AlterRoleStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List * AlterRoleSetStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List * PreprocessCreateRoleStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessDropRoleStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessGrantRoleStmt(Node *stmt, const char *queryString, +extern List *GenerateAlterRoleSetCommandForRole(Oid roleid); +extern List *AlterRoleStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterRoleSetStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *PreprocessCreateRoleStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString); -extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid); -extern List * CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); +extern List *PreprocessDropRoleStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PreprocessGrantRoleStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessGrantRoleStmt(Node *stmt, const char *queryString); +extern List *GenerateCreateOrAlterRoleCommand(Oid roleOid); +extern List *CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); extern List * RenameRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); extern void UnmarkRolesDistributed(List *roles); -extern List * FilterDistributedRoles(List *roles); +extern List *FilterDistributedRoles(List *roles); /* schema.c - forward declarations */ -extern List * PostprocessCreateSchemaStmt(Node *node, const char *queryString); -extern List * PreprocessDropSchemaStmt(Node *dropSchemaStatement, - const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt, - const char *alterObjectSchemaCommand); -extern List * PreprocessGrantOnSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * CreateSchemaStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * AlterSchemaOwnerStmtObjectAddress(Node *node, bool missing_ok, - bool isPostprocess); -extern List * AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); +extern List *PostprocessCreateSchemaStmt(Node *node, const char *queryString); +extern List *PreprocessDropSchemaStmt(Node *dropSchemaStatement, + const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt, + const char *alterObjectSchemaCommand); +extern List *PreprocessGrantOnSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *CreateSchemaStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterSchemaOwnerStmtObjectAddress(Node *node, bool missing_ok, + bool isPostprocess); +extern List *AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); /* sequence.c - forward declarations */ -extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * PostprocessAlterSequenceSchemaStmt(Node *node, const char *queryString); -extern List * PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString); -#if (PG_VERSION_NUM >= PG_VERSION_15) -extern List * PreprocessAlterSequencePersistenceStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * PreprocessSequenceAlterTableStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -#endif -extern List * PreprocessDropSequenceStmt(Node *node, const char *queryString, +extern List *PreprocessAlterSequenceStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List * SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * PreprocessRenameSequenceStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessGrantOnSequenceStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessGrantOnSequenceStmt(Node *node, const char *queryString); -extern List * AlterSequenceStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); +extern List *PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *PostprocessAlterSequenceSchemaStmt(Node *node, const char *queryString); +extern List *PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString); #if (PG_VERSION_NUM >= PG_VERSION_15) -extern List * AlterSequencePersistenceStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); +extern List *PreprocessAlterSequencePersistenceStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *PreprocessSequenceAlterTableStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); #endif -extern List * RenameSequenceStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); +extern List *PreprocessDropSequenceStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *PreprocessRenameSequenceStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PreprocessGrantOnSequenceStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessGrantOnSequenceStmt(Node *node, const char *queryString); +extern List *AlterSequenceStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +#if (PG_VERSION_NUM >= PG_VERSION_15) +extern List *AlterSequencePersistenceStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +#endif +extern List *RenameSequenceStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt); extern void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt); -extern char * GenerateBackupNameForSequenceCollision(const ObjectAddress *address); +extern char *GenerateBackupNameForSequenceCollision(const ObjectAddress *address); extern void RenameExistingSequenceWithDifferentTypeIfExists(RangeVar *sequence, Oid desiredSeqTypeId); /* statistics.c - forward declarations */ -extern List * PreprocessCreateStatisticsStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessCreateStatisticsStmt(Node *node, const char *queryString); -extern List * CreateStatisticsStmtObjectAddress(Node *node, bool missingOk, bool - isPostprocess); -extern List * PreprocessDropStatisticsStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * DropStatisticsObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List * PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); -extern List * AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk, bool - isPostprocess); -extern List * PreprocessAlterStatisticsStmt(Node *node, const char *queryString, +extern List *PreprocessCreateStatisticsStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString, +extern List *PostprocessCreateStatisticsStmt(Node *node, const char *queryString); +extern List *CreateStatisticsStmtObjectAddress(Node *node, bool missingOk, bool isPostprocess); +extern List *PreprocessDropStatisticsStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *DropStatisticsObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString, ProcessUtilityContext - processUtilityContext); -extern List * PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString); -extern List * GetExplicitStatisticsCommandList(Oid relationId); -extern List * GetExplicitStatisticsSchemaIdList(Oid relationId); -extern List * GetAlterIndexStatisticsCommands(Oid indexOid); + processUtilityContext); +extern List *PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); +extern List *AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk, bool isPostprocess); +extern List *PreprocessAlterStatisticsStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List *PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString); +extern List *GetExplicitStatisticsCommandList(Oid relationId); +extern List *GetExplicitStatisticsSchemaIdList(Oid relationId); +extern List *GetAlterIndexStatisticsCommands(Oid indexOid); /* subscription.c - forward declarations */ -extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt); - +extern Node *ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt); /* table.c - forward declarations */ -extern List * PreprocessDropTableStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List *PreprocessDropTableStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void PostprocessCreateTableStmt(CreateStmt *createStatement, const char *queryString); extern bool ShouldEnableLocalReferenceForeignKeys(void); -extern List * PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement, - const char *queryString); -extern List * PostprocessAlterTableSchemaStmt(Node *node, const char *queryString); +extern List *PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement, + const char *queryString); +extern List *PostprocessAlterTableSchemaStmt(Node *node, const char *queryString); extern void PrepareAlterTableStmtForConstraint(AlterTableStmt *alterTableStatement, Oid relationId, Constraint *constraint); -extern List * PreprocessAlterTableStmt(Node *node, const char *alterTableCommand, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PreprocessAlterTableSchemaStmt(Node *node, const char *queryString, +extern List *PreprocessAlterTableStmt(Node *node, const char *alterTableCommand, + ProcessUtilityContext processUtilityContext); +extern List *PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); +extern List *PreprocessAlterTableSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void SkipForeignKeyValidationIfConstraintIsFkey(AlterTableStmt *alterTableStmt, bool processLocalRelation); extern bool IsAlterTableRenameStmt(RenameStmt *renameStmt); @@ -626,160 +582,144 @@ extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *c extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod, char referencingReplicationModel, Var *distributionColumn, uint32 colocationId); -extern List * InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId, - const char *commandString); -extern List * AlterTableSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * MakeNameListFromRangeVar(const RangeVar *rel); +extern List *InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId, + const char *commandString); +extern List *AlterTableSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *MakeNameListFromRangeVar(const RangeVar *rel); extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum); extern bool ConstrTypeUsesIndex(ConstrType constrType); extern bool ConstrTypeCitusCanDefaultName(ConstrType constrType); -extern char * GetAlterColumnWithNextvalDefaultCmd(Oid sequenceOid, Oid relationId, - char *colname, bool missingTableOk); +extern char *GetAlterColumnWithNextvalDefaultCmd(Oid sequenceOid, Oid relationId, + char *colname, bool missingTableOk); extern void ErrorIfTableHasIdentityColumn(Oid relationId); extern void ConvertNewTableIfNecessary(Node *createStmt); extern void ConvertToTenantTableIfNecessary(AlterObjectSchemaStmt *alterObjectSchemaStmt); /* text_search.c - forward declarations */ -extern List * GetCreateTextSearchConfigStatements(const ObjectAddress *address); -extern List * GetCreateTextSearchDictionaryStatements(const ObjectAddress *address); -extern List * CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address); -extern List * CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address); -extern List * CreateTextSearchConfigurationObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * CreateTextSearchDictObjectAddress(Node *node, +extern List *GetCreateTextSearchConfigStatements(const ObjectAddress *address); +extern List *GetCreateTextSearchDictionaryStatements(const ObjectAddress *address); +extern List *CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address); +extern List *CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address); +extern List *CreateTextSearchConfigurationObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *CreateTextSearchDictObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *RenameTextSearchConfigurationStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *RenameTextSearchDictionaryStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterTextSearchConfigurationStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterTextSearchDictionaryStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *TextSearchConfigurationCommentObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *TextSearchDictCommentObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List * RenameTextSearchConfigurationStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * RenameTextSearchDictionaryStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * AlterTextSearchConfigurationStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * AlterTextSearchDictionaryStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * TextSearchConfigurationCommentObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * TextSearchDictCommentObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List * AlterTextSearchConfigurationOwnerObjectAddress(Node *node, - bool missing_ok, bool - isPostprocess); -extern List * AlterTextSearchDictOwnerObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern char * GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address); -extern char * GenerateBackupNameForTextSearchDict(const ObjectAddress *address); -extern List * get_ts_config_namelist(Oid tsconfigOid); +extern List *AlterTextSearchConfigurationOwnerObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List *AlterTextSearchDictOwnerObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern char *GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address); +extern char *GenerateBackupNameForTextSearchDict(const ObjectAddress *address); +extern List *get_ts_config_namelist(Oid tsconfigOid); /* truncate.c - forward declarations */ extern void PreprocessTruncateStatement(TruncateStmt *truncateStatement); /* type.c - forward declarations */ -extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address); -extern List * CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List * AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List * RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * AlterTypeSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List * RenameTypeAttributeStmtObjectAddress(Node *stmt, - bool missing_ok); -extern List * AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok, bool - isPostprocess); -extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); -extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address); +extern List *PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern Node *CreateTypeStmtByObjectAddress(const ObjectAddress *address); +extern List *CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *AlterTypeSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List *RenameTypeAttributeStmtObjectAddress(Node *stmt, + bool missing_ok); +extern List *AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List *CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); +extern char *GenerateBackupNameForTypeCollision(const ObjectAddress *address); /* function.c - forward declarations */ -extern List * CreateFunctionDDLCommandsIdempotent(const ObjectAddress *functionAddress); -extern char * GetFunctionDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace); -extern char * GenerateBackupNameForProcCollision(const ObjectAddress *address); -extern ObjectWithArgs * ObjectWithArgsFromOid(Oid funcOid); +extern List *CreateFunctionDDLCommandsIdempotent(const ObjectAddress *functionAddress); +extern char *GetFunctionDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace); +extern char *GenerateBackupNameForProcCollision(const ObjectAddress *address); +extern ObjectWithArgs *ObjectWithArgsFromOid(Oid funcOid); extern void UpdateFunctionDistributionInfo(const ObjectAddress *distAddress, int *distribution_argument_index, int *colocationId, bool *forceDelegation); /* vacuum.c - forward declarations */ -extern List * PostprocessVacuumStmt(Node *node, const char *vacuumCommand); +extern List *PostprocessVacuumStmt(Node *node, const char *vacuumCommand); /* view.c - forward declarations */ -extern List * PreprocessViewStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessViewStmt(Node *node, const char *queryString); -extern List * ViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List * AlterViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List * PreprocessDropViewStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * DropViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern char * CreateViewDDLCommand(Oid viewOid); -extern List * GetViewCreationCommandsOfTable(Oid relationId); -extern char * AlterViewOwnerCommand(Oid viewOid); -extern char * DeparseViewStmt(Node *node); -extern char * DeparseDropViewStmt(Node *node); +extern List *PreprocessViewStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessViewStmt(Node *node, const char *queryString); +extern List *ViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *AlterViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *PreprocessDropViewStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *DropViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern char *CreateViewDDLCommand(Oid viewOid); +extern List *GetViewCreationCommandsOfTable(Oid relationId); +extern char *AlterViewOwnerCommand(Oid viewOid); +extern char *DeparseViewStmt(Node *node); +extern char *DeparseDropViewStmt(Node *node); extern bool IsViewDistributed(Oid viewOid); -extern List * CreateViewDDLCommandsIdempotent(Oid viewOid); -extern List * PreprocessAlterViewStmt(Node *node, const char *queryString, +extern List *CreateViewDDLCommandsIdempotent(Oid viewOid); +extern List *PreprocessAlterViewStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessAlterViewStmt(Node *node, const char *queryString); +extern List *PreprocessRenameViewStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List * PostprocessAlterViewStmt(Node *node, const char *queryString); -extern List * PreprocessRenameViewStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * RenameViewStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); -extern List * PreprocessAlterViewSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessAlterViewSchemaStmt(Node *node, const char *queryString); -extern List * AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); +extern List *RenameViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List *PreprocessAlterViewSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessAlterViewSchemaStmt(Node *node, const char *queryString); +extern List *AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); extern bool IsViewRenameStmt(RenameStmt *renameStmt); /* trigger.c - forward declarations */ -extern List * GetExplicitTriggerCommandList(Oid relationId); +extern List *GetExplicitTriggerCommandList(Oid relationId); extern HeapTuple GetTriggerTupleById(Oid triggerId, bool missingOk); -extern List * GetExplicitTriggerIdList(Oid relationId); -extern List * PostprocessCreateTriggerStmt(Node *node, const char *queryString); -extern List * CreateTriggerStmtObjectAddress(Node *node, bool missingOk, bool - isPostprocess); +extern List *GetExplicitTriggerIdList(Oid relationId); +extern List *PostprocessCreateTriggerStmt(Node *node, const char *queryString); +extern List *CreateTriggerStmtObjectAddress(Node *node, bool missingOk, bool isPostprocess); extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt, char *schemaName, uint64 shardId); -extern List * PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString); +extern List *PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List *PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString); extern void AlterTriggerRenameEventExtendNames(RenameStmt *renameTriggerStmt, char *schemaName, uint64 shardId); -extern List * PostprocessAlterTriggerDependsStmt(Node *node, const char *queryString); -extern List * PreprocessAlterTriggerDependsStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); +extern List *PostprocessAlterTriggerDependsStmt(Node *node, const char *queryString); +extern List *PreprocessAlterTriggerDependsStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); extern void AlterTriggerDependsEventExtendNames( AlterObjectDependsStmt *alterTriggerDependsStmt, char *schemaName, uint64 shardId); extern void ErrorOutForTriggerIfNotSupported(Oid relationId); extern void ErrorIfRelationHasUnsupportedTrigger(Oid relationId); -extern List * PreprocessDropTriggerStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List *PreprocessDropTriggerStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void DropTriggerEventExtendNames(DropStmt *dropTriggerStmt, char *schemaName, uint64 shardId); -extern List * CitusCreateTriggerCommandDDLJob(Oid relationId, char *triggerName, - const char *queryString); +extern List *CitusCreateTriggerCommandDDLJob(Oid relationId, char *triggerName, + const char *queryString); extern Oid GetTriggerFunctionId(Oid triggerId); /* cascade_table_operation_for_connected_relations.c */ @@ -806,12 +746,12 @@ typedef enum CascadeOperationType extern void CascadeOperationForFkeyConnectedRelations(Oid relationId, LOCKMODE relLockMode, CascadeOperationType - cascadeOperationType); + cascadeOperationType); extern void CascadeOperationForRelationIdList(List *relationIdList, LOCKMODE lockMode, CascadeOperationType cascadeOperationType); extern void ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList); extern bool RelationIdListHasReferenceTable(List *relationIdList); -extern List * GetFKeyCreationCommandsForRelationIdList(List *relationIdList); +extern List *GetFKeyCreationCommandsForRelationIdList(List *relationIdList); extern void DropRelationForeignKeys(Oid relationId, int flags); extern void SetLocalEnableLocalReferenceForeignKeys(bool state); extern void ExecuteAndLogUtilityCommandListInTableTypeConversionViaSPI( @@ -825,7 +765,7 @@ extern void ExecuteForeignKeyCreateCommandList(List *ddlCommandList, extern void CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys, bool autoConverted); extern bool ShouldAddNewTableToMetadata(Oid relationId); -extern List * GetExplicitIndexOidList(Oid relationId); +extern List *GetExplicitIndexOidList(Oid relationId); extern bool ShouldPropagateSetCommand(VariableSetStmt *setStmt); extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *setCommand); @@ -833,7 +773,7 @@ extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *set extern void CreateCitusLocalTablePartitionOf(CreateStmt *createStatement, Oid relationId, Oid parentRelationId); extern void UpdateAutoConvertedForConnectedRelations(List *relationId, bool - autoConverted); + autoConverted); /* schema_based_sharding.c */ extern bool ShouldUseSchemaBasedSharding(char *schemaName); diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 95d948bc9..f7ba8c02b 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -227,6 +227,9 @@ extern char * DeparseGrantOnDatabaseStmt(Node *node); extern char * DeparseAlterDatabaseStmt(Node *node); extern char * DeparseAlterDatabaseRefreshCollStmt(Node *node); extern char * DeparseAlterDatabaseSetStmt(Node *node); +extern char * DeparseCreateDatabaseStmt(Node *node); +extern char * DeparseDropDatabaseStmt(Node *node); + /* forward declaration for deparse_publication_stmts.c */ diff --git a/src/include/distributed/metadata/distobject.h b/src/include/distributed/metadata/distobject.h index de56c0e1f..ba984091c 100644 --- a/src/include/distributed/metadata/distobject.h +++ b/src/include/distributed/metadata/distobject.h @@ -21,6 +21,7 @@ extern bool ObjectExists(const ObjectAddress *address); extern bool CitusExtensionObject(const ObjectAddress *objectAddress); extern bool IsAnyObjectDistributed(const List *addresses); +extern bool IsObjectDistributed(const ObjectAddress *address); extern bool ClusterHasDistributedFunctionWithDistArgument(void); extern void MarkObjectDistributed(const ObjectAddress *distAddress); extern void MarkObjectDistributedViaSuperUser(const ObjectAddress *distAddress); From 39cb7977ced66087aab047175bf20e8f231bb489 Mon Sep 17 00:00:00 2001 From: gindibay Date: Sat, 23 Sep 2023 03:09:06 +0300 Subject: [PATCH 04/63] Fixes additional compile errors --- src/backend/distributed/commands/database.c | 2 + .../distributed/database/database_lock.c | 53 ++ .../distributed/database/database_sharding.c | 544 ++++++++++++++++++ .../distributed/database/database_size.c | 180 ++++++ .../distributed/database/database_sharding.h | 0 .../distributed/pooler/pgbouncer_manager.h | 47 ++ 6 files changed, 826 insertions(+) create mode 100644 src/backend/distributed/database/database_lock.c create mode 100644 src/backend/distributed/database/database_sharding.c create mode 100644 src/backend/distributed/database/database_size.c rename src/{backend => include}/distributed/database/database_sharding.h (100%) create mode 100644 src/include/distributed/pooler/pgbouncer_manager.h diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 626234434..4886ed62e 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -34,6 +34,8 @@ #include "distributed/metadata/distobject.h" #include "distributed/database/database_sharding.h" #include "distributed/deparse_shard_query.h" +#include "distributed/listutils.h" +#include "distributed/adaptive_executor.h" diff --git a/src/backend/distributed/database/database_lock.c b/src/backend/distributed/database/database_lock.c new file mode 100644 index 000000000..64757832f --- /dev/null +++ b/src/backend/distributed/database/database_lock.c @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------- + * + * database_lock.c + * Functions for locking a database. + * + * Copyright (c) Microsoft, Inc. + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" +#include "funcapi.h" +#include "fmgr.h" +#include "miscadmin.h" + +#include "catalog/pg_database.h" +#include "commands/dbcommands.h" +#include "distributed/metadata_cache.h" +#include "storage/lmgr.h" + + +static void CitusDatabaseLock(Oid databaseId); + + +PG_FUNCTION_INFO_V1(citus_database_lock_by_name); + + +/* + * citus_database_lock locks the given database in access exclusive mode + * to temporarily block new connections. + */ +Datum +citus_database_lock_by_name(PG_FUNCTION_ARGS) +{ + CheckCitusVersion(ERROR); + + Name databaseName = PG_GETARG_NAME(0); + bool missingOk = false; + Oid databaseId = get_database_oid(NameStr(*databaseName), missingOk); + + CitusDatabaseLock(databaseId); + + PG_RETURN_VOID(); +} + + +/* + * CitusDatabaseLock locks a database for new connections. + */ +static void +CitusDatabaseLock(Oid databaseId) +{ + LockSharedObject(DatabaseRelationId, databaseId, 0, ExclusiveLock); +} diff --git a/src/backend/distributed/database/database_sharding.c b/src/backend/distributed/database/database_sharding.c new file mode 100644 index 000000000..b6e844890 --- /dev/null +++ b/src/backend/distributed/database/database_sharding.c @@ -0,0 +1,544 @@ +/*------------------------------------------------------------------------- + * + * database_sharding.c + * + * This file contains module-level definitions. + * + * Copyright (c) 2023, Microsoft, Inc. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" +#include "fmgr.h" +#include "miscadmin.h" + +#include "citus_version.h" +#include "pg_version_compat.h" + +#include "access/genam.h" +#include "commands/dbcommands.h" +#include "distributed/connection_management.h" +#include "distributed/database/database_sharding.h" +#include "distributed/deparser.h" +#include "distributed/deparse_shard_query.h" +#include "distributed/listutils.h" +#include "distributed/metadata_sync.h" +#include "distributed/remote_commands.h" +#include "distributed/shared_library_init.h" +#include "distributed/worker_transaction.h" +#include "executor/spi.h" +#include "nodes/makefuncs.h" +#include "nodes/parsenodes.h" +#include "postmaster/postmaster.h" +#include "tcop/utility.h" +#include "utils/builtins.h" +#include "utils/fmgroids.h" + + +static void ExecuteCommandInControlDatabase(char *command); +static void AllowConnectionsOnlyOnNodeGroup(Oid databaseOid, Oid nodeGroupId); +static void InsertDatabaseShardAssignment(Oid databaseOid, int nodeGroupId); +static void InsertDatabaseShardAssignmentLocally(Oid databaseOid, int nodeGroupId); +static void InsertDatabaseShardAssignmentOnOtherNodes(Oid databaseOid, int nodeGroupId); +static void DeleteDatabaseShardByDatabaseId(Oid databaseOid); +static void DeleteDatabaseShardByDatabaseIdOnOtherNodes(Oid databaseOid); +static DatabaseShard * TupleToDatabaseShard(HeapTuple heapTuple, + TupleDesc tupleDescriptor); +static char * DeleteDatabaseShardByDatabaseIdCommand(Oid databaseOid); + + +PG_FUNCTION_INFO_V1(database_shard_assign); +PG_FUNCTION_INFO_V1(citus_internal_add_database_shard); +PG_FUNCTION_INFO_V1(citus_internal_delete_database_shard); + + +/* citus.enable_database_sharding setting */ +bool EnableDatabaseSharding = false; + +/* citus.database_sharding_pgbouncer_file setting */ +char *DatabaseShardingPgBouncerFile = ""; + + +/* + * PreProcessUtilityInDatabaseShard handles DDL commands that occur within a + * database shard and require global coordination: + * - CREATE/ALTER/DROP DATABASE + * - CREATE/ALTER/DROP ROLE/USER/GROUP + */ +void +PreProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, + ProcessUtilityContext context, + bool *runPreviousUtilityHook) +{ + if (!EnableDatabaseSharding || context != PROCESS_UTILITY_TOPLEVEL) + { + return; + } + + if (EnableCreateDatabasePropagation) + { + if (IsA(parseTree, CreatedbStmt)) + { + char *command = DeparseCreatedbStmt(parseTree); + ExecuteCommandInControlDatabase(command); + + /* command is fully delegated to control database */ + *runPreviousUtilityHook = false; + } + else if (IsA(parseTree, DropdbStmt)) + { + char *command = DeparseDropdbStmt(parseTree); + ExecuteCommandInControlDatabase(command); + + /* command is fully delegated to control database */ + *runPreviousUtilityHook = false; + } + } +} + + +/* + * PostProcessUtilityInDatabaseShard is currently a noop. + */ +void +PostProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, + ProcessUtilityContext context) +{ + if (!EnableDatabaseSharding || context != PROCESS_UTILITY_TOPLEVEL) + { + return; + } +} + + +/* + * ExecuteCommandInControlDatabase connects to localhost to execute a command + * in the main Citus database. + */ +static void +ExecuteCommandInControlDatabase(char *command) +{ + int connectionFlag = FORCE_NEW_CONNECTION; + + MultiConnection *connection = + GetNodeUserDatabaseConnection(connectionFlag, LocalHostName, PostPortNumber, + NULL, CitusMainDatabase); + + ExecuteCriticalRemoteCommand(connection, + "SET application_name TO 'citus_database_shard'"); + ExecuteCriticalRemoteCommand(connection, command); + CloseConnection(connection); +} + + +/* + * database_shard_assign assigns an existing database to a node. + */ +Datum +database_shard_assign(PG_FUNCTION_ARGS) +{ + CheckCitusVersion(ERROR); + + char *databaseName = text_to_cstring(PG_GETARG_TEXT_P(0)); + + bool missingOk = false; + Oid databaseOid = get_database_oid(databaseName, missingOk); + + if (!pg_database_ownercheck(databaseOid, GetUserId())) + { + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied to assign database \"%s\" " + "to a shard", + databaseName))); + } + + if (GetDatabaseShardByOid(databaseOid) != NULL) + { + ereport(ERROR, (errmsg("database is already assigned to a shard"))); + } + + AssignDatabaseToShard(databaseOid); + + PG_RETURN_VOID(); +} + + +/* + * AssignDatabaseToShard finds a suitable node for the given + * database and assigns it. + */ +void +AssignDatabaseToShard(Oid databaseOid) +{ + int nodeGroupId = GetLocalGroupId(); + + List *workerNodes = TargetWorkerSetNodeList(ALL_SHARD_NODES, RowShareLock); + if (list_length(workerNodes) > 0) + { + /* TODO: actually look for available space */ + int workerNodeIndex = databaseOid % list_length(workerNodes); + WorkerNode *workerNode = list_nth(workerNodes, workerNodeIndex); + nodeGroupId = workerNode->groupId; + } + + InsertDatabaseShardAssignment(databaseOid, nodeGroupId); + AllowConnectionsOnlyOnNodeGroup(databaseOid, nodeGroupId); + + ReconfigurePgBouncersOnCommit = true; +} + + +/* + * AllowConnectionsOnlyOnNodeGroup sets the ALLOW_CONNECTIONS properties on + * the database to false, except on nodeGroupId. + */ +static void +AllowConnectionsOnlyOnNodeGroup(Oid databaseOid, Oid nodeGroupId) +{ + StringInfo command = makeStringInfo(); + char *databaseName = get_database_name(databaseOid); + + List *workerNodes = TargetWorkerSetNodeList(ALL_SHARD_NODES, RowShareLock); + WorkerNode *workerNode = NULL; + + foreach_ptr(workerNode, workerNodes) + { + resetStringInfo(command); + + if (workerNode->groupId == nodeGroupId) + { + appendStringInfo(command, "GRANT CONNECT ON DATABASE %s TO public", + quote_identifier(databaseName)); + } + else + { + appendStringInfo(command, "REVOKE CONNECT ON DATABASE %s FROM public", + quote_identifier(databaseName)); + } + + if (workerNode->groupId == GetLocalGroupId()) + { + ExecuteQueryViaSPI(command->data, SPI_OK_UTILITY); + } + else + { + SendCommandToWorker(workerNode->workerName, workerNode->workerPort, + command->data); + } + } +} + + +/* + * InsertDatabaseShardAssignment inserts a record into the local + * citus_catalog.database_sharding table. + */ +static void +InsertDatabaseShardAssignment(Oid databaseOid, int nodeGroupId) +{ + InsertDatabaseShardAssignmentLocally(databaseOid, nodeGroupId); + + if (EnableMetadataSync) + { + InsertDatabaseShardAssignmentOnOtherNodes(databaseOid, nodeGroupId); + } +} + + +/* + * InsertDatabaseShardAssignmentLocally inserts a record into the local + * citus_catalog.database_sharding table. + */ +static void +InsertDatabaseShardAssignmentLocally(Oid databaseOid, int nodeGroupId) +{ + Datum values[Natts_database_shard]; + bool isNulls[Natts_database_shard]; + + /* form new shard tuple */ + memset(values, 0, sizeof(values)); + memset(isNulls, false, sizeof(isNulls)); + + values[Anum_database_shard_database_id - 1] = ObjectIdGetDatum(databaseOid); + values[Anum_database_shard_node_group_id - 1] = Int32GetDatum(nodeGroupId); + values[Anum_database_shard_is_available - 1] = BoolGetDatum(true); + + /* open shard relation and insert new tuple */ + Relation databaseShardTable = table_open(DatabaseShardRelationId(), RowExclusiveLock); + + TupleDesc tupleDescriptor = RelationGetDescr(databaseShardTable); + HeapTuple heapTuple = heap_form_tuple(tupleDescriptor, values, isNulls); + + CatalogTupleInsert(databaseShardTable, heapTuple); + + CommandCounterIncrement(); + table_close(databaseShardTable, NoLock); +} + + +/* + * InsertDatabaseShardAssignmentOnOtherNodes inserts a record into the + * citus_catalog.database_sharding table on other nodes. + */ +static void +InsertDatabaseShardAssignmentOnOtherNodes(Oid databaseOid, int nodeGroupId) +{ + char *insertCommand = InsertDatabaseShardAssignmentCommand(databaseOid, nodeGroupId); + SendCommandToWorkersWithMetadata(insertCommand); +} + + +/* + * UpdateDatabaseShard updates a database shard after it is moved to a new node. + */ +void +UpdateDatabaseShard(Oid databaseOid, int targetNodeGroupId) +{ + DeleteDatabaseShardByDatabaseId(databaseOid); + InsertDatabaseShardAssignment(databaseOid, targetNodeGroupId); + AllowConnectionsOnlyOnNodeGroup(databaseOid, targetNodeGroupId); +} + + +/* + * DeleteDatabaseShardByDatabaseId deletes a record from the + * citus_catalog.database_sharding table. + */ +static void +DeleteDatabaseShardByDatabaseId(Oid databaseOid) +{ + DeleteDatabaseShardByDatabaseIdLocally(databaseOid); + + if (EnableMetadataSync) + { + DeleteDatabaseShardByDatabaseIdOnOtherNodes(databaseOid); + } +} + + +/* + * DeleteDatabaseShardByDatabaseIdLocally deletes a database_shard record by database OID. + */ +void +DeleteDatabaseShardByDatabaseIdLocally(Oid databaseOid) +{ + Relation databaseShardTable = table_open(DatabaseShardRelationId(), + RowExclusiveLock); + + const int scanKeyCount = 1; + ScanKeyData scanKey[1]; + bool indexOK = true; + + ScanKeyInit(&scanKey[0], Anum_database_shard_database_id, + BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseOid)); + + SysScanDesc scanDescriptor = systable_beginscan(databaseShardTable, + DatabaseShardPrimaryKeyIndexId(), + indexOK, + NULL, scanKeyCount, scanKey); + + HeapTuple heapTuple = systable_getnext(scanDescriptor); + if (heapTuple != NULL) + { + simple_heap_delete(databaseShardTable, &heapTuple->t_self); + } + + systable_endscan(scanDescriptor); + + CommandCounterIncrement(); + table_close(databaseShardTable, NoLock); +} + + +/* + * DeleteDatabaseShardByDatabaseIdOnOtherNodes deletes a record from the + * citus_catalog.database_sharding table on other nodes. + */ +static void +DeleteDatabaseShardByDatabaseIdOnOtherNodes(Oid databaseOid) +{ + char *deleteCommand = DeleteDatabaseShardByDatabaseIdCommand(databaseOid); + SendCommandToWorkersWithMetadata(deleteCommand); +} + + +/* + * ListDatabaseShards lists all database shards in citus_catalog.database_shard. + */ +List * +ListDatabaseShards(void) +{ + Relation databaseShardTable = table_open(DatabaseShardRelationId(), AccessShareLock); + TupleDesc tupleDescriptor = RelationGetDescr(databaseShardTable); + + List *dbShardList = NIL; + int scanKeyCount = 0; + bool indexOK = false; + + SysScanDesc scanDescriptor = systable_beginscan(databaseShardTable, InvalidOid, + indexOK, NULL, scanKeyCount, NULL); + + HeapTuple heapTuple = NULL; + while (HeapTupleIsValid(heapTuple = systable_getnext(scanDescriptor))) + { + DatabaseShard *dbShard = TupleToDatabaseShard(heapTuple, tupleDescriptor); + dbShardList = lappend(dbShardList, dbShard); + } + + systable_endscan(scanDescriptor); + table_close(databaseShardTable, NoLock); + + return dbShardList; +} + + +/* + * GetDatabaseShardByOid gets a database shard by database OID or + * NULL if no database shard could be found. + */ +DatabaseShard * +GetDatabaseShardByOid(Oid databaseOid) +{ + DatabaseShard *result = NULL; + + Relation databaseShardTable = table_open(DatabaseShardRelationId(), AccessShareLock); + TupleDesc tupleDescriptor = RelationGetDescr(databaseShardTable); + + const int scanKeyCount = 1; + ScanKeyData scanKey[1]; + bool indexOK = true; + + ScanKeyInit(&scanKey[0], Anum_database_shard_database_id, + BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseOid)); + + SysScanDesc scanDescriptor = systable_beginscan(databaseShardTable, + DatabaseShardPrimaryKeyIndexId(), + indexOK, + NULL, scanKeyCount, scanKey); + + HeapTuple heapTuple = systable_getnext(scanDescriptor); + if (HeapTupleIsValid(heapTuple)) + { + result = TupleToDatabaseShard(heapTuple, tupleDescriptor); + } + + systable_endscan(scanDescriptor); + table_close(databaseShardTable, NoLock); + + return result; +} + + +/* + * TupleToDatabaseShard converts a database_shard record tuple into a DatabaseShard struct. + */ +static DatabaseShard * +TupleToDatabaseShard(HeapTuple heapTuple, TupleDesc tupleDescriptor) +{ + Datum datumArray[Natts_database_shard]; + bool isNullArray[Natts_database_shard]; + heap_deform_tuple(heapTuple, tupleDescriptor, datumArray, isNullArray); + + DatabaseShard *record = palloc0(sizeof(DatabaseShard)); + + record->databaseOid = + DatumGetObjectId(datumArray[Anum_database_shard_database_id - 1]); + + record->nodeGroupId = + DatumGetInt32(datumArray[Anum_database_shard_node_group_id - 1]); + + record->isAvailable = + DatumGetBool(datumArray[Anum_database_shard_is_available - 1]); + + return record; +} + + +/* + * citus_internal_add_database_shard is an internal UDF to + * add a row to database_shard. + */ +Datum +citus_internal_add_database_shard(PG_FUNCTION_ARGS) +{ + char *databaseName = TextDatumGetCString(PG_GETARG_DATUM(0)); + int nodeGroupId = PG_GETARG_INT32(1); + + bool missingOk = false; + Oid databaseOid = get_database_oid(databaseName, missingOk); + + if (!pg_database_ownercheck(databaseOid, GetUserId())) + { + aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, + databaseName); + } + + InsertDatabaseShardAssignmentLocally(databaseOid, nodeGroupId); + + + PG_RETURN_VOID(); +} + + +/* + * InsertDatabaseShardAssignmentCommand returns a command to insert a database shard + * assignment into the metadata on a remote node. + */ +char * +InsertDatabaseShardAssignmentCommand(Oid databaseOid, int nodeGroupId) +{ + StringInfo command = makeStringInfo(); + char *databaseName = get_database_name(databaseOid); + + appendStringInfo(command, + "SELECT pg_catalog.citus_internal_add_database_shard(%s,%d)", + quote_literal_cstr(databaseName), + nodeGroupId); + + return command->data; +} + + +/* + * citus_internal_delete_database_shard is an internal UDF to + * delete a row from database_shard. + */ +Datum +citus_internal_delete_database_shard(PG_FUNCTION_ARGS) +{ + char *databaseName = TextDatumGetCString(PG_GETARG_DATUM(0)); + + bool missingOk = false; + Oid databaseOid = get_database_oid(databaseName, missingOk); + + if (!pg_database_ownercheck(databaseOid, GetUserId())) + { + aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, + databaseName); + } + + DeleteDatabaseShardByDatabaseIdLocally(databaseOid); + + + + PG_RETURN_VOID(); +} + + +/* + * DeleteDatabaseShardByDatabaseIdCommand returns a command to delete a database shard + * assignment from the metadata on a remote node. + */ +static char * +DeleteDatabaseShardByDatabaseIdCommand(Oid databaseOid) +{ + StringInfo command = makeStringInfo(); + char *databaseName = get_database_name(databaseOid); + + appendStringInfo(command, + "SELECT pg_catalog.citus_internal_delete_database_shard(%s)", + quote_literal_cstr(databaseName)); + + return command->data; +} diff --git a/src/backend/distributed/database/database_size.c b/src/backend/distributed/database/database_size.c new file mode 100644 index 000000000..46e72ad13 --- /dev/null +++ b/src/backend/distributed/database/database_size.c @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------------- + * + * database_size.c + * Functions for getting the size of a database. + * + * Copyright (c) Microsoft, Inc. + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" +#include "funcapi.h" +#include "fmgr.h" +#include "miscadmin.h" + +#include "commands/dbcommands.h" +#include "distributed/citus_safe_lib.h" +#include "distributed/database/database_sharding.h" +#include "distributed/listutils.h" +#include "distributed/metadata_cache.h" +#include "distributed/remote_commands.h" +#include "distributed/worker_transaction.h" +#include "utils/builtins.h" + + +static int64 GetLocalDatabaseSize(Oid databaseId); +static int64 CitusDatabaseShardSize(DatabaseShard *dbShard); +static int64 CitusDatabaseSizeOnNodeList(Oid databaseId, List *workerNodeList); + + +PG_FUNCTION_INFO_V1(citus_database_size_oid); +PG_FUNCTION_INFO_V1(citus_database_size_name); + + +/* + * citus_database_size_oid returns the size of a Citus database + * with the given oid. + */ +Datum +citus_database_size_oid(PG_FUNCTION_ARGS) +{ + CheckCitusVersion(ERROR); + + Oid databaseId = PG_GETARG_OID(0); + int64 size = CitusDatabaseSize(databaseId); + + PG_RETURN_INT64(size); +} + + +/* + * citus_database_size_name returns the size of a Citus database + * with the given name. + */ +Datum +citus_database_size_name(PG_FUNCTION_ARGS) +{ + CheckCitusVersion(ERROR); + + Name databaseName = PG_GETARG_NAME(0); + bool missingOk = false; + Oid databaseId = get_database_oid(NameStr(*databaseName), missingOk); + + int64 size = CitusDatabaseSize(databaseId); + + PG_RETURN_INT64(size); +} + + +/* + * CitusDatabaseSize returns the size of a Citus database. + */ +int64 +CitusDatabaseSize(Oid databaseId) +{ + DatabaseShard *dbShard = GetDatabaseShardByOid(databaseId); + if (dbShard != NULL) + { + /* for known database shards, get the remote size */ + return CitusDatabaseShardSize(dbShard); + } + + if (databaseId == MyDatabaseId) + { + /* for the current database, get the size from all nodes */ + List *workerNodes = TargetWorkerSetNodeList(ALL_SHARD_NODES, RowShareLock); + return CitusDatabaseSizeOnNodeList(databaseId, workerNodes); + } + + /* for other databases, get the local size */ + /* TODO: get it from main database? */ + return GetLocalDatabaseSize(databaseId); +} + + +/* + * GetLocalDatabaseSize returns the local database size by calling pg_database_size. + */ +static int64 +GetLocalDatabaseSize(Oid databaseId) +{ + Datum databaseIdDatum = ObjectIdGetDatum(databaseId); + Datum sizeDatum = DirectFunctionCall1(pg_database_size_oid, databaseIdDatum); + return DatumGetInt64(sizeDatum); +} + + +/* + * CitusDatabaseShardSize gets the database size for a specific + * shard. + */ +static int64 +CitusDatabaseShardSize(DatabaseShard *dbShard) +{ + WorkerNode *workerNode = LookupNodeForGroup(dbShard->nodeGroupId); + + return CitusDatabaseSizeOnNodeList(dbShard->databaseOid, list_make1(workerNode)); +} + + +/* + * CitusDatabaseSizeOnNodeList returns the sum of the sizes + * for a given database from all nodes in the list. + */ +static int64 +CitusDatabaseSizeOnNodeList(Oid databaseId, List *workerNodeList) +{ + int64 size = 0; + + bool raiseInterrupts = true; + + char *databaseName = get_database_name(databaseId); + char *command = psprintf("SELECT pg_catalog.pg_database_size(%s)", + quote_literal_cstr(databaseName)); + + WorkerNode *workerNode = NULL; + foreach_ptr(workerNode, workerNodeList) + { + if (workerNode->groupId == GetLocalGroupId()) + { + return GetLocalDatabaseSize(databaseId); + } + + int connectionFlags = 0; + MultiConnection *connection = GetNodeConnection(connectionFlags, + workerNode->workerName, + workerNode->workerPort); + + int querySent = SendRemoteCommand(connection, command); + if (querySent == 0) + { + ReportConnectionError(connection, ERROR); + } + + PGresult *result = GetRemoteCommandResult(connection, raiseInterrupts); + if (!IsResponseOK(result)) + { + ReportResultError(connection, result, ERROR); + } + + if (PQntuples(result) != 1 || PQnfields(result) != 1) + { + PQclear(result); + ClearResults(connection, raiseInterrupts); + + ereport(ERROR, (errmsg("unexpected number of columns returned by: %s", + command))); + } + + if (!PQgetisnull(result, 0, 0)) + { + char *sizeString = PQgetvalue(result, 0, 0); + size += SafeStringToUint64(sizeString); + } + + PQclear(result); + ClearResults(connection, raiseInterrupts); + } + + return size; +} diff --git a/src/backend/distributed/database/database_sharding.h b/src/include/distributed/database/database_sharding.h similarity index 100% rename from src/backend/distributed/database/database_sharding.h rename to src/include/distributed/database/database_sharding.h diff --git a/src/include/distributed/pooler/pgbouncer_manager.h b/src/include/distributed/pooler/pgbouncer_manager.h new file mode 100644 index 000000000..530d1b1ee --- /dev/null +++ b/src/include/distributed/pooler/pgbouncer_manager.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------- + * + * pgbouncer_manager.h + * Functions for managing outbound pgbouncers + * + * Copyright (c) Citus Data, Inc. + * + *------------------------------------------------------------------------- + */ + +#ifndef PGBOUNCER_MANAGER_H +#define PGBOUNCER_MANAGER_H + +/* default number of inbound pgbouncer processes (0 is disabled) */ +#define PGBOUNCER_INBOUND_PROCS_DEFAULT 0 + +/* bits reserved for local pgbouncer ID in the pgbouncer peer_id */ +#define PGBOUNCER_PEER_ID_LOCAL_ID_BITS 5 + +/* maximum number of inbound pgbouncer processes */ +#define PGBOUNCER_INBOUND_PROCS_MAX ((1 << PGBOUNCER_PEER_ID_LOCAL_ID_BITS) - 1) + + +/* GUC variable that sets the number of inbound pgbouncer procs */ +extern int PgBouncerInboundProcs; + +/* GUC variable that sets the inbound pgbouncer port */ +extern int PgBouncerInboundPort; + +/* GUC variable that sets the path to pgbouncer executable */ +extern char *PgBouncerPath; + +/* GUC variable that sets a pgbouncer file to include */ +extern char *PgBouncerIncludeConfig; + +/* global variable to request pgbouncer reconfiguration */ +extern bool ReconfigurePgBouncersOnCommit; + +void InitializeSharedPgBouncerManager(void); +size_t SharedPgBouncerManagerShmemSize(void); +void PgBouncerManagerMain(Datum arg); +bool PauseDatabaseOnInboundPgBouncers(char *databaseName); +bool ResumeDatabaseOnInboundPgBouncers(char *databaseName); +void TriggerPgBouncerReconfigureIfNeeded(void); + + +#endif /* PGBOUNCER_MANAGER_H */ From bd398a627b99eb10de1286cc8fbc205fe1d0a96a Mon Sep 17 00:00:00 2001 From: gindibay Date: Sat, 23 Sep 2023 13:28:49 +0300 Subject: [PATCH 05/63] Fixes compile errors --- .../distributed/database/database_sharding.c | 5 +-- .../deparser/deparse_database_stmts.c | 36 ++++++++++--------- src/backend/distributed/metadata/distobject.c | 4 +-- .../distributed/metadata/metadata_cache.c | 30 ++++++++++++++-- src/backend/distributed/shared_library_init.c | 2 ++ .../distributed/commands/utility_hook.h | 1 + src/include/distributed/metadata_cache.h | 2 ++ src/include/distributed/shared_library_init.h | 2 ++ 8 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/backend/distributed/database/database_sharding.c b/src/backend/distributed/database/database_sharding.c index b6e844890..51cd4a8f6 100644 --- a/src/backend/distributed/database/database_sharding.c +++ b/src/backend/distributed/database/database_sharding.c @@ -24,6 +24,7 @@ #include "distributed/deparse_shard_query.h" #include "distributed/listutils.h" #include "distributed/metadata_sync.h" +#include "distributed/pooler/pgbouncer_manager.h" #include "distributed/remote_commands.h" #include "distributed/shared_library_init.h" #include "distributed/worker_transaction.h" @@ -80,7 +81,7 @@ PreProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, { if (IsA(parseTree, CreatedbStmt)) { - char *command = DeparseCreatedbStmt(parseTree); + char *command = DeparseCreateDatabaseStmt(parseTree); ExecuteCommandInControlDatabase(command); /* command is fully delegated to control database */ @@ -88,7 +89,7 @@ PreProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, } else if (IsA(parseTree, DropdbStmt)) { - char *command = DeparseDropdbStmt(parseTree); + char *command = DeparseDropDatabaseStmt(parseTree); ExecuteCommandInControlDatabase(command); /* command is fully delegated to control database */ diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 1247aba43..864a9cdf7 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -196,18 +196,6 @@ DeparseAlterDatabaseSetStmt(Node *node) return str.data; } -char * -DeparseCreateDatabaseSetStmt(Node *node) -{ - CreatedbStmt *stmt = castNode(CreatedbStmt, node); - StringInfoData str = {0}; - initStringInfo(&str); - - AppendCreatedbStmt(&str, stmt); - - return str.data; -} - static void AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) { @@ -338,18 +326,17 @@ AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) } char * -DeparseDropDatabaseStmt(Node *node) +DeparseCreateDatabaseStmt(Node *node) { - DropdbStmt *stmt = castNode(DropdbStmt, node); - StringInfoData str = { 0 }; + CreatedbStmt *stmt = castNode(CreatedbStmt, node); + StringInfoData str = {0}; initStringInfo(&str); - AppendDropDatabaseStmt(&str, stmt); + AppendCreatedbStmt(&str, stmt); return str.data; } - static void AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt) { @@ -373,3 +360,18 @@ AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt) } } } + +char * +DeparseDropDatabaseStmt(Node *node) +{ + DropdbStmt *stmt = castNode(DropdbStmt, node); + StringInfoData str = { 0 }; + initStringInfo(&str); + + AppendDropDatabaseStmt(&str, stmt); + + return str.data; +} + + + diff --git a/src/backend/distributed/metadata/distobject.c b/src/backend/distributed/metadata/distobject.c index c6a8b0a22..a025ba73f 100644 --- a/src/backend/distributed/metadata/distobject.c +++ b/src/backend/distributed/metadata/distobject.c @@ -53,7 +53,7 @@ static char * CreatePgDistObjectEntryCommand(const ObjectAddress *objectAddress); static int ExecuteCommandAsSuperuser(char *query, int paramCount, Oid *paramTypes, Datum *paramValues); -static bool IsObjectDistributed(const ObjectAddress *address); +bool IsObjectDistributed(const ObjectAddress *address); PG_FUNCTION_INFO_V1(citus_unmark_object_distributed); PG_FUNCTION_INFO_V1(master_unmark_object_distributed); @@ -392,7 +392,7 @@ UnmarkObjectDistributed(const ObjectAddress *address) * IsObjectDistributed returns if the object addressed is already distributed in the * cluster. This performs a local indexed lookup in pg_dist_object. */ -static bool +bool IsObjectDistributed(const ObjectAddress *address) { ScanKeyData key[3]; diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 55d0f11c5..108750ed6 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -182,6 +182,8 @@ typedef struct MetadataCacheData Oid citusTaskStatusUnscheduledId; Oid citusTaskStatusCancelledId; Oid citusTaskStatusCancellingId; + Oid databaseShardRelationId; + Oid databaseShardPKeyIndexId; Oid distRebalanceStrategyRelationId; Oid distNodeRelationId; Oid distNodeNodeIdIndexId; @@ -2769,12 +2771,34 @@ DistRebalanceStrategyRelationId(void) return MetadataCache.distRebalanceStrategyRelationId; } +/* return oid of citus_catalog.database_sharding relation */ +Oid +DatabaseShardRelationId(void) +{ + CachedRelationNamespaceLookup("database_shard", CitusCatalogNamespaceId(), + &MetadataCache.databaseShardRelationId); + + return MetadataCache.databaseShardRelationId; +} + + +/* return oid of citus_catalog.database_sharding primary key */ +Oid +DatabaseShardPrimaryKeyIndexId(void) +{ + CachedRelationNamespaceLookup("database_shard_pkey", CitusCatalogNamespaceId(), + &MetadataCache.databaseShardPKeyIndexId); + + return MetadataCache.databaseShardPKeyIndexId; +} + + /* return the oid of citus namespace */ Oid CitusCatalogNamespaceId(void) { - CachedNamespaceLookup("citus", &MetadataCache.citusCatalogNamespaceId); + CachedNamespaceLookup("citus_catalog", &MetadataCache.citusCatalogNamespaceId); return MetadataCache.citusCatalogNamespaceId; } @@ -2805,12 +2829,14 @@ DistObjectRelationId(void) true); if (!OidIsValid(MetadataCache.distObjectRelationId)) { + Oid citusNamespaceId = get_namespace_oid("citus", false); + /* * We can only ever reach here while we are creating/altering our extension before * the table is moved to pg_catalog. */ CachedRelationNamespaceLookupExtended("pg_dist_object", - CitusCatalogNamespaceId(), + citusNamespaceId, &MetadataCache.distObjectRelationId, false); } diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index e5d593295..3cdd3dbaa 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -172,6 +172,8 @@ static GucStringAssignHook OldApplicationNameAssignHook = NULL; */ static bool FinishedStartupCitusBackend = false; +char *CitusMainDatabase = "postgres"; + static object_access_hook_type PrevObjectAccessHook = NULL; #if PG_VERSION_NUM >= PG_VERSION_15 diff --git a/src/include/distributed/commands/utility_hook.h b/src/include/distributed/commands/utility_hook.h index f02f83fe3..9ae57b49a 100644 --- a/src/include/distributed/commands/utility_hook.h +++ b/src/include/distributed/commands/utility_hook.h @@ -40,6 +40,7 @@ typedef enum extern PropSetCmdBehavior PropagateSetCommands; extern bool EnableDDLPropagation; extern int CreateObjectPropagationMode; +extern bool EnableCreateDatabasePropagation; extern bool EnableCreateTypePropagation; extern bool EnableCreateRolePropagation; extern bool EnableAlterRolePropagation; diff --git a/src/include/distributed/metadata_cache.h b/src/include/distributed/metadata_cache.h index 34b95b859..a5e9081a4 100644 --- a/src/include/distributed/metadata_cache.h +++ b/src/include/distributed/metadata_cache.h @@ -247,6 +247,7 @@ extern Oid DistLocalGroupIdRelationId(void); extern Oid DistObjectRelationId(void); extern Oid DistEnabledCustomAggregatesId(void); extern Oid DistTenantSchemaRelationId(void); +extern Oid DatabaseShardRelationId(void); /* index oids */ extern Oid DistNodeNodeIdIndexId(void); @@ -271,6 +272,7 @@ extern Oid DistObjectPrimaryKeyIndexId(void); extern Oid DistCleanupPrimaryKeyIndexId(void); extern Oid DistTenantSchemaPrimaryKeyIndexId(void); extern Oid DistTenantSchemaUniqueColocationIdIndexId(void); +extern Oid DatabaseShardPrimaryKeyIndexId(void); /* sequence oids */ extern Oid DistBackgroundJobJobIdSequenceId(void); diff --git a/src/include/distributed/shared_library_init.h b/src/include/distributed/shared_library_init.h index 3764b52fd..82910d453 100644 --- a/src/include/distributed/shared_library_init.h +++ b/src/include/distributed/shared_library_init.h @@ -17,6 +17,8 @@ #define MAX_SHARD_COUNT 64000 #define MAX_SHARD_REPLICATION_FACTOR 100 +extern char *CitusMainDatabase; + extern PGDLLEXPORT ColumnarSupportsIndexAM_type extern_ColumnarSupportsIndexAM; extern PGDLLEXPORT CompressionTypeStr_type extern_CompressionTypeStr; extern PGDLLEXPORT IsColumnarTableAmTable_type extern_IsColumnarTableAmTable; From ca36833b5c3d519b21788a3065aa82fc95aac64b Mon Sep 17 00:00:00 2001 From: gindibay Date: Sat, 23 Sep 2023 13:49:50 +0300 Subject: [PATCH 06/63] Fix for Pg16 compile error --- src/backend/distributed/database/database_sharding.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/distributed/database/database_sharding.c b/src/backend/distributed/database/database_sharding.c index 51cd4a8f6..e8c35c04b 100644 --- a/src/backend/distributed/database/database_sharding.c +++ b/src/backend/distributed/database/database_sharding.c @@ -35,6 +35,7 @@ #include "tcop/utility.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "catalog/pg_database.h" static void ExecuteCommandInControlDatabase(char *command); From eb1f09338179985326349dbe95368c47a424d98d Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 12:57:05 +0300 Subject: [PATCH 07/63] Fixes runtime and compile errors --- src/backend/distributed/commands/database.c | 229 ++++---- .../distributed/commands/utility_hook.c | 2 +- .../distributed/database/database_lock.c | 53 -- .../distributed/database/database_sharding.c | 546 ------------------ .../distributed/database/database_size.c | 180 ------ .../distributed/metadata/metadata_cache.c | 64 -- src/backend/distributed/shared_library_init.c | 11 + .../distributed/pooler/pgbouncer_manager.h | 47 -- 8 files changed, 125 insertions(+), 1007 deletions(-) delete mode 100644 src/backend/distributed/database/database_lock.c delete mode 100644 src/backend/distributed/database/database_sharding.c delete mode 100644 src/backend/distributed/database/database_size.c delete mode 100644 src/include/distributed/pooler/pgbouncer_manager.h diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 4886ed62e..61d89db44 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -32,44 +32,43 @@ #include "distributed/deparser.h" #include "distributed/worker_protocol.h" #include "distributed/metadata/distobject.h" -#include "distributed/database/database_sharding.h" #include "distributed/deparse_shard_query.h" #include "distributed/listutils.h" #include "distributed/adaptive_executor.h" - - /* macros to add DefElems to a list */ -#define DEFELEM_ADD_STRING(options, key, value) { \ - DefElem *elem = makeDefElem(key, (Node *) makeString(value), -1); \ - options = lappend(options, elem); \ -} +#define DEFELEM_ADD_STRING(options, key, value) \ + { \ + DefElem *elem = makeDefElem(key, (Node *)makeString(value), -1); \ + options = lappend(options, elem); \ + } -#define DEFELEM_ADD_BOOL(options, key, value) { \ - DefElem *elem = makeDefElem(key, (Node *) makeBoolean(value), -1); \ - options = lappend(options, elem); \ -} +#define DEFELEM_ADD_BOOL(options, key, value) \ + { \ + DefElem *elem = makeDefElem(key, (Node *)makeBoolean(value), -1); \ + options = lappend(options, elem); \ + } -#define DEFELEM_ADD_INT(options, key, value) { \ - DefElem *elem = makeDefElem(key, (Node *) makeInteger(value), -1); \ - options = lappend(options, elem); \ -} +#define DEFELEM_ADD_INT(options, key, value) \ + { \ + DefElem *elem = makeDefElem(key, (Node *)makeInteger(value), -1); \ + options = lappend(options, elem); \ + } -static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid); +static AlterOwnerStmt *RecreateAlterDatabaseOwnerStmt(Oid databaseOid); -static List * CreateDDLTaskList(char *command, List *workerNodeList, - bool outsideTransaction); +static List *CreateDDLTaskList(char *command, List *workerNodeList, + bool outsideTransaction); PG_FUNCTION_INFO_V1(citus_internal_database_command); static Oid get_database_owner(Oid db_oid); -List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +List *PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); /* controlled via GUC */ bool EnableCreateDatabasePropagation = true; bool EnableAlterDatabaseOwner = true; - /* * AlterDatabaseOwnerObjectAddress returns the ObjectAddress of the database that is the * object of the AlterOwnerStmt. Errors if missing_ok is false. @@ -80,14 +79,13 @@ AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool isPostprocess) AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_DATABASE); - Oid databaseOid = get_database_oid(strVal((String *) stmt->object), missing_ok); + Oid databaseOid = get_database_oid(strVal((String *)stmt->object), missing_ok); ObjectAddress *address = palloc0(sizeof(ObjectAddress)); ObjectAddressSet(*address, DatabaseRelationId, databaseOid); return list_make1(address); } - /* * DatabaseOwnerDDLCommands returns a list of sql statements to idempotently apply a * change of the database owner on the workers so that the database is owned by the same @@ -96,11 +94,10 @@ AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool isPostprocess) List * DatabaseOwnerDDLCommands(const ObjectAddress *address) { - Node *stmt = (Node *) RecreateAlterDatabaseOwnerStmt(address->objectId); + Node *stmt = (Node *)RecreateAlterDatabaseOwnerStmt(address->objectId); return list_make1(DeparseTreeNode(stmt)); } - /* * RecreateAlterDatabaseOwnerStmt creates an AlterOwnerStmt that represents the operation * of changing the owner of the database to its current owner. @@ -111,7 +108,7 @@ RecreateAlterDatabaseOwnerStmt(Oid databaseOid) AlterOwnerStmt *stmt = makeNode(AlterOwnerStmt); stmt->objectType = OBJECT_DATABASE; - stmt->object = (Node *) makeString(get_database_name(databaseOid)); + stmt->object = (Node *)makeString(get_database_name(databaseOid)); Oid ownerOid = get_database_owner(databaseOid); stmt->newowner = makeNode(RoleSpec); @@ -121,7 +118,6 @@ RecreateAlterDatabaseOwnerStmt(Oid databaseOid) return stmt; } - /* * get_database_owner returns the Oid of the role owning the database */ @@ -135,14 +131,13 @@ get_database_owner(Oid db_oid) errmsg("database with OID %u does not exist", db_oid))); } - Oid dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba; + Oid dba = ((Form_pg_database)GETSTRUCT(tuple))->datdba; ReleaseSysCache(tuple); return dba; } - /* * PreprocessGrantOnDatabaseStmt is executed before the statement is applied to the local * postgres instance. @@ -171,88 +166,15 @@ PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, EnsureCoordinator(); - char *sql = DeparseTreeNode((Node *) stmt); + char *sql = DeparseTreeNode((Node *)stmt); List *commands = list_make3(DISABLE_DDL_PROPAGATION, - (void *) sql, + (void *)sql, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } -/* - * citus_internal_database_command is an internal UDF to - * create/drop a database in an idempotent maner without - * transaction block restrictions. - */ -Datum -citus_internal_database_command(PG_FUNCTION_ARGS) -{ - text *commandText = PG_GETARG_TEXT_P(0); - char *command = text_to_cstring(commandText); - Node *parseTree = ParseTreeNode(command); - - set_config_option("citus.enable_ddl_propagation", "off", - (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, - GUC_ACTION_LOCAL, true, 0, false); - - set_config_option("citus.enable_create_database_propagation", "off", - (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, - GUC_ACTION_LOCAL, true, 0, false); - - if (IsA(parseTree, CreatedbStmt)) - { - CreatedbStmt *stmt = castNode(CreatedbStmt, parseTree); - - bool missingOk = true; - Oid databaseOid = get_database_oid(stmt->dbname, missingOk); - - if (!OidIsValid(databaseOid)) - { - createdb(NULL, (CreatedbStmt *) parseTree); - } - else - { - /* TODO: check database properties */ - } - } - else if (IsA(parseTree, DropdbStmt)) - { - DropdbStmt *stmt = castNode(DropdbStmt, parseTree); - - bool missingOk = true; - Oid databaseOid = get_database_oid(stmt->dbname, missingOk); - - if (!OidIsValid(databaseOid)) - { - /* already dropped? */ - } - else - { - /* remove database from pg_dist_object */ - ObjectAddress dbAddress = { 0 }; - ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); - - if (IsObjectDistributed(&dbAddress)) - { - UnmarkObjectDistributed(&dbAddress); - } - - /* remove database from database shards */ - DeleteDatabaseShardByDatabaseIdLocally(databaseOid); - - DropDatabase(NULL, (DropdbStmt *) parseTree); - } - } - else - { - ereport(ERROR, (errmsg("unsupported command type %d", nodeTag(parseTree)))); - } - - PG_RETURN_VOID(); -} - - /* * PreprocessAlterDatabaseStmt is executed before the statement is applied to the local * postgres instance. @@ -273,16 +195,15 @@ PreprocessAlterDatabaseStmt(Node *node, const char *queryString, EnsureCoordinator(); - char *sql = DeparseTreeNode((Node *) stmt); + char *sql = DeparseTreeNode((Node *)stmt); List *commands = list_make3(DISABLE_DDL_PROPAGATION, - (void *) sql, + (void *)sql, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } - #if PG_VERSION_NUM >= PG_VERSION_15 /* @@ -305,16 +226,15 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString, EnsureCoordinator(); - char *sql = DeparseTreeNode((Node *) stmt); + char *sql = DeparseTreeNode((Node *)stmt); List *commands = list_make3(DISABLE_DDL_PROPAGATION, - (void *) sql, + (void *)sql, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } - #endif /* @@ -380,7 +300,7 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, /* * PostprocessCreatedbStmt creates the plan to synchronize CREATE DATABASE * across nodes. We use the cannotBeExecutedInTransction option to avoid - * u* sending transaction blocks. + * sending transaction blocks. */ List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString) @@ -425,24 +345,102 @@ PostprocessCreateDatabaseStmt(Node *node, const char *queryString) } /* synchronize pg_dist_object records */ - ObjectAddress dbAddress = { 0 }; + ObjectAddress dbAddress = {0}; ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); MarkObjectDistributed(&dbAddress); + return NIL; } +/* + * citus_internal_database_command is an internal UDF to + * create/drop a database in an idempotent maner without + * transaction block restrictions. + */ +Datum citus_internal_database_command(PG_FUNCTION_ARGS) +{ + int saveNestLevel = NewGUCNestLevel(); + text *commandText = PG_GETARG_TEXT_P(0); + char *command = text_to_cstring(commandText); + Node *parseTree = ParseTreeNode(command); + + ereport(NOTICE, (errmsg("test internal pre"), + errhint("test pre hint"))); + + set_config_option("citus.enable_ddl_propagation", "off", + (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, + GUC_ACTION_LOCAL, true, 0, false); + + set_config_option("citus.enable_create_database_propagation", "off", + (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, + GUC_ACTION_LOCAL, true, 0, false); + + if (IsA(parseTree, CreatedbStmt)) + { + CreatedbStmt *stmt = castNode(CreatedbStmt, parseTree); + + bool missingOk = true; + Oid databaseOid = get_database_oid(stmt->dbname, missingOk); + + if (!OidIsValid(databaseOid)) + { + createdb(NULL, (CreatedbStmt *)parseTree); + } + else + { + /* TODO: check database properties */ + } + } + else if (IsA(parseTree, DropdbStmt)) + { + DropdbStmt *stmt = castNode(DropdbStmt, parseTree); + + bool missingOk = true; + Oid databaseOid = get_database_oid(stmt->dbname, missingOk); + + if (!OidIsValid(databaseOid)) + { + /* already dropped? */ + } + else + { + /* remove database from pg_dist_object */ + ObjectAddress dbAddress = {0}; + ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); + + if (IsObjectDistributed(&dbAddress)) + { + UnmarkObjectDistributed(&dbAddress); + } + + // /* remove database from database shards */ + // DeleteDatabaseShardByDatabaseIdLocally(databaseOid); + + DropDatabase(NULL, (DropdbStmt *)parseTree); + } + } + else + { + ereport(ERROR, (errmsg("unsupported command type %d", nodeTag(parseTree)))); + } + + AtEOXact_GUC(true, saveNestLevel); + + PG_RETURN_VOID(); +} + List * PreprocessDropDatabaseStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext) + ProcessUtilityContext processUtilityContext) { if (!EnableCreateDatabasePropagation || !ShouldPropagate()) { return NIL; } - DropdbStmt *stmt = (DropdbStmt *) node; + DropdbStmt *stmt = (DropdbStmt *)node; char *databaseName = stmt->dbname; bool missingOk = true; Oid databaseOid = get_database_oid(databaseName, missingOk); @@ -452,7 +450,7 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, return NIL; } - ObjectAddress dbAddress = { 0 }; + ObjectAddress dbAddress = {0}; ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); if (!IsObjectDistributed(&dbAddress)) { @@ -472,7 +470,6 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, "SELECT pg_catalog.citus_internal_database_command(%s)", quote_literal_cstr(dropDatabaseCommand)); - /* we execute here to avoid EnsureCoordinator check in ExecuteDistributedDDLJob */ bool outsideTransaction = false; List *taskList = CreateDDLTaskList(internalDropCommand->data, workerNodes, diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index cf8e0644e..a818a1ad7 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -694,7 +694,7 @@ ProcessUtilityInternal(PlannedStmt *pstmt, } /* inform the user about potential caveats */ - if (IsA(parsetree, CreatedbStmt)) + if (IsA(parsetree, CreatedbStmt) &&!EnableCreateDatabasePropagation) { if (EnableUnsupportedFeatureMessages) { diff --git a/src/backend/distributed/database/database_lock.c b/src/backend/distributed/database/database_lock.c deleted file mode 100644 index 64757832f..000000000 --- a/src/backend/distributed/database/database_lock.c +++ /dev/null @@ -1,53 +0,0 @@ -/*------------------------------------------------------------------------- - * - * database_lock.c - * Functions for locking a database. - * - * Copyright (c) Microsoft, Inc. - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" -#include "funcapi.h" -#include "fmgr.h" -#include "miscadmin.h" - -#include "catalog/pg_database.h" -#include "commands/dbcommands.h" -#include "distributed/metadata_cache.h" -#include "storage/lmgr.h" - - -static void CitusDatabaseLock(Oid databaseId); - - -PG_FUNCTION_INFO_V1(citus_database_lock_by_name); - - -/* - * citus_database_lock locks the given database in access exclusive mode - * to temporarily block new connections. - */ -Datum -citus_database_lock_by_name(PG_FUNCTION_ARGS) -{ - CheckCitusVersion(ERROR); - - Name databaseName = PG_GETARG_NAME(0); - bool missingOk = false; - Oid databaseId = get_database_oid(NameStr(*databaseName), missingOk); - - CitusDatabaseLock(databaseId); - - PG_RETURN_VOID(); -} - - -/* - * CitusDatabaseLock locks a database for new connections. - */ -static void -CitusDatabaseLock(Oid databaseId) -{ - LockSharedObject(DatabaseRelationId, databaseId, 0, ExclusiveLock); -} diff --git a/src/backend/distributed/database/database_sharding.c b/src/backend/distributed/database/database_sharding.c deleted file mode 100644 index e8c35c04b..000000000 --- a/src/backend/distributed/database/database_sharding.c +++ /dev/null @@ -1,546 +0,0 @@ -/*------------------------------------------------------------------------- - * - * database_sharding.c - * - * This file contains module-level definitions. - * - * Copyright (c) 2023, Microsoft, Inc. - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "fmgr.h" -#include "miscadmin.h" - -#include "citus_version.h" -#include "pg_version_compat.h" - -#include "access/genam.h" -#include "commands/dbcommands.h" -#include "distributed/connection_management.h" -#include "distributed/database/database_sharding.h" -#include "distributed/deparser.h" -#include "distributed/deparse_shard_query.h" -#include "distributed/listutils.h" -#include "distributed/metadata_sync.h" -#include "distributed/pooler/pgbouncer_manager.h" -#include "distributed/remote_commands.h" -#include "distributed/shared_library_init.h" -#include "distributed/worker_transaction.h" -#include "executor/spi.h" -#include "nodes/makefuncs.h" -#include "nodes/parsenodes.h" -#include "postmaster/postmaster.h" -#include "tcop/utility.h" -#include "utils/builtins.h" -#include "utils/fmgroids.h" -#include "catalog/pg_database.h" - - -static void ExecuteCommandInControlDatabase(char *command); -static void AllowConnectionsOnlyOnNodeGroup(Oid databaseOid, Oid nodeGroupId); -static void InsertDatabaseShardAssignment(Oid databaseOid, int nodeGroupId); -static void InsertDatabaseShardAssignmentLocally(Oid databaseOid, int nodeGroupId); -static void InsertDatabaseShardAssignmentOnOtherNodes(Oid databaseOid, int nodeGroupId); -static void DeleteDatabaseShardByDatabaseId(Oid databaseOid); -static void DeleteDatabaseShardByDatabaseIdOnOtherNodes(Oid databaseOid); -static DatabaseShard * TupleToDatabaseShard(HeapTuple heapTuple, - TupleDesc tupleDescriptor); -static char * DeleteDatabaseShardByDatabaseIdCommand(Oid databaseOid); - - -PG_FUNCTION_INFO_V1(database_shard_assign); -PG_FUNCTION_INFO_V1(citus_internal_add_database_shard); -PG_FUNCTION_INFO_V1(citus_internal_delete_database_shard); - - -/* citus.enable_database_sharding setting */ -bool EnableDatabaseSharding = false; - -/* citus.database_sharding_pgbouncer_file setting */ -char *DatabaseShardingPgBouncerFile = ""; - - -/* - * PreProcessUtilityInDatabaseShard handles DDL commands that occur within a - * database shard and require global coordination: - * - CREATE/ALTER/DROP DATABASE - * - CREATE/ALTER/DROP ROLE/USER/GROUP - */ -void -PreProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, - ProcessUtilityContext context, - bool *runPreviousUtilityHook) -{ - if (!EnableDatabaseSharding || context != PROCESS_UTILITY_TOPLEVEL) - { - return; - } - - if (EnableCreateDatabasePropagation) - { - if (IsA(parseTree, CreatedbStmt)) - { - char *command = DeparseCreateDatabaseStmt(parseTree); - ExecuteCommandInControlDatabase(command); - - /* command is fully delegated to control database */ - *runPreviousUtilityHook = false; - } - else if (IsA(parseTree, DropdbStmt)) - { - char *command = DeparseDropDatabaseStmt(parseTree); - ExecuteCommandInControlDatabase(command); - - /* command is fully delegated to control database */ - *runPreviousUtilityHook = false; - } - } -} - - -/* - * PostProcessUtilityInDatabaseShard is currently a noop. - */ -void -PostProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, - ProcessUtilityContext context) -{ - if (!EnableDatabaseSharding || context != PROCESS_UTILITY_TOPLEVEL) - { - return; - } -} - - -/* - * ExecuteCommandInControlDatabase connects to localhost to execute a command - * in the main Citus database. - */ -static void -ExecuteCommandInControlDatabase(char *command) -{ - int connectionFlag = FORCE_NEW_CONNECTION; - - MultiConnection *connection = - GetNodeUserDatabaseConnection(connectionFlag, LocalHostName, PostPortNumber, - NULL, CitusMainDatabase); - - ExecuteCriticalRemoteCommand(connection, - "SET application_name TO 'citus_database_shard'"); - ExecuteCriticalRemoteCommand(connection, command); - CloseConnection(connection); -} - - -/* - * database_shard_assign assigns an existing database to a node. - */ -Datum -database_shard_assign(PG_FUNCTION_ARGS) -{ - CheckCitusVersion(ERROR); - - char *databaseName = text_to_cstring(PG_GETARG_TEXT_P(0)); - - bool missingOk = false; - Oid databaseOid = get_database_oid(databaseName, missingOk); - - if (!pg_database_ownercheck(databaseOid, GetUserId())) - { - ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied to assign database \"%s\" " - "to a shard", - databaseName))); - } - - if (GetDatabaseShardByOid(databaseOid) != NULL) - { - ereport(ERROR, (errmsg("database is already assigned to a shard"))); - } - - AssignDatabaseToShard(databaseOid); - - PG_RETURN_VOID(); -} - - -/* - * AssignDatabaseToShard finds a suitable node for the given - * database and assigns it. - */ -void -AssignDatabaseToShard(Oid databaseOid) -{ - int nodeGroupId = GetLocalGroupId(); - - List *workerNodes = TargetWorkerSetNodeList(ALL_SHARD_NODES, RowShareLock); - if (list_length(workerNodes) > 0) - { - /* TODO: actually look for available space */ - int workerNodeIndex = databaseOid % list_length(workerNodes); - WorkerNode *workerNode = list_nth(workerNodes, workerNodeIndex); - nodeGroupId = workerNode->groupId; - } - - InsertDatabaseShardAssignment(databaseOid, nodeGroupId); - AllowConnectionsOnlyOnNodeGroup(databaseOid, nodeGroupId); - - ReconfigurePgBouncersOnCommit = true; -} - - -/* - * AllowConnectionsOnlyOnNodeGroup sets the ALLOW_CONNECTIONS properties on - * the database to false, except on nodeGroupId. - */ -static void -AllowConnectionsOnlyOnNodeGroup(Oid databaseOid, Oid nodeGroupId) -{ - StringInfo command = makeStringInfo(); - char *databaseName = get_database_name(databaseOid); - - List *workerNodes = TargetWorkerSetNodeList(ALL_SHARD_NODES, RowShareLock); - WorkerNode *workerNode = NULL; - - foreach_ptr(workerNode, workerNodes) - { - resetStringInfo(command); - - if (workerNode->groupId == nodeGroupId) - { - appendStringInfo(command, "GRANT CONNECT ON DATABASE %s TO public", - quote_identifier(databaseName)); - } - else - { - appendStringInfo(command, "REVOKE CONNECT ON DATABASE %s FROM public", - quote_identifier(databaseName)); - } - - if (workerNode->groupId == GetLocalGroupId()) - { - ExecuteQueryViaSPI(command->data, SPI_OK_UTILITY); - } - else - { - SendCommandToWorker(workerNode->workerName, workerNode->workerPort, - command->data); - } - } -} - - -/* - * InsertDatabaseShardAssignment inserts a record into the local - * citus_catalog.database_sharding table. - */ -static void -InsertDatabaseShardAssignment(Oid databaseOid, int nodeGroupId) -{ - InsertDatabaseShardAssignmentLocally(databaseOid, nodeGroupId); - - if (EnableMetadataSync) - { - InsertDatabaseShardAssignmentOnOtherNodes(databaseOid, nodeGroupId); - } -} - - -/* - * InsertDatabaseShardAssignmentLocally inserts a record into the local - * citus_catalog.database_sharding table. - */ -static void -InsertDatabaseShardAssignmentLocally(Oid databaseOid, int nodeGroupId) -{ - Datum values[Natts_database_shard]; - bool isNulls[Natts_database_shard]; - - /* form new shard tuple */ - memset(values, 0, sizeof(values)); - memset(isNulls, false, sizeof(isNulls)); - - values[Anum_database_shard_database_id - 1] = ObjectIdGetDatum(databaseOid); - values[Anum_database_shard_node_group_id - 1] = Int32GetDatum(nodeGroupId); - values[Anum_database_shard_is_available - 1] = BoolGetDatum(true); - - /* open shard relation and insert new tuple */ - Relation databaseShardTable = table_open(DatabaseShardRelationId(), RowExclusiveLock); - - TupleDesc tupleDescriptor = RelationGetDescr(databaseShardTable); - HeapTuple heapTuple = heap_form_tuple(tupleDescriptor, values, isNulls); - - CatalogTupleInsert(databaseShardTable, heapTuple); - - CommandCounterIncrement(); - table_close(databaseShardTable, NoLock); -} - - -/* - * InsertDatabaseShardAssignmentOnOtherNodes inserts a record into the - * citus_catalog.database_sharding table on other nodes. - */ -static void -InsertDatabaseShardAssignmentOnOtherNodes(Oid databaseOid, int nodeGroupId) -{ - char *insertCommand = InsertDatabaseShardAssignmentCommand(databaseOid, nodeGroupId); - SendCommandToWorkersWithMetadata(insertCommand); -} - - -/* - * UpdateDatabaseShard updates a database shard after it is moved to a new node. - */ -void -UpdateDatabaseShard(Oid databaseOid, int targetNodeGroupId) -{ - DeleteDatabaseShardByDatabaseId(databaseOid); - InsertDatabaseShardAssignment(databaseOid, targetNodeGroupId); - AllowConnectionsOnlyOnNodeGroup(databaseOid, targetNodeGroupId); -} - - -/* - * DeleteDatabaseShardByDatabaseId deletes a record from the - * citus_catalog.database_sharding table. - */ -static void -DeleteDatabaseShardByDatabaseId(Oid databaseOid) -{ - DeleteDatabaseShardByDatabaseIdLocally(databaseOid); - - if (EnableMetadataSync) - { - DeleteDatabaseShardByDatabaseIdOnOtherNodes(databaseOid); - } -} - - -/* - * DeleteDatabaseShardByDatabaseIdLocally deletes a database_shard record by database OID. - */ -void -DeleteDatabaseShardByDatabaseIdLocally(Oid databaseOid) -{ - Relation databaseShardTable = table_open(DatabaseShardRelationId(), - RowExclusiveLock); - - const int scanKeyCount = 1; - ScanKeyData scanKey[1]; - bool indexOK = true; - - ScanKeyInit(&scanKey[0], Anum_database_shard_database_id, - BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseOid)); - - SysScanDesc scanDescriptor = systable_beginscan(databaseShardTable, - DatabaseShardPrimaryKeyIndexId(), - indexOK, - NULL, scanKeyCount, scanKey); - - HeapTuple heapTuple = systable_getnext(scanDescriptor); - if (heapTuple != NULL) - { - simple_heap_delete(databaseShardTable, &heapTuple->t_self); - } - - systable_endscan(scanDescriptor); - - CommandCounterIncrement(); - table_close(databaseShardTable, NoLock); -} - - -/* - * DeleteDatabaseShardByDatabaseIdOnOtherNodes deletes a record from the - * citus_catalog.database_sharding table on other nodes. - */ -static void -DeleteDatabaseShardByDatabaseIdOnOtherNodes(Oid databaseOid) -{ - char *deleteCommand = DeleteDatabaseShardByDatabaseIdCommand(databaseOid); - SendCommandToWorkersWithMetadata(deleteCommand); -} - - -/* - * ListDatabaseShards lists all database shards in citus_catalog.database_shard. - */ -List * -ListDatabaseShards(void) -{ - Relation databaseShardTable = table_open(DatabaseShardRelationId(), AccessShareLock); - TupleDesc tupleDescriptor = RelationGetDescr(databaseShardTable); - - List *dbShardList = NIL; - int scanKeyCount = 0; - bool indexOK = false; - - SysScanDesc scanDescriptor = systable_beginscan(databaseShardTable, InvalidOid, - indexOK, NULL, scanKeyCount, NULL); - - HeapTuple heapTuple = NULL; - while (HeapTupleIsValid(heapTuple = systable_getnext(scanDescriptor))) - { - DatabaseShard *dbShard = TupleToDatabaseShard(heapTuple, tupleDescriptor); - dbShardList = lappend(dbShardList, dbShard); - } - - systable_endscan(scanDescriptor); - table_close(databaseShardTable, NoLock); - - return dbShardList; -} - - -/* - * GetDatabaseShardByOid gets a database shard by database OID or - * NULL if no database shard could be found. - */ -DatabaseShard * -GetDatabaseShardByOid(Oid databaseOid) -{ - DatabaseShard *result = NULL; - - Relation databaseShardTable = table_open(DatabaseShardRelationId(), AccessShareLock); - TupleDesc tupleDescriptor = RelationGetDescr(databaseShardTable); - - const int scanKeyCount = 1; - ScanKeyData scanKey[1]; - bool indexOK = true; - - ScanKeyInit(&scanKey[0], Anum_database_shard_database_id, - BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseOid)); - - SysScanDesc scanDescriptor = systable_beginscan(databaseShardTable, - DatabaseShardPrimaryKeyIndexId(), - indexOK, - NULL, scanKeyCount, scanKey); - - HeapTuple heapTuple = systable_getnext(scanDescriptor); - if (HeapTupleIsValid(heapTuple)) - { - result = TupleToDatabaseShard(heapTuple, tupleDescriptor); - } - - systable_endscan(scanDescriptor); - table_close(databaseShardTable, NoLock); - - return result; -} - - -/* - * TupleToDatabaseShard converts a database_shard record tuple into a DatabaseShard struct. - */ -static DatabaseShard * -TupleToDatabaseShard(HeapTuple heapTuple, TupleDesc tupleDescriptor) -{ - Datum datumArray[Natts_database_shard]; - bool isNullArray[Natts_database_shard]; - heap_deform_tuple(heapTuple, tupleDescriptor, datumArray, isNullArray); - - DatabaseShard *record = palloc0(sizeof(DatabaseShard)); - - record->databaseOid = - DatumGetObjectId(datumArray[Anum_database_shard_database_id - 1]); - - record->nodeGroupId = - DatumGetInt32(datumArray[Anum_database_shard_node_group_id - 1]); - - record->isAvailable = - DatumGetBool(datumArray[Anum_database_shard_is_available - 1]); - - return record; -} - - -/* - * citus_internal_add_database_shard is an internal UDF to - * add a row to database_shard. - */ -Datum -citus_internal_add_database_shard(PG_FUNCTION_ARGS) -{ - char *databaseName = TextDatumGetCString(PG_GETARG_DATUM(0)); - int nodeGroupId = PG_GETARG_INT32(1); - - bool missingOk = false; - Oid databaseOid = get_database_oid(databaseName, missingOk); - - if (!pg_database_ownercheck(databaseOid, GetUserId())) - { - aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, - databaseName); - } - - InsertDatabaseShardAssignmentLocally(databaseOid, nodeGroupId); - - - PG_RETURN_VOID(); -} - - -/* - * InsertDatabaseShardAssignmentCommand returns a command to insert a database shard - * assignment into the metadata on a remote node. - */ -char * -InsertDatabaseShardAssignmentCommand(Oid databaseOid, int nodeGroupId) -{ - StringInfo command = makeStringInfo(); - char *databaseName = get_database_name(databaseOid); - - appendStringInfo(command, - "SELECT pg_catalog.citus_internal_add_database_shard(%s,%d)", - quote_literal_cstr(databaseName), - nodeGroupId); - - return command->data; -} - - -/* - * citus_internal_delete_database_shard is an internal UDF to - * delete a row from database_shard. - */ -Datum -citus_internal_delete_database_shard(PG_FUNCTION_ARGS) -{ - char *databaseName = TextDatumGetCString(PG_GETARG_DATUM(0)); - - bool missingOk = false; - Oid databaseOid = get_database_oid(databaseName, missingOk); - - if (!pg_database_ownercheck(databaseOid, GetUserId())) - { - aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, - databaseName); - } - - DeleteDatabaseShardByDatabaseIdLocally(databaseOid); - - - - PG_RETURN_VOID(); -} - - -/* - * DeleteDatabaseShardByDatabaseIdCommand returns a command to delete a database shard - * assignment from the metadata on a remote node. - */ -static char * -DeleteDatabaseShardByDatabaseIdCommand(Oid databaseOid) -{ - StringInfo command = makeStringInfo(); - char *databaseName = get_database_name(databaseOid); - - appendStringInfo(command, - "SELECT pg_catalog.citus_internal_delete_database_shard(%s)", - quote_literal_cstr(databaseName)); - - return command->data; -} diff --git a/src/backend/distributed/database/database_size.c b/src/backend/distributed/database/database_size.c deleted file mode 100644 index 46e72ad13..000000000 --- a/src/backend/distributed/database/database_size.c +++ /dev/null @@ -1,180 +0,0 @@ -/*------------------------------------------------------------------------- - * - * database_size.c - * Functions for getting the size of a database. - * - * Copyright (c) Microsoft, Inc. - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" -#include "funcapi.h" -#include "fmgr.h" -#include "miscadmin.h" - -#include "commands/dbcommands.h" -#include "distributed/citus_safe_lib.h" -#include "distributed/database/database_sharding.h" -#include "distributed/listutils.h" -#include "distributed/metadata_cache.h" -#include "distributed/remote_commands.h" -#include "distributed/worker_transaction.h" -#include "utils/builtins.h" - - -static int64 GetLocalDatabaseSize(Oid databaseId); -static int64 CitusDatabaseShardSize(DatabaseShard *dbShard); -static int64 CitusDatabaseSizeOnNodeList(Oid databaseId, List *workerNodeList); - - -PG_FUNCTION_INFO_V1(citus_database_size_oid); -PG_FUNCTION_INFO_V1(citus_database_size_name); - - -/* - * citus_database_size_oid returns the size of a Citus database - * with the given oid. - */ -Datum -citus_database_size_oid(PG_FUNCTION_ARGS) -{ - CheckCitusVersion(ERROR); - - Oid databaseId = PG_GETARG_OID(0); - int64 size = CitusDatabaseSize(databaseId); - - PG_RETURN_INT64(size); -} - - -/* - * citus_database_size_name returns the size of a Citus database - * with the given name. - */ -Datum -citus_database_size_name(PG_FUNCTION_ARGS) -{ - CheckCitusVersion(ERROR); - - Name databaseName = PG_GETARG_NAME(0); - bool missingOk = false; - Oid databaseId = get_database_oid(NameStr(*databaseName), missingOk); - - int64 size = CitusDatabaseSize(databaseId); - - PG_RETURN_INT64(size); -} - - -/* - * CitusDatabaseSize returns the size of a Citus database. - */ -int64 -CitusDatabaseSize(Oid databaseId) -{ - DatabaseShard *dbShard = GetDatabaseShardByOid(databaseId); - if (dbShard != NULL) - { - /* for known database shards, get the remote size */ - return CitusDatabaseShardSize(dbShard); - } - - if (databaseId == MyDatabaseId) - { - /* for the current database, get the size from all nodes */ - List *workerNodes = TargetWorkerSetNodeList(ALL_SHARD_NODES, RowShareLock); - return CitusDatabaseSizeOnNodeList(databaseId, workerNodes); - } - - /* for other databases, get the local size */ - /* TODO: get it from main database? */ - return GetLocalDatabaseSize(databaseId); -} - - -/* - * GetLocalDatabaseSize returns the local database size by calling pg_database_size. - */ -static int64 -GetLocalDatabaseSize(Oid databaseId) -{ - Datum databaseIdDatum = ObjectIdGetDatum(databaseId); - Datum sizeDatum = DirectFunctionCall1(pg_database_size_oid, databaseIdDatum); - return DatumGetInt64(sizeDatum); -} - - -/* - * CitusDatabaseShardSize gets the database size for a specific - * shard. - */ -static int64 -CitusDatabaseShardSize(DatabaseShard *dbShard) -{ - WorkerNode *workerNode = LookupNodeForGroup(dbShard->nodeGroupId); - - return CitusDatabaseSizeOnNodeList(dbShard->databaseOid, list_make1(workerNode)); -} - - -/* - * CitusDatabaseSizeOnNodeList returns the sum of the sizes - * for a given database from all nodes in the list. - */ -static int64 -CitusDatabaseSizeOnNodeList(Oid databaseId, List *workerNodeList) -{ - int64 size = 0; - - bool raiseInterrupts = true; - - char *databaseName = get_database_name(databaseId); - char *command = psprintf("SELECT pg_catalog.pg_database_size(%s)", - quote_literal_cstr(databaseName)); - - WorkerNode *workerNode = NULL; - foreach_ptr(workerNode, workerNodeList) - { - if (workerNode->groupId == GetLocalGroupId()) - { - return GetLocalDatabaseSize(databaseId); - } - - int connectionFlags = 0; - MultiConnection *connection = GetNodeConnection(connectionFlags, - workerNode->workerName, - workerNode->workerPort); - - int querySent = SendRemoteCommand(connection, command); - if (querySent == 0) - { - ReportConnectionError(connection, ERROR); - } - - PGresult *result = GetRemoteCommandResult(connection, raiseInterrupts); - if (!IsResponseOK(result)) - { - ReportResultError(connection, result, ERROR); - } - - if (PQntuples(result) != 1 || PQnfields(result) != 1) - { - PQclear(result); - ClearResults(connection, raiseInterrupts); - - ereport(ERROR, (errmsg("unexpected number of columns returned by: %s", - command))); - } - - if (!PQgetisnull(result, 0, 0)) - { - char *sizeString = PQgetvalue(result, 0, 0); - size += SafeStringToUint64(sizeString); - } - - PQclear(result); - ClearResults(connection, raiseInterrupts); - } - - return size; -} diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 108750ed6..7345b1839 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -208,7 +208,6 @@ typedef struct MetadataCacheData Oid distTransactionGroupIndexId; Oid distTenantSchemaPrimaryKeyIndexId; Oid distTenantSchemaUniqueColocationIdIndexId; - Oid citusCatalogNamespaceId; Oid copyFormatTypeId; Oid readIntermediateResultFuncId; Oid readIntermediateResultArrayFuncId; @@ -312,7 +311,6 @@ static HeapTuple LookupDistPartitionTuple(Relation pgDistPartition, Oid relation static void GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, Oid *columnTypeId, int32 *columnTypeMod, Oid *intervalTypeId, int32 *intervalTypeMod); -static void CachedNamespaceLookup(const char *nspname, Oid *cachedOid); static void CachedRelationLookup(const char *relationName, Oid *cachedOid); static void CachedRelationLookupExtended(const char *relationName, Oid *cachedOid, bool missing_ok); @@ -2771,36 +2769,7 @@ DistRebalanceStrategyRelationId(void) return MetadataCache.distRebalanceStrategyRelationId; } -/* return oid of citus_catalog.database_sharding relation */ -Oid -DatabaseShardRelationId(void) -{ - CachedRelationNamespaceLookup("database_shard", CitusCatalogNamespaceId(), - &MetadataCache.databaseShardRelationId); - return MetadataCache.databaseShardRelationId; -} - - -/* return oid of citus_catalog.database_sharding primary key */ -Oid -DatabaseShardPrimaryKeyIndexId(void) -{ - CachedRelationNamespaceLookup("database_shard_pkey", CitusCatalogNamespaceId(), - &MetadataCache.databaseShardPKeyIndexId); - - return MetadataCache.databaseShardPKeyIndexId; -} - - - -/* return the oid of citus namespace */ -Oid -CitusCatalogNamespaceId(void) -{ - CachedNamespaceLookup("citus_catalog", &MetadataCache.citusCatalogNamespaceId); - return MetadataCache.citusCatalogNamespaceId; -} /* return oid of pg_dist_object relation */ @@ -2870,17 +2839,6 @@ DistObjectPrimaryKeyIndexId(void) &MetadataCache.distObjectPrimaryKeyIndexId, true); - if (!OidIsValid(MetadataCache.distObjectPrimaryKeyIndexId)) - { - /* - * We can only ever reach here while we are creating/altering our extension before - * the table is moved to pg_catalog. - */ - CachedRelationNamespaceLookupExtended("pg_dist_object_pkey", - CitusCatalogNamespaceId(), - &MetadataCache.distObjectPrimaryKeyIndexId, - false); - } return MetadataCache.distObjectPrimaryKeyIndexId; } @@ -5446,28 +5404,6 @@ DeformedDistShardTupleToShardInterval(Datum *datumArray, bool *isNullArray, } -/* - * CachedNamespaceLookup performs a cached lookup for the namespace (schema), with the - * result cached in cachedOid. - */ -static void -CachedNamespaceLookup(const char *nspname, Oid *cachedOid) -{ - /* force callbacks to be registered, so we always get notified upon changes */ - InitializeCaches(); - - if (*cachedOid == InvalidOid) - { - *cachedOid = get_namespace_oid(nspname, true); - - if (*cachedOid == InvalidOid) - { - ereport(ERROR, (errmsg( - "cache lookup failed for namespace %s, called too early?", - nspname))); - } - } -} /* diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 3cdd3dbaa..c510c2d30 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -1264,6 +1264,17 @@ RegisterCitusConfigVariables(void) GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE, NULL, NULL, NULL); + DefineCustomBoolVariable( + "citus.enable_create_database_propagation", + gettext_noop("Enables propagating CREATE DATABASE " + "and DROP DATABASE statements to workers"), + NULL, + &EnableCreateDatabasePropagation, + true, + PGC_USERSET, + GUC_STANDARD, + NULL, NULL, NULL); + DefineCustomBoolVariable( "citus.enable_create_role_propagation", gettext_noop("Enables propagating CREATE ROLE " diff --git a/src/include/distributed/pooler/pgbouncer_manager.h b/src/include/distributed/pooler/pgbouncer_manager.h deleted file mode 100644 index 530d1b1ee..000000000 --- a/src/include/distributed/pooler/pgbouncer_manager.h +++ /dev/null @@ -1,47 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgbouncer_manager.h - * Functions for managing outbound pgbouncers - * - * Copyright (c) Citus Data, Inc. - * - *------------------------------------------------------------------------- - */ - -#ifndef PGBOUNCER_MANAGER_H -#define PGBOUNCER_MANAGER_H - -/* default number of inbound pgbouncer processes (0 is disabled) */ -#define PGBOUNCER_INBOUND_PROCS_DEFAULT 0 - -/* bits reserved for local pgbouncer ID in the pgbouncer peer_id */ -#define PGBOUNCER_PEER_ID_LOCAL_ID_BITS 5 - -/* maximum number of inbound pgbouncer processes */ -#define PGBOUNCER_INBOUND_PROCS_MAX ((1 << PGBOUNCER_PEER_ID_LOCAL_ID_BITS) - 1) - - -/* GUC variable that sets the number of inbound pgbouncer procs */ -extern int PgBouncerInboundProcs; - -/* GUC variable that sets the inbound pgbouncer port */ -extern int PgBouncerInboundPort; - -/* GUC variable that sets the path to pgbouncer executable */ -extern char *PgBouncerPath; - -/* GUC variable that sets a pgbouncer file to include */ -extern char *PgBouncerIncludeConfig; - -/* global variable to request pgbouncer reconfiguration */ -extern bool ReconfigurePgBouncersOnCommit; - -void InitializeSharedPgBouncerManager(void); -size_t SharedPgBouncerManagerShmemSize(void); -void PgBouncerManagerMain(Datum arg); -bool PauseDatabaseOnInboundPgBouncers(char *databaseName); -bool ResumeDatabaseOnInboundPgBouncers(char *databaseName); -void TriggerPgBouncerReconfigureIfNeeded(void); - - -#endif /* PGBOUNCER_MANAGER_H */ From 40893e6ffc2df399a4bee3f15d80a518f75a459e Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 13:17:49 +0300 Subject: [PATCH 08/63] Removes unnecessary files --- .../distributed/metadata/metadata_cache.c | 2 - .../distributed/database/database_sharding.h | 53 ------------------- src/include/distributed/metadata_cache.h | 2 - src/include/distributed/shared_library_init.h | 2 - 4 files changed, 59 deletions(-) delete mode 100644 src/include/distributed/database/database_sharding.h diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 7345b1839..531db2796 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -182,8 +182,6 @@ typedef struct MetadataCacheData Oid citusTaskStatusUnscheduledId; Oid citusTaskStatusCancelledId; Oid citusTaskStatusCancellingId; - Oid databaseShardRelationId; - Oid databaseShardPKeyIndexId; Oid distRebalanceStrategyRelationId; Oid distNodeRelationId; Oid distNodeNodeIdIndexId; diff --git a/src/include/distributed/database/database_sharding.h b/src/include/distributed/database/database_sharding.h deleted file mode 100644 index 390be1383..000000000 --- a/src/include/distributed/database/database_sharding.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * database_sharding.h - * - * Data structure definition for managing backend data and related function - * - * Copyright (c) Microsoft, Inc. - */ - -#ifndef DATABASE_SHARDING_H -#define DATABASE_SHARDING_H - - -#include "tcop/utility.h" - - -/* attributes of citus_catalog.database_shard */ -#define Natts_database_shard 3 -#define Anum_database_shard_database_id 1 -#define Anum_database_shard_node_group_id 2 -#define Anum_database_shard_is_available 3 - - -typedef struct DatabaseShard -{ - /* database oid */ - Oid databaseOid; - - /* node group on which the database shard is placed */ - int nodeGroupId; - - /* whether the database shard is available */ - bool isAvailable; -} DatabaseShard; - -/* citus.enable_database_sharding setting */ -extern bool EnableDatabaseSharding; - -void PreProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, - ProcessUtilityContext context, - bool *runPreviousUtilityHook); -void PostProcessUtilityInDatabaseShard(Node *parseTree, const char *queryString, - ProcessUtilityContext context); -bool DatabaseShardingEnabled(void); -void AssignDatabaseToShard(Oid databaseOid); -void UpdateDatabaseShard(Oid databaseOid, int targetNodeGroupId); -void DeleteDatabaseShardByDatabaseIdLocally(Oid databaseOid); -DatabaseShard * GetDatabaseShardByOid(Oid databaseOid); -List * ListDatabaseShards(void); -int64 CitusDatabaseSize(Oid databaseId); -char * InsertDatabaseShardAssignmentCommand(Oid databaseOid, int nodeGroupId); - - -#endif diff --git a/src/include/distributed/metadata_cache.h b/src/include/distributed/metadata_cache.h index a5e9081a4..34b95b859 100644 --- a/src/include/distributed/metadata_cache.h +++ b/src/include/distributed/metadata_cache.h @@ -247,7 +247,6 @@ extern Oid DistLocalGroupIdRelationId(void); extern Oid DistObjectRelationId(void); extern Oid DistEnabledCustomAggregatesId(void); extern Oid DistTenantSchemaRelationId(void); -extern Oid DatabaseShardRelationId(void); /* index oids */ extern Oid DistNodeNodeIdIndexId(void); @@ -272,7 +271,6 @@ extern Oid DistObjectPrimaryKeyIndexId(void); extern Oid DistCleanupPrimaryKeyIndexId(void); extern Oid DistTenantSchemaPrimaryKeyIndexId(void); extern Oid DistTenantSchemaUniqueColocationIdIndexId(void); -extern Oid DatabaseShardPrimaryKeyIndexId(void); /* sequence oids */ extern Oid DistBackgroundJobJobIdSequenceId(void); diff --git a/src/include/distributed/shared_library_init.h b/src/include/distributed/shared_library_init.h index 82910d453..3764b52fd 100644 --- a/src/include/distributed/shared_library_init.h +++ b/src/include/distributed/shared_library_init.h @@ -17,8 +17,6 @@ #define MAX_SHARD_COUNT 64000 #define MAX_SHARD_REPLICATION_FACTOR 100 -extern char *CitusMainDatabase; - extern PGDLLEXPORT ColumnarSupportsIndexAM_type extern_ColumnarSupportsIndexAM; extern PGDLLEXPORT CompressionTypeStr_type extern_CompressionTypeStr; extern PGDLLEXPORT IsColumnarTableAmTable_type extern_IsColumnarTableAmTable; From 1e7c18cb619bd8cd39ff985c02d108e29ce49777 Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 13:19:36 +0300 Subject: [PATCH 09/63] Removes unnecessary code --- src/backend/distributed/metadata/metadata_cache.c | 1 + src/backend/distributed/shared_library_init.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 531db2796..862eb0bfc 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -206,6 +206,7 @@ typedef struct MetadataCacheData Oid distTransactionGroupIndexId; Oid distTenantSchemaPrimaryKeyIndexId; Oid distTenantSchemaUniqueColocationIdIndexId; + Oid citusCatalogNamespaceId; Oid copyFormatTypeId; Oid readIntermediateResultFuncId; Oid readIntermediateResultArrayFuncId; diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index c510c2d30..886517464 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -172,8 +172,6 @@ static GucStringAssignHook OldApplicationNameAssignHook = NULL; */ static bool FinishedStartupCitusBackend = false; -char *CitusMainDatabase = "postgres"; - static object_access_hook_type PrevObjectAccessHook = NULL; #if PG_VERSION_NUM >= PG_VERSION_15 From cef9ac702e7fe1f57d68ede4d208f7919205f8ae Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 13:32:39 +0300 Subject: [PATCH 10/63] Fixes indentation --- src/backend/distributed/commands/database.c | 91 ++- .../commands/distribute_object_ops.c | 1 + .../distributed/commands/utility_hook.c | 2 +- .../deparser/deparse_database_stmts.c | 37 +- .../distributed/metadata/metadata_cache.c | 4 - src/include/distributed/commands.h | 773 ++++++++++-------- src/include/distributed/deparser.h | 1 - 7 files changed, 487 insertions(+), 422 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 61d89db44..c760aaa70 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -37,33 +37,33 @@ #include "distributed/adaptive_executor.h" /* macros to add DefElems to a list */ -#define DEFELEM_ADD_STRING(options, key, value) \ - { \ - DefElem *elem = makeDefElem(key, (Node *)makeString(value), -1); \ - options = lappend(options, elem); \ +#define DEFELEM_ADD_STRING(options, key, value) \ + { \ + DefElem *elem = makeDefElem(key, (Node *) makeString(value), -1); \ + options = lappend(options, elem); \ } -#define DEFELEM_ADD_BOOL(options, key, value) \ - { \ - DefElem *elem = makeDefElem(key, (Node *)makeBoolean(value), -1); \ - options = lappend(options, elem); \ +#define DEFELEM_ADD_BOOL(options, key, value) \ + { \ + DefElem *elem = makeDefElem(key, (Node *) makeBoolean(value), -1); \ + options = lappend(options, elem); \ } -#define DEFELEM_ADD_INT(options, key, value) \ - { \ - DefElem *elem = makeDefElem(key, (Node *)makeInteger(value), -1); \ - options = lappend(options, elem); \ +#define DEFELEM_ADD_INT(options, key, value) \ + { \ + DefElem *elem = makeDefElem(key, (Node *) makeInteger(value), -1); \ + options = lappend(options, elem); \ } -static AlterOwnerStmt *RecreateAlterDatabaseOwnerStmt(Oid databaseOid); +static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid); -static List *CreateDDLTaskList(char *command, List *workerNodeList, - bool outsideTransaction); +static List * CreateDDLTaskList(char *command, List *workerNodeList, + bool outsideTransaction); PG_FUNCTION_INFO_V1(citus_internal_database_command); static Oid get_database_owner(Oid db_oid); -List *PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); /* controlled via GUC */ bool EnableCreateDatabasePropagation = true; @@ -79,13 +79,14 @@ AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool isPostprocess) AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); Assert(stmt->objectType == OBJECT_DATABASE); - Oid databaseOid = get_database_oid(strVal((String *)stmt->object), missing_ok); + Oid databaseOid = get_database_oid(strVal((String *) stmt->object), missing_ok); ObjectAddress *address = palloc0(sizeof(ObjectAddress)); ObjectAddressSet(*address, DatabaseRelationId, databaseOid); return list_make1(address); } + /* * DatabaseOwnerDDLCommands returns a list of sql statements to idempotently apply a * change of the database owner on the workers so that the database is owned by the same @@ -94,10 +95,11 @@ AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool isPostprocess) List * DatabaseOwnerDDLCommands(const ObjectAddress *address) { - Node *stmt = (Node *)RecreateAlterDatabaseOwnerStmt(address->objectId); + Node *stmt = (Node *) RecreateAlterDatabaseOwnerStmt(address->objectId); return list_make1(DeparseTreeNode(stmt)); } + /* * RecreateAlterDatabaseOwnerStmt creates an AlterOwnerStmt that represents the operation * of changing the owner of the database to its current owner. @@ -108,7 +110,7 @@ RecreateAlterDatabaseOwnerStmt(Oid databaseOid) AlterOwnerStmt *stmt = makeNode(AlterOwnerStmt); stmt->objectType = OBJECT_DATABASE; - stmt->object = (Node *)makeString(get_database_name(databaseOid)); + stmt->object = (Node *) makeString(get_database_name(databaseOid)); Oid ownerOid = get_database_owner(databaseOid); stmt->newowner = makeNode(RoleSpec); @@ -118,6 +120,7 @@ RecreateAlterDatabaseOwnerStmt(Oid databaseOid) return stmt; } + /* * get_database_owner returns the Oid of the role owning the database */ @@ -131,13 +134,14 @@ get_database_owner(Oid db_oid) errmsg("database with OID %u does not exist", db_oid))); } - Oid dba = ((Form_pg_database)GETSTRUCT(tuple))->datdba; + Oid dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba; ReleaseSysCache(tuple); return dba; } + /* * PreprocessGrantOnDatabaseStmt is executed before the statement is applied to the local * postgres instance. @@ -166,15 +170,16 @@ PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, EnsureCoordinator(); - char *sql = DeparseTreeNode((Node *)stmt); + char *sql = DeparseTreeNode((Node *) stmt); List *commands = list_make3(DISABLE_DDL_PROPAGATION, - (void *)sql, + (void *) sql, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } + /* * PreprocessAlterDatabaseStmt is executed before the statement is applied to the local * postgres instance. @@ -195,15 +200,16 @@ PreprocessAlterDatabaseStmt(Node *node, const char *queryString, EnsureCoordinator(); - char *sql = DeparseTreeNode((Node *)stmt); + char *sql = DeparseTreeNode((Node *) stmt); List *commands = list_make3(DISABLE_DDL_PROPAGATION, - (void *)sql, + (void *) sql, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } + #if PG_VERSION_NUM >= PG_VERSION_15 /* @@ -226,15 +232,16 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString, EnsureCoordinator(); - char *sql = DeparseTreeNode((Node *)stmt); + char *sql = DeparseTreeNode((Node *) stmt); List *commands = list_make3(DISABLE_DDL_PROPAGATION, - (void *)sql, + (void *) sql, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } + #endif /* @@ -320,7 +327,8 @@ PostprocessCreateDatabaseStmt(Node *node, const char *queryString) * * We do not do this right now because of the AssignDatabaseToShard at the end. */ - List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, RowShareLock); + List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, + RowShareLock); if (list_length(workerNodes) > 0) { char *createDatabaseCommand = DeparseTreeNode(node); @@ -345,21 +353,22 @@ PostprocessCreateDatabaseStmt(Node *node, const char *queryString) } /* synchronize pg_dist_object records */ - ObjectAddress dbAddress = {0}; + ObjectAddress dbAddress = { 0 }; ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); MarkObjectDistributed(&dbAddress); - return NIL; } + /* * citus_internal_database_command is an internal UDF to * create/drop a database in an idempotent maner without * transaction block restrictions. */ -Datum citus_internal_database_command(PG_FUNCTION_ARGS) +Datum +citus_internal_database_command(PG_FUNCTION_ARGS) { int saveNestLevel = NewGUCNestLevel(); text *commandText = PG_GETARG_TEXT_P(0); @@ -367,7 +376,7 @@ Datum citus_internal_database_command(PG_FUNCTION_ARGS) Node *parseTree = ParseTreeNode(command); ereport(NOTICE, (errmsg("test internal pre"), - errhint("test pre hint"))); + errhint("test pre hint"))); set_config_option("citus.enable_ddl_propagation", "off", (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, @@ -386,7 +395,7 @@ Datum citus_internal_database_command(PG_FUNCTION_ARGS) if (!OidIsValid(databaseOid)) { - createdb(NULL, (CreatedbStmt *)parseTree); + createdb(NULL, (CreatedbStmt *) parseTree); } else { @@ -407,7 +416,7 @@ Datum citus_internal_database_command(PG_FUNCTION_ARGS) else { /* remove database from pg_dist_object */ - ObjectAddress dbAddress = {0}; + ObjectAddress dbAddress = { 0 }; ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); if (IsObjectDistributed(&dbAddress)) @@ -415,10 +424,10 @@ Datum citus_internal_database_command(PG_FUNCTION_ARGS) UnmarkObjectDistributed(&dbAddress); } - // /* remove database from database shards */ - // DeleteDatabaseShardByDatabaseIdLocally(databaseOid); + /* / * remove database from database shards * / */ + /* DeleteDatabaseShardByDatabaseIdLocally(databaseOid); */ - DropDatabase(NULL, (DropdbStmt *)parseTree); + DropDatabase(NULL, (DropdbStmt *) parseTree); } } else @@ -431,6 +440,7 @@ Datum citus_internal_database_command(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + List * PreprocessDropDatabaseStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext) @@ -440,7 +450,7 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, return NIL; } - DropdbStmt *stmt = (DropdbStmt *)node; + DropdbStmt *stmt = (DropdbStmt *) node; char *databaseName = stmt->dbname; bool missingOk = true; Oid databaseOid = get_database_oid(databaseName, missingOk); @@ -450,14 +460,15 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, return NIL; } - ObjectAddress dbAddress = {0}; + ObjectAddress dbAddress = { 0 }; ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); if (!IsObjectDistributed(&dbAddress)) { return NIL; } - List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, RowShareLock); + List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, + RowShareLock); if (list_length(workerNodes) == 0) { return NIL; diff --git a/src/backend/distributed/commands/distribute_object_ops.c b/src/backend/distributed/commands/distribute_object_ops.c index 7465a58cd..ef7d486b5 100644 --- a/src/backend/distributed/commands/distribute_object_ops.c +++ b/src/backend/distributed/commands/distribute_object_ops.c @@ -1355,6 +1355,7 @@ GetDistributeObjectOps(Node *node) { return &Database_Alter; } + case T_CreatedbStmt: { return &Database_Create; diff --git a/src/backend/distributed/commands/utility_hook.c b/src/backend/distributed/commands/utility_hook.c index a818a1ad7..dd729cad0 100644 --- a/src/backend/distributed/commands/utility_hook.c +++ b/src/backend/distributed/commands/utility_hook.c @@ -694,7 +694,7 @@ ProcessUtilityInternal(PlannedStmt *pstmt, } /* inform the user about potential caveats */ - if (IsA(parsetree, CreatedbStmt) &&!EnableCreateDatabasePropagation) + if (IsA(parsetree, CreatedbStmt) && !EnableCreateDatabasePropagation) { if (EnableUnsupportedFeatureMessages) { diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 864a9cdf7..75ab1d489 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -34,7 +34,7 @@ char * DeparseAlterDatabaseOwnerStmt(Node *node) { AlterOwnerStmt *stmt = castNode(AlterOwnerStmt, node); - StringInfoData str = {0}; + StringInfoData str = { 0 }; initStringInfo(&str); Assert(stmt->objectType == OBJECT_DATABASE); @@ -44,6 +44,7 @@ DeparseAlterDatabaseOwnerStmt(Node *node) return str.data; } + static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt) { @@ -51,17 +52,18 @@ AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt) appendStringInfo(buf, "ALTER DATABASE %s OWNER TO %s;", - quote_identifier(strVal((String *)stmt->object)), + quote_identifier(strVal((String *) stmt->object)), RoleSpecString(stmt->newowner, true)); } + static void AppendGrantDatabases(StringInfo buf, GrantStmt *stmt) { ListCell *cell = NULL; appendStringInfo(buf, " ON DATABASE "); - foreach (cell, stmt->objects) + foreach(cell, stmt->objects) { char *database = strVal(lfirst(cell)); appendStringInfoString(buf, quote_identifier(database)); @@ -72,6 +74,7 @@ AppendGrantDatabases(StringInfo buf, GrantStmt *stmt) } } + static void AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt) { @@ -84,12 +87,14 @@ AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt) AppendGrantSharedSuffix(buf, stmt); } + static void AppendDefElemConnLimit(StringInfo buf, DefElem *def) { - appendStringInfo(buf, " CONNECTION LIMIT %ld", (long int)defGetNumeric(def)); + appendStringInfo(buf, " CONNECTION LIMIT %ld", (long int) defGetNumeric(def)); } + static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) { @@ -99,7 +104,7 @@ AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) { ListCell *cell = NULL; appendStringInfo(buf, "WITH "); - foreach (cell, stmt->options) + foreach(cell, stmt->options) { DefElem *def = castNode(DefElem, lfirst(cell)); if (strcmp(def->defname, "is_template") == 0) @@ -128,13 +133,14 @@ AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) appendStringInfo(buf, ";"); } + char * DeparseGrantOnDatabaseStmt(Node *node) { GrantStmt *stmt = castNode(GrantStmt, node); Assert(stmt->objtype == OBJECT_DATABASE); - StringInfoData str = {0}; + StringInfoData str = { 0 }; initStringInfo(&str); AppendGrantOnDatabaseStmt(&str, stmt); @@ -142,12 +148,13 @@ DeparseGrantOnDatabaseStmt(Node *node) return str.data; } + char * DeparseAlterDatabaseStmt(Node *node) { AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node); - StringInfoData str = {0}; + StringInfoData str = { 0 }; initStringInfo(&str); AppendAlterDatabaseStmt(&str, stmt); @@ -155,11 +162,12 @@ DeparseAlterDatabaseStmt(Node *node) return str.data; } + #if PG_VERSION_NUM >= PG_VERSION_15 char * DeparseAlterDatabaseRefreshCollStmt(Node *node) { - AlterDatabaseRefreshCollStmt *stmt = (AlterDatabaseRefreshCollStmt *)node; + AlterDatabaseRefreshCollStmt *stmt = (AlterDatabaseRefreshCollStmt *) node; StringInfoData str; initStringInfo(&str); @@ -171,6 +179,7 @@ DeparseAlterDatabaseRefreshCollStmt(Node *node) return str.data; } + #endif static void @@ -183,12 +192,13 @@ AppendAlterDatabaseSetStmt(StringInfo buf, AlterDatabaseSetStmt *stmt) AppendVariableSet(buf, varSetStmt); } + char * DeparseAlterDatabaseSetStmt(Node *node) { AlterDatabaseSetStmt *stmt = castNode(AlterDatabaseSetStmt, node); - StringInfoData str = {0}; + StringInfoData str = { 0 }; initStringInfo(&str); AppendAlterDatabaseSetStmt(&str, stmt); @@ -196,6 +206,7 @@ DeparseAlterDatabaseSetStmt(Node *node) return str.data; } + static void AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) { @@ -325,11 +336,12 @@ AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) } } + char * DeparseCreateDatabaseStmt(Node *node) { CreatedbStmt *stmt = castNode(CreatedbStmt, node); - StringInfoData str = {0}; + StringInfoData str = { 0 }; initStringInfo(&str); AppendCreatedbStmt(&str, stmt); @@ -337,6 +349,7 @@ DeparseCreateDatabaseStmt(Node *node) return str.data; } + static void AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt) { @@ -361,6 +374,7 @@ AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt) } } + char * DeparseDropDatabaseStmt(Node *node) { @@ -372,6 +386,3 @@ DeparseDropDatabaseStmt(Node *node) return str.data; } - - - diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 862eb0bfc..55ec63a6a 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -2769,8 +2769,6 @@ DistRebalanceStrategyRelationId(void) } - - /* return oid of pg_dist_object relation */ Oid DistObjectRelationId(void) @@ -5403,8 +5401,6 @@ DeformedDistShardTupleToShardInterval(Datum *datumArray, bool *isNullArray, } - - /* * CachedRelationLookup performs a cached lookup for the relation * relationName, with the result cached in *cachedOid. diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 6b764dfbb..36e412378 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -42,11 +42,11 @@ extern bool EnforceLocalObjectRestrictions; extern void SwitchToSequentialAndLocalExecutionIfRelationNameTooLong(Oid relationId, char * - finalRelationName); + finalRelationName); extern void SwitchToSequentialAndLocalExecutionIfPartitionNameTooLong(Oid - parentRelationId, + parentRelationId, Oid - partitionRelationId); + partitionRelationId); /* DistOpsOperationType to be used in DistributeObjectOps */ typedef enum DistOpsOperationType @@ -99,7 +99,7 @@ typedef struct DistributeObjectOps #define CITUS_TRUNCATE_TRIGGER_NAME "citus_truncate_trigger" -const DistributeObjectOps *GetDistributeObjectOps(Node *node); +const DistributeObjectOps * GetDistributeObjectOps(Node *node); /* * Flags that can be passed to GetForeignKeyOids to indicate @@ -172,21 +172,23 @@ extern const char *TenantOperationNames[TOTAL_TENANT_OPERATION]; extern void SaveBeginCommandProperties(TransactionStmt *transactionStmt); /* cluster.c - forward declarations */ -extern List *PreprocessClusterStmt(Node *node, const char *clusterCommand, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessClusterStmt(Node *node, const char *clusterCommand, + ProcessUtilityContext processUtilityContext); /* common.c - forward declarations*/ -extern List *PostprocessCreateDistributedObjectFromCatalogStmt(Node *stmt, - const char *queryString); -extern List *PreprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString, +extern List * PostprocessCreateDistributedObjectFromCatalogStmt(Node *stmt, + const char *queryString); +extern List * PreprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString); +extern List * PreprocessDropDistributedObjectStmt(Node *node, const char *queryString, ProcessUtilityContext - processUtilityContext); -extern List *PostprocessAlterDistributedObjectStmt(Node *stmt, const char *queryString); -extern List *PreprocessDropDistributedObjectStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *DropTextSearchConfigObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *DropTextSearchDictObjectAddress(Node *node, bool missing_ok, bool isPostprocess); + processUtilityContext); +extern List * DropTextSearchConfigObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * DropTextSearchDictObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); /* index.c */ typedef void (*PGIndexProcessor)(Form_pg_index, List **, int); @@ -195,78 +197,87 @@ typedef void (*PGIndexProcessor)(Form_pg_index, List **, int); extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest); /* collation.c - forward declarations */ -extern char *CreateCollationDDL(Oid collationId); -extern List *CreateCollationDDLsIdempotent(Oid collationId); -extern List *AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *AlterCollationSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern char *GenerateBackupNameForCollationCollision(const ObjectAddress *address); -extern List *DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern char * CreateCollationDDL(Oid collationId); +extern List * CreateCollationDDLsIdempotent(Oid collationId); +extern List * AlterCollationOwnerObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * RenameCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * AlterCollationSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern char * GenerateBackupNameForCollationCollision(const ObjectAddress *address); +extern List * DefineCollationStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); /* database.c - forward declarations */ -extern List *AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *DatabaseOwnerDDLCommands(const ObjectAddress *address); +extern List * AlterDatabaseOwnerObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +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, +extern List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PostprocessCreateDatabaseStmt(Node *node, const char *queryString); -extern List *PreprocessDropDatabaseStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessAlterDatabaseStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); - /* domain.c - forward declarations */ - extern List *CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterDomainStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *DomainRenameConstraintStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *RenameDomainStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern CreateDomainStmt *RecreateDomainStmt(Oid domainOid); +extern List * PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); + +extern List * PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); + +extern List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString); +extern List * PreprocessDropDatabaseStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); + +/* domain.c - forward declarations */ +extern List * CreateDomainStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * AlterDomainStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * DomainRenameConstraintStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * AlterDomainOwnerStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * RenameDomainStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid); extern Oid get_constraint_typid(Oid conoid); /* extension.c - forward declarations */ extern bool IsDropCitusExtensionStmt(Node *parsetree); -extern List *GetDependentFDWsToExtension(Oid extensionId); +extern List * GetDependentFDWsToExtension(Oid extensionId); extern bool IsCreateAlterExtensionUpdateCitusStmt(Node *parsetree); extern void PreprocessCreateExtensionStmtForCitusColumnar(Node *parsetree); extern void PreprocessAlterExtensionCitusStmtForCitusColumnar(Node *parsetree); extern void PostprocessAlterExtensionCitusStmtForCitusColumnar(Node *parsetree); extern bool ShouldMarkRelationDistributed(Oid relationId); extern void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree); -extern List *PostprocessCreateExtensionStmt(Node *stmt, const char *queryString); -extern List *PreprocessDropExtensionStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PreprocessAlterExtensionSchemaStmt(Node *stmt, - const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *PostprocessAlterExtensionSchemaStmt(Node *stmt, - const char *queryString); -extern List *PreprocessAlterExtensionUpdateStmt(Node *stmt, - const char *queryString, - ProcessUtilityContext - processUtilityContext); +extern List * PostprocessCreateExtensionStmt(Node *stmt, const char *queryString); +extern List * PreprocessDropExtensionStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessAlterExtensionSchemaStmt(Node *stmt, + const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PostprocessAlterExtensionSchemaStmt(Node *stmt, + const char *queryString); +extern List * PreprocessAlterExtensionUpdateStmt(Node *stmt, + const char *queryString, + ProcessUtilityContext + processUtilityContext); extern void PostprocessAlterExtensionCitusUpdateStmt(Node *node); -extern List *PreprocessAlterExtensionContentsStmt(Node *node, - const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *CreateExtensionDDLCommand(const ObjectAddress *extensionAddress); -extern List *AlterExtensionSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *AlterExtensionUpdateStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); +extern List * PreprocessAlterExtensionContentsStmt(Node *node, + const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * CreateExtensionDDLCommand(const ObjectAddress *extensionAddress); +extern List * AlterExtensionSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * AlterExtensionUpdateStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); extern void CreateExtensionWithVersion(char *extname, char *extVersion); extern void AlterExtensionUpdateStmt(char *extname, char *extVersion); extern int GetExtensionVersionNumber(char *extVersion); @@ -285,21 +296,21 @@ extern void ErrorOutForFKeyBetweenPostgresAndCitusLocalTable(Oid localTableId); extern bool ColumnReferencedByAnyForeignKey(char *columnName, Oid relationId); extern bool ColumnAppearsInForeignKey(char *columnName, Oid relationId); extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid - relationId); -extern List *GetReferencingForeignConstaintCommands(Oid relationOid); -extern List *GetForeignConstraintToReferenceTablesCommands(Oid relationId); -extern List *GetForeignConstraintFromOtherReferenceTablesCommands(Oid relationId); -extern List *GetForeignConstraintToDistributedTablesCommands(Oid relationId); -extern List *GetForeignConstraintFromDistributedTablesCommands(Oid relationId); -extern List *GetForeignConstraintCommandsInternal(Oid relationId, int flags); + relationId); +extern List * GetReferencingForeignConstaintCommands(Oid relationOid); +extern List * GetForeignConstraintToReferenceTablesCommands(Oid relationId); +extern List * GetForeignConstraintFromOtherReferenceTablesCommands(Oid relationId); +extern List * GetForeignConstraintToDistributedTablesCommands(Oid relationId); +extern List * GetForeignConstraintFromDistributedTablesCommands(Oid relationId); +extern List * GetForeignConstraintCommandsInternal(Oid relationId, int flags); extern Oid DropFKeysAndUndistributeTable(Oid relationId); extern void DropFKeysRelationInvolvedWithTableType(Oid relationId, int tableTypeFlag); -extern List *GetFKeyCreationCommandsRelationInvolvedWithTableType(Oid relationId, - int tableTypeFlag); +extern List * GetFKeyCreationCommandsRelationInvolvedWithTableType(Oid relationId, + int tableTypeFlag); extern bool AnyForeignKeyDependsOnIndex(Oid indexId); extern bool HasForeignKeyWithLocalTable(Oid relationId); extern bool HasForeignKeyToReferenceTable(Oid relationOid); -extern List *GetForeignKeysFromLocalTables(Oid relationId); +extern List * GetForeignKeysFromLocalTables(Oid relationId); extern bool TableReferenced(Oid relationOid); extern bool TableReferencing(Oid relationOid); extern bool ConstraintIsAUniquenessConstraint(char *inputConstaintName, Oid relationId); @@ -308,269 +319,289 @@ extern bool ConstraintWithNameIsOfType(char *inputConstaintName, Oid relationId, char targetConstraintType); extern bool ConstraintWithIdIsOfType(Oid constraintId, char targetConstraintType); extern bool TableHasExternalForeignKeys(Oid relationId); -extern List *GetForeignKeyOids(Oid relationId, int flags); +extern List * GetForeignKeyOids(Oid relationId, int flags); extern Oid GetReferencedTableId(Oid foreignKeyId); extern Oid GetReferencingTableId(Oid foreignKeyId); extern bool RelationInvolvedInAnyNonInheritedForeignKeys(Oid relationId); /* foreign_data_wrapper.c - forward declarations */ -extern List *PreprocessGrantOnFDWStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern Acl *GetPrivilegesForFDW(Oid FDWOid); +extern List * PreprocessGrantOnFDWStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern Acl * GetPrivilegesForFDW(Oid FDWOid); /* foreign_server.c - forward declarations */ -extern List *PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *GetForeignServerCreateDDLCommand(Oid serverId); +extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * CreateForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * GetForeignServerCreateDDLCommand(Oid serverId); /* foreign_table.c - forward declarations */ -extern List *PreprocessAlterForeignTableSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); +extern List * PreprocessAlterForeignTableSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); /* function.c - forward declarations */ -extern List *PreprocessCreateFunctionStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessCreateFunctionStmt(Node *stmt, - const char *queryString); -extern List *CreateFunctionStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *DefineAggregateStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *PreprocessAlterFunctionStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *AlterFunctionStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *RenameFunctionStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *AlterFunctionOwnerObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *AlterFunctionSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *PreprocessAlterFunctionDependsStmt(Node *stmt, - const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *AlterFunctionDependsStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *PreprocessGrantOnFunctionStmt(Node *node, const char *queryString, +extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PostprocessGrantOnFunctionStmt(Node *node, const char *queryString); +extern List * PostprocessCreateFunctionStmt(Node *stmt, + const char *queryString); +extern List * CreateFunctionStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * DefineAggregateStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * PreprocessAlterFunctionStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * AlterFunctionStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * RenameFunctionStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * AlterFunctionOwnerObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * AlterFunctionSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * PreprocessAlterFunctionDependsStmt(Node *stmt, + const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * AlterFunctionDependsStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessGrantOnFunctionStmt(Node *node, const char *queryString); /* grant.c - forward declarations */ -extern List *PreprocessGrantStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessGrantStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void deparsePrivileges(StringInfo privsString, GrantStmt *grantStmt); extern void deparseGrantees(StringInfo granteesString, GrantStmt *grantStmt); /* index.c - forward declarations */ extern bool IsIndexRenameStmt(RenameStmt *renameStmt); -extern List *PreprocessIndexStmt(Node *createIndexStatement, - const char *createIndexCommand, - ProcessUtilityContext processUtilityContext); -extern char *ChooseIndexName(const char *tabname, Oid namespaceId, - List *colnames, List *exclusionOpNames, - bool primary, bool isconstraint); -extern char *ChooseIndexNameAddition(List *colnames); -extern List *ChooseIndexColumnNames(List *indexElems); +extern List * PreprocessIndexStmt(Node *createIndexStatement, + const char *createIndexCommand, + ProcessUtilityContext processUtilityContext); +extern char * ChooseIndexName(const char *tabname, Oid namespaceId, + List *colnames, List *exclusionOpNames, + bool primary, bool isconstraint); +extern char * ChooseIndexNameAddition(List *colnames); +extern List * ChooseIndexColumnNames(List *indexElems); extern LOCKMODE GetCreateIndexRelationLockMode(IndexStmt *createIndexStatement); -extern List *PreprocessReindexStmt(Node *ReindexStatement, - const char *ReindexCommand, - ProcessUtilityContext processUtilityContext); -extern List *ReindexStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *PreprocessDropIndexStmt(Node *dropIndexStatement, - const char *dropIndexCommand, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessIndexStmt(Node *node, - const char *queryString); +extern List * PreprocessReindexStmt(Node *ReindexStatement, + const char *ReindexCommand, + ProcessUtilityContext processUtilityContext); +extern List * ReindexStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List * PreprocessDropIndexStmt(Node *dropIndexStatement, + const char *dropIndexCommand, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessIndexStmt(Node *node, + const char *queryString); extern void ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement); extern void MarkIndexValid(IndexStmt *indexStmt); -extern List *ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor pgIndexProcessor, int flags); +extern List * ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor + pgIndexProcessor, int flags); extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName); /* objectaddress.c - forward declarations */ -extern List *CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List * CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); /* owned.c - forward declarations */ -extern List *PreprocessDropOwnedStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessDropOwnedStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); /* policy.c - forward declarations */ -extern List *CreatePolicyCommands(Oid relationId); +extern List * CreatePolicyCommands(Oid relationId); extern void ErrorIfUnsupportedPolicy(Relation relation); extern void ErrorIfUnsupportedPolicyExpr(Node *expr); -extern List *PostprocessCreatePolicyStmt(Node *node, const char *queryString); -extern List *PreprocessAlterPolicyStmt(Node *node, const char *queryString, +extern List * PostprocessCreatePolicyStmt(Node *node, const char *queryString); +extern List * PreprocessAlterPolicyStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessDropPolicyStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PreprocessDropPolicyStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); extern bool IsPolicyRenameStmt(RenameStmt *stmt); extern void CreatePolicyEventExtendNames(CreatePolicyStmt *stmt, const char *schemaName, uint64 shardId); extern void AlterPolicyEventExtendNames(AlterPolicyStmt *stmt, const char *schemaName, uint64 shardId); -extern void RenamePolicyEventExtendNames(RenameStmt *stmt, const char *schemaName, uint64 shardId); -extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, uint64 shardId); +extern void RenamePolicyEventExtendNames(RenameStmt *stmt, const char *schemaName, uint64 + shardId); +extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, uint64 + shardId); extern void AddRangeTableEntryToQueryCompat(ParseState *parseState, Relation relation); /* publication.c - forward declarations */ -extern List *PostProcessCreatePublicationStmt(Node *node, const char *queryString); -extern List *CreatePublicationDDLCommandsIdempotent(const ObjectAddress *address); -extern char *CreatePublicationDDLCommand(Oid publicationId); -extern List *PreprocessAlterPublicationStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityCtx); -extern List *GetAlterPublicationDDLCommandsForTable(Oid relationId, bool isAdd); -extern char *GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId, - bool isAdd); -extern List *AlterPublicationOwnerStmtObjectAddress(Node *node, bool missingOk, - bool isPostProcess); -extern List *AlterPublicationStmtObjectAddress(Node *node, bool missingOk, - bool isPostProcess); -extern List *CreatePublicationStmtObjectAddress(Node *node, bool missingOk, - bool isPostProcess); -extern List *RenamePublicationStmtObjectAddress(Node *node, bool missingOk, +extern List * PostProcessCreatePublicationStmt(Node *node, const char *queryString); +extern List * CreatePublicationDDLCommandsIdempotent(const ObjectAddress *address); +extern char * CreatePublicationDDLCommand(Oid publicationId); +extern List * PreprocessAlterPublicationStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityCtx); +extern List * GetAlterPublicationDDLCommandsForTable(Oid relationId, bool isAdd); +extern char * GetAlterPublicationTableDDLCommand(Oid publicationId, Oid relationId, + bool isAdd); +extern List * AlterPublicationOwnerStmtObjectAddress(Node *node, bool missingOk, + bool isPostProcess); +extern List * AlterPublicationStmtObjectAddress(Node *node, bool missingOk, bool isPostProcess); +extern List * CreatePublicationStmtObjectAddress(Node *node, bool missingOk, + bool isPostProcess); +extern List * RenamePublicationStmtObjectAddress(Node *node, bool missingOk, + bool isPostProcess); /* rename.c - forward declarations*/ -extern List *PreprocessRenameStmt(Node *renameStmt, const char *renameCommand, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessRenameStmt(Node *renameStmt, const char *renameCommand, + ProcessUtilityContext processUtilityContext); extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt); -extern List *PreprocessRenameAttributeStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); /* role.c - forward declarations*/ -extern List *PostprocessAlterRoleStmt(Node *stmt, const char *queryString); -extern List *PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString); +extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); extern List * PreprocessAlterRoleRenameStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *GenerateAlterRoleSetCommandForRole(Oid roleid); -extern List *AlterRoleStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterRoleSetStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *PreprocessCreateRoleStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PreprocessDropRoleStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PreprocessGrantRoleStmt(Node *stmt, const char *queryString, +extern List * GenerateAlterRoleSetCommandForRole(Oid roleid); +extern List * AlterRoleStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List * AlterRoleSetStmtObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List * PreprocessCreateRoleStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessDropRoleStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PostprocessGrantRoleStmt(Node *stmt, const char *queryString); -extern List *GenerateCreateOrAlterRoleCommand(Oid roleOid); -extern List *CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List * PreprocessGrantRoleStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString); +extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid); +extern List * CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); extern List * RenameRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); extern void UnmarkRolesDistributed(List *roles); -extern List *FilterDistributedRoles(List *roles); +extern List * FilterDistributedRoles(List *roles); /* schema.c - forward declarations */ -extern List *PostprocessCreateSchemaStmt(Node *node, const char *queryString); -extern List *PreprocessDropSchemaStmt(Node *dropSchemaStatement, - const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt, - const char *alterObjectSchemaCommand); -extern List *PreprocessGrantOnSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *CreateSchemaStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterSchemaOwnerStmtObjectAddress(Node *node, bool missing_ok, - bool isPostprocess); -extern List *AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * PostprocessCreateSchemaStmt(Node *node, const char *queryString); +extern List * PreprocessDropSchemaStmt(Node *dropSchemaStatement, + const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessAlterObjectSchemaStmt(Node *alterObjectSchemaStmt, + const char *alterObjectSchemaCommand); +extern List * PreprocessGrantOnSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * CreateSchemaStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * AlterSchemaOwnerStmtObjectAddress(Node *node, bool missing_ok, + bool isPostprocess); +extern List * AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); /* sequence.c - forward declarations */ -extern List *PreprocessAlterSequenceStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *PostprocessAlterSequenceSchemaStmt(Node *node, const char *queryString); -extern List *PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString); -#if (PG_VERSION_NUM >= PG_VERSION_15) -extern List *PreprocessAlterSequencePersistenceStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *PreprocessSequenceAlterTableStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -#endif -extern List *PreprocessDropSequenceStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *PreprocessRenameSequenceStmt(Node *node, const char *queryString, +extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PreprocessGrantOnSequenceStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessGrantOnSequenceStmt(Node *node, const char *queryString); -extern List *AlterSequenceStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * PreprocessAlterSequenceSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PostprocessAlterSequenceSchemaStmt(Node *node, const char *queryString); +extern List * PreprocessAlterSequenceOwnerStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessAlterSequenceOwnerStmt(Node *node, const char *queryString); #if (PG_VERSION_NUM >= PG_VERSION_15) -extern List *AlterSequencePersistenceStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * PreprocessAlterSequencePersistenceStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PreprocessSequenceAlterTableStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); #endif -extern List *RenameSequenceStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * PreprocessDropSequenceStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * SequenceDropStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * PreprocessRenameSequenceStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessGrantOnSequenceStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessGrantOnSequenceStmt(Node *node, const char *queryString); +extern List * AlterSequenceStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * AlterSequenceSchemaStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * AlterSequenceOwnerStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +#if (PG_VERSION_NUM >= PG_VERSION_15) +extern List * AlterSequencePersistenceStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +#endif +extern List * RenameSequenceStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); extern void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt); extern void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt); -extern char *GenerateBackupNameForSequenceCollision(const ObjectAddress *address); +extern char * GenerateBackupNameForSequenceCollision(const ObjectAddress *address); extern void RenameExistingSequenceWithDifferentTypeIfExists(RangeVar *sequence, Oid desiredSeqTypeId); /* statistics.c - forward declarations */ -extern List *PreprocessCreateStatisticsStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessCreateStatisticsStmt(Node *node, const char *queryString); -extern List *CreateStatisticsStmtObjectAddress(Node *node, bool missingOk, bool isPostprocess); -extern List *PreprocessDropStatisticsStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *DropStatisticsObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); -extern List *AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk, bool isPostprocess); -extern List *PreprocessAlterStatisticsStmt(Node *node, const char *queryString, +extern List * PreprocessCreateStatisticsStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessCreateStatisticsStmt(Node *node, const char *queryString); +extern List * CreateStatisticsStmtObjectAddress(Node *node, bool missingOk, bool + isPostprocess); +extern List * PreprocessDropStatisticsStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern List *PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString); -extern List *GetExplicitStatisticsCommandList(Oid relationId); -extern List *GetExplicitStatisticsSchemaIdList(Oid relationId); -extern List *GetAlterIndexStatisticsCommands(Oid indexOid); +extern List * DropStatisticsObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * PreprocessAlterStatisticsRenameStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PreprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PostprocessAlterStatisticsSchemaStmt(Node *node, const char *queryString); +extern List * AlterStatisticsSchemaStmtObjectAddress(Node *node, bool missingOk, bool + isPostprocess); +extern List * PreprocessAlterStatisticsStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern List * PostprocessAlterStatisticsOwnerStmt(Node *node, const char *queryString); +extern List * GetExplicitStatisticsCommandList(Oid relationId); +extern List * GetExplicitStatisticsSchemaIdList(Oid relationId); +extern List * GetAlterIndexStatisticsCommands(Oid indexOid); /* subscription.c - forward declarations */ -extern Node *ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt); +extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt); /* table.c - forward declarations */ -extern List *PreprocessDropTableStmt(Node *stmt, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessDropTableStmt(Node *stmt, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void PostprocessCreateTableStmt(CreateStmt *createStatement, const char *queryString); extern bool ShouldEnableLocalReferenceForeignKeys(void); -extern List *PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement, - const char *queryString); -extern List *PostprocessAlterTableSchemaStmt(Node *node, const char *queryString); +extern List * PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement, + const char *queryString); +extern List * PostprocessAlterTableSchemaStmt(Node *node, const char *queryString); extern void PrepareAlterTableStmtForConstraint(AlterTableStmt *alterTableStatement, Oid relationId, Constraint *constraint); -extern List *PreprocessAlterTableStmt(Node *node, const char *alterTableCommand, - ProcessUtilityContext processUtilityContext); -extern List *PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString, +extern List * PreprocessAlterTableStmt(Node *node, const char *alterTableCommand, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessAlterTableMoveAllStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PreprocessAlterTableSchemaStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PreprocessAlterTableSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); extern void SkipForeignKeyValidationIfConstraintIsFkey(AlterTableStmt *alterTableStmt, bool processLocalRelation); extern bool IsAlterTableRenameStmt(RenameStmt *renameStmt); @@ -582,144 +613,160 @@ extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *c extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod, char referencingReplicationModel, Var *distributionColumn, uint32 colocationId); -extern List *InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId, - const char *commandString); -extern List *AlterTableSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *MakeNameListFromRangeVar(const RangeVar *rel); +extern List * InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId, + const char *commandString); +extern List * AlterTableSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * MakeNameListFromRangeVar(const RangeVar *rel); extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum); extern bool ConstrTypeUsesIndex(ConstrType constrType); extern bool ConstrTypeCitusCanDefaultName(ConstrType constrType); -extern char *GetAlterColumnWithNextvalDefaultCmd(Oid sequenceOid, Oid relationId, - char *colname, bool missingTableOk); +extern char * GetAlterColumnWithNextvalDefaultCmd(Oid sequenceOid, Oid relationId, + char *colname, bool missingTableOk); extern void ErrorIfTableHasIdentityColumn(Oid relationId); extern void ConvertNewTableIfNecessary(Node *createStmt); extern void ConvertToTenantTableIfNecessary(AlterObjectSchemaStmt *alterObjectSchemaStmt); /* text_search.c - forward declarations */ -extern List *GetCreateTextSearchConfigStatements(const ObjectAddress *address); -extern List *GetCreateTextSearchDictionaryStatements(const ObjectAddress *address); -extern List *CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address); -extern List *CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address); -extern List *CreateTextSearchConfigurationObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *CreateTextSearchDictObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *RenameTextSearchConfigurationStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *RenameTextSearchDictionaryStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterTextSearchConfigurationStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterTextSearchDictionaryStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *TextSearchConfigurationCommentObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *TextSearchDictCommentObjectAddress(Node *node, +extern List * GetCreateTextSearchConfigStatements(const ObjectAddress *address); +extern List * GetCreateTextSearchDictionaryStatements(const ObjectAddress *address); +extern List * CreateTextSearchConfigDDLCommandsIdempotent(const ObjectAddress *address); +extern List * CreateTextSearchDictDDLCommandsIdempotent(const ObjectAddress *address); +extern List * CreateTextSearchConfigurationObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * CreateTextSearchDictObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterTextSearchConfigurationOwnerObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern List *AlterTextSearchDictOwnerObjectAddress(Node *node, - bool missing_ok, bool isPostprocess); -extern char *GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address); -extern char *GenerateBackupNameForTextSearchDict(const ObjectAddress *address); -extern List *get_ts_config_namelist(Oid tsconfigOid); +extern List * RenameTextSearchConfigurationStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * RenameTextSearchDictionaryStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * AlterTextSearchConfigurationStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * AlterTextSearchDictionaryStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * AlterTextSearchConfigurationSchemaStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * AlterTextSearchDictionarySchemaStmtObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * TextSearchConfigurationCommentObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * TextSearchDictCommentObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern List * AlterTextSearchConfigurationOwnerObjectAddress(Node *node, + bool missing_ok, bool + isPostprocess); +extern List * AlterTextSearchDictOwnerObjectAddress(Node *node, + bool missing_ok, bool isPostprocess); +extern char * GenerateBackupNameForTextSearchConfiguration(const ObjectAddress *address); +extern char * GenerateBackupNameForTextSearchDict(const ObjectAddress *address); +extern List * get_ts_config_namelist(Oid tsconfigOid); /* truncate.c - forward declarations */ extern void PreprocessTruncateStatement(TruncateStmt *truncateStatement); /* type.c - forward declarations */ -extern List *PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString, - ProcessUtilityContext - processUtilityContext); -extern Node *CreateTypeStmtByObjectAddress(const ObjectAddress *address); -extern List *CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *AlterTypeSchemaStmtObjectAddress(Node *stmt, - bool missing_ok, bool isPostprocess); -extern List *RenameTypeAttributeStmtObjectAddress(Node *stmt, - bool missing_ok); -extern List *AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); -extern List *CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); -extern char *GenerateBackupNameForTypeCollision(const ObjectAddress *address); +extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString, + ProcessUtilityContext + processUtilityContext); +extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address); +extern List * CompositeTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * CreateEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * AlterTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List * AlterEnumStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); +extern List * RenameTypeStmtObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * AlterTypeSchemaStmtObjectAddress(Node *stmt, + bool missing_ok, bool isPostprocess); +extern List * RenameTypeAttributeStmtObjectAddress(Node *stmt, + bool missing_ok); +extern List * AlterTypeOwnerObjectAddress(Node *stmt, bool missing_ok, bool + isPostprocess); +extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); +extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address); /* function.c - forward declarations */ -extern List *CreateFunctionDDLCommandsIdempotent(const ObjectAddress *functionAddress); -extern char *GetFunctionDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace); -extern char *GenerateBackupNameForProcCollision(const ObjectAddress *address); -extern ObjectWithArgs *ObjectWithArgsFromOid(Oid funcOid); +extern List * CreateFunctionDDLCommandsIdempotent(const ObjectAddress *functionAddress); +extern char * GetFunctionDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace); +extern char * GenerateBackupNameForProcCollision(const ObjectAddress *address); +extern ObjectWithArgs * ObjectWithArgsFromOid(Oid funcOid); extern void UpdateFunctionDistributionInfo(const ObjectAddress *distAddress, int *distribution_argument_index, int *colocationId, bool *forceDelegation); /* vacuum.c - forward declarations */ -extern List *PostprocessVacuumStmt(Node *node, const char *vacuumCommand); +extern List * PostprocessVacuumStmt(Node *node, const char *vacuumCommand); /* view.c - forward declarations */ -extern List *PreprocessViewStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessViewStmt(Node *node, const char *queryString); -extern List *ViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *AlterViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *PreprocessDropViewStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *DropViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern char *CreateViewDDLCommand(Oid viewOid); -extern List *GetViewCreationCommandsOfTable(Oid relationId); -extern char *AlterViewOwnerCommand(Oid viewOid); -extern char *DeparseViewStmt(Node *node); -extern char *DeparseDropViewStmt(Node *node); -extern bool IsViewDistributed(Oid viewOid); -extern List *CreateViewDDLCommandsIdempotent(Oid viewOid); -extern List *PreprocessAlterViewStmt(Node *node, const char *queryString, +extern List * PreprocessViewStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessViewStmt(Node *node, const char *queryString); +extern List * ViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * AlterViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * PreprocessDropViewStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *PostprocessAlterViewStmt(Node *node, const char *queryString); -extern List *PreprocessRenameViewStmt(Node *node, const char *queryString, +extern List * DropViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern char * CreateViewDDLCommand(Oid viewOid); +extern List * GetViewCreationCommandsOfTable(Oid relationId); +extern char * AlterViewOwnerCommand(Oid viewOid); +extern char * DeparseViewStmt(Node *node); +extern char * DeparseDropViewStmt(Node *node); +extern bool IsViewDistributed(Oid viewOid); +extern List * CreateViewDDLCommandsIdempotent(Oid viewOid); +extern List * PreprocessAlterViewStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); -extern List *RenameViewStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List *PreprocessAlterViewSchemaStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessAlterViewSchemaStmt(Node *node, const char *queryString); -extern List *AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); +extern List * PostprocessAlterViewStmt(Node *node, const char *queryString); +extern List * PreprocessRenameViewStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * RenameViewStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); +extern List * PreprocessAlterViewSchemaStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessAlterViewSchemaStmt(Node *node, const char *queryString); +extern List * AlterViewSchemaStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); extern bool IsViewRenameStmt(RenameStmt *renameStmt); /* trigger.c - forward declarations */ -extern List *GetExplicitTriggerCommandList(Oid relationId); +extern List * GetExplicitTriggerCommandList(Oid relationId); extern HeapTuple GetTriggerTupleById(Oid triggerId, bool missingOk); -extern List *GetExplicitTriggerIdList(Oid relationId); -extern List *PostprocessCreateTriggerStmt(Node *node, const char *queryString); -extern List *CreateTriggerStmtObjectAddress(Node *node, bool missingOk, bool isPostprocess); +extern List * GetExplicitTriggerIdList(Oid relationId); +extern List * PostprocessCreateTriggerStmt(Node *node, const char *queryString); +extern List * CreateTriggerStmtObjectAddress(Node *node, bool missingOk, bool + isPostprocess); extern void CreateTriggerEventExtendNames(CreateTrigStmt *createTriggerStmt, char *schemaName, uint64 shardId); -extern List *PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); -extern List *PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString); +extern List * PreprocessAlterTriggerRenameStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); +extern List * PostprocessAlterTriggerRenameStmt(Node *node, const char *queryString); extern void AlterTriggerRenameEventExtendNames(RenameStmt *renameTriggerStmt, char *schemaName, uint64 shardId); -extern List *PostprocessAlterTriggerDependsStmt(Node *node, const char *queryString); -extern List *PreprocessAlterTriggerDependsStmt(Node *node, const char *queryString, - ProcessUtilityContext - processUtilityContext); +extern List * PostprocessAlterTriggerDependsStmt(Node *node, const char *queryString); +extern List * PreprocessAlterTriggerDependsStmt(Node *node, const char *queryString, + ProcessUtilityContext + processUtilityContext); extern void AlterTriggerDependsEventExtendNames( AlterObjectDependsStmt *alterTriggerDependsStmt, char *schemaName, uint64 shardId); extern void ErrorOutForTriggerIfNotSupported(Oid relationId); extern void ErrorIfRelationHasUnsupportedTrigger(Oid relationId); -extern List *PreprocessDropTriggerStmt(Node *node, const char *queryString, - ProcessUtilityContext processUtilityContext); +extern List * PreprocessDropTriggerStmt(Node *node, const char *queryString, + ProcessUtilityContext processUtilityContext); extern void DropTriggerEventExtendNames(DropStmt *dropTriggerStmt, char *schemaName, uint64 shardId); -extern List *CitusCreateTriggerCommandDDLJob(Oid relationId, char *triggerName, - const char *queryString); +extern List * CitusCreateTriggerCommandDDLJob(Oid relationId, char *triggerName, + const char *queryString); extern Oid GetTriggerFunctionId(Oid triggerId); /* cascade_table_operation_for_connected_relations.c */ @@ -746,12 +793,12 @@ typedef enum CascadeOperationType extern void CascadeOperationForFkeyConnectedRelations(Oid relationId, LOCKMODE relLockMode, CascadeOperationType - cascadeOperationType); + cascadeOperationType); extern void CascadeOperationForRelationIdList(List *relationIdList, LOCKMODE lockMode, CascadeOperationType cascadeOperationType); extern void ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList); extern bool RelationIdListHasReferenceTable(List *relationIdList); -extern List *GetFKeyCreationCommandsForRelationIdList(List *relationIdList); +extern List * GetFKeyCreationCommandsForRelationIdList(List *relationIdList); extern void DropRelationForeignKeys(Oid relationId, int flags); extern void SetLocalEnableLocalReferenceForeignKeys(bool state); extern void ExecuteAndLogUtilityCommandListInTableTypeConversionViaSPI( @@ -765,7 +812,7 @@ extern void ExecuteForeignKeyCreateCommandList(List *ddlCommandList, extern void CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys, bool autoConverted); extern bool ShouldAddNewTableToMetadata(Oid relationId); -extern List *GetExplicitIndexOidList(Oid relationId); +extern List * GetExplicitIndexOidList(Oid relationId); extern bool ShouldPropagateSetCommand(VariableSetStmt *setStmt); extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *setCommand); @@ -773,7 +820,7 @@ extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *set extern void CreateCitusLocalTablePartitionOf(CreateStmt *createStatement, Oid relationId, Oid parentRelationId); extern void UpdateAutoConvertedForConnectedRelations(List *relationId, bool - autoConverted); + autoConverted); /* schema_based_sharding.c */ extern bool ShouldUseSchemaBasedSharding(char *schemaName); diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index f7ba8c02b..6d76b03dd 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -231,7 +231,6 @@ extern char * DeparseCreateDatabaseStmt(Node *node); extern char * DeparseDropDatabaseStmt(Node *node); - /* forward declaration for deparse_publication_stmts.c */ extern char * DeparseCreatePublicationStmt(Node *stmt); extern char * DeparseCreatePublicationStmtExtended(Node *node, From 3735bef156c108215e2f4e4431adaf32a4e298c6 Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 13:40:37 +0300 Subject: [PATCH 11/63] Fixes sql comments --- src/backend/distributed/sql/citus--12.1-1--12.2-1.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql b/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql index 94814c48b..5d869f40e 100644 --- a/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql +++ b/src/backend/distributed/sql/citus--12.1-1--12.2-1.sql @@ -1,8 +1,8 @@ -- citus--12.1-1--12.2-1 -/* - * citus_internal_database_command creates a database according to the given command. - */ +-- +-- citus_internal_database_command creates a database according to the given command. + CREATE OR REPLACE FUNCTION pg_catalog.citus_internal_database_command(command text) RETURNS void LANGUAGE C From 5c50d5875756a4b62495c5613ca8e97c5cd5569d Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 15:06:22 +0300 Subject: [PATCH 12/63] Changes EnableCreateDatabasePropagation to false to fix failing tests --- src/backend/distributed/shared_library_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 886517464..00cdb0027 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -1268,7 +1268,7 @@ RegisterCitusConfigVariables(void) "and DROP DATABASE statements to workers"), NULL, &EnableCreateDatabasePropagation, - true, + false, PGC_USERSET, GUC_STANDARD, NULL, NULL, NULL); From 8c98369e215d2166cc86a4902544db7c2e45333d Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 15:33:14 +0300 Subject: [PATCH 13/63] Fixes affected tests --- src/test/regress/expected/multi_extension.out | 3 ++- src/test/regress/expected/upgrade_list_citus_objects.out | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/regress/expected/multi_extension.out b/src/test/regress/expected/multi_extension.out index 295b10c76..43f9c3b98 100644 --- a/src/test/regress/expected/multi_extension.out +++ b/src/test/regress/expected/multi_extension.out @@ -1422,7 +1422,8 @@ ALTER EXTENSION citus UPDATE TO '12.2-1'; SELECT * FROM multi_extension.print_extension_changes(); previous_object | current_object --------------------------------------------------------------------- -(0 rows) + | function citus_internal_database_command(text) void +(1 row) DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff; -- show running version diff --git a/src/test/regress/expected/upgrade_list_citus_objects.out b/src/test/regress/expected/upgrade_list_citus_objects.out index 36bd504e8..942e0336f 100644 --- a/src/test/regress/expected/upgrade_list_citus_objects.out +++ b/src/test/regress/expected/upgrade_list_citus_objects.out @@ -71,6 +71,7 @@ ORDER BY 1; function citus_internal_add_shard_metadata(regclass,bigint,"char",text,text) function citus_internal_add_tenant_schema(oid,integer) function citus_internal_adjust_local_clock_to_remote(cluster_clock) + function citus_internal_database_command(text) function citus_internal_delete_colocation_metadata(integer) function citus_internal_delete_partition_metadata(regclass) function citus_internal_delete_placement_metadata(bigint) @@ -343,5 +344,5 @@ ORDER BY 1; view citus_stat_tenants_local view pg_dist_shard_placement view time_partitions -(333 rows) +(334 rows) From a5e0b9411a9394dd419a00fac72fd613f3776dd9 Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 21:20:19 +0300 Subject: [PATCH 14/63] Adds tests for create and drop database --- src/backend/distributed/commands/database.c | 5 ++ .../deparser/deparse_database_stmts.c | 11 +++-- .../create_drop_database_propagation.out | 46 +++++++++++++++++++ src/test/regress/multi_1_schedule | 1 + .../sql/create_drop_database_propagation.sql | 45 ++++++++++++++++++ 5 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/test/regress/expected/create_drop_database_propagation.out create mode 100644 src/test/regress/sql/create_drop_database_propagation.sql diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index c760aaa70..c7da5d068 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -312,6 +312,11 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString) { + if (EnableCreateDatabasePropagation) + { + EnsureCoordinator(); + } + if (!EnableCreateDatabasePropagation || !ShouldPropagate()) { return NIL; diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 75ab1d489..6ffce3b48 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -274,6 +274,13 @@ AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) appendStringInfo(buf, " ICU_LOCALE %s", quote_literal_cstr(icuLocale)); } + else if (strcmp(option->defname, "icu_rules") == 0) + { + char *icuLocale = defGetString(option); + + appendStringInfo(buf, " ICU_RULES %s", + quote_literal_cstr(icuLocale)); + } else if (strcmp(option->defname, "locale_provider") == 0) { char *localeProvider = defGetString(option); @@ -323,10 +330,6 @@ AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) quote_literal_cstr(strategy)); } #endif - else if (strcmp(option->defname, "location") == 0) - { - /* deprecated option */ - } else { ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out new file mode 100644 index 000000000..34251f9c4 --- /dev/null +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -0,0 +1,46 @@ +set citus.enable_create_database_propagation=on; +create user create_drop_db_test_user; +CREATE DATABASE mydatabase + WITH TEMPLATE = 'template0' + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'en_US.UTF-8' + LC_COLLATE = 'en_US.UTF-8' + LC_CTYPE = 'en_US.UTF-8' + ICU_LOCALE = 'en_US.UTF-8' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = test_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 17343 | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace +(1 row) + +drop database mydatabase; +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +drop user create_drop_db_test_user; +set citus.enable_create_database_propagation=off; diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index ad70f136e..6cd6225ef 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -52,6 +52,7 @@ test: multi_read_from_secondaries test: grant_on_database_propagation test: alter_database_propagation +test: create_drop_database_propagation test: citus_shards diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql new file mode 100644 index 000000000..27820b32b --- /dev/null +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -0,0 +1,45 @@ +set citus.enable_create_database_propagation=on; +create user create_drop_db_test_user; + + +CREATE DATABASE mydatabase + WITH TEMPLATE = 'template0' + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'en_US.UTF-8' + LC_COLLATE = 'en_US.UTF-8' + LC_CTYPE = 'en_US.UTF-8' + ICU_LOCALE = 'en_US.UTF-8' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = test_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; + +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +drop database mydatabase; + +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +drop user create_drop_db_test_user; +set citus.enable_create_database_propagation=off; + + From 25488afccd564a0016eae1fbcdd18201b1f4cb05 Mon Sep 17 00:00:00 2001 From: gindibay Date: Wed, 4 Oct 2023 23:11:48 +0300 Subject: [PATCH 15/63] Changes encoding --- .../create_drop_database_propagation.out | 32 +++++++++---------- .../sql/create_drop_database_propagation.sql | 28 ++++++++-------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index 34251f9c4..5b835567e 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -2,20 +2,20 @@ set citus.enable_create_database_propagation=on; create user create_drop_db_test_user; CREATE DATABASE mydatabase WITH TEMPLATE = 'template0' - OWNER = create_drop_db_test_user - CONNECTION LIMIT = 10 - ENCODING = 'UTF8' - STRATEGY = 'wal_log' - LOCALE = 'en_US.UTF-8' - LC_COLLATE = 'en_US.UTF-8' - LC_CTYPE = 'en_US.UTF-8' - ICU_LOCALE = 'en_US.UTF-8' - LOCALE_PROVIDER = 'icu' - COLLATION_VERSION = '1.0' - TABLESPACE = test_tablespace - ALLOW_CONNECTIONS = true - IS_TEMPLATE = false - OID = 966345; + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'C' + LC_COLLATE = 'C' + LC_CTYPE = 'C' + ICU_LOCALE = 'C' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = test_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, @@ -24,9 +24,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 17343 | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 17343 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace (1 row) drop database mydatabase; diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 27820b32b..487f13826 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -4,20 +4,20 @@ create user create_drop_db_test_user; CREATE DATABASE mydatabase WITH TEMPLATE = 'template0' - OWNER = create_drop_db_test_user - CONNECTION LIMIT = 10 - ENCODING = 'UTF8' - STRATEGY = 'wal_log' - LOCALE = 'en_US.UTF-8' - LC_COLLATE = 'en_US.UTF-8' - LC_CTYPE = 'en_US.UTF-8' - ICU_LOCALE = 'en_US.UTF-8' - LOCALE_PROVIDER = 'icu' - COLLATION_VERSION = '1.0' - TABLESPACE = test_tablespace - ALLOW_CONNECTIONS = true - IS_TEMPLATE = false - OID = 966345; + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'C' + LC_COLLATE = 'C' + LC_CTYPE = 'C' + ICU_LOCALE = 'C' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = test_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, From d0bd20c9b1f7d385b58ce2ded6219ab4a4eaefc6 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 17:11:07 +0300 Subject: [PATCH 16/63] Fixes tests --- .../create_drop_database_propagation.out | 103 +++++++++-- src/test/regress/expected/pg15.out | 168 +++++++++++++----- src/test/regress/pg_regress_multi.pl | 2 +- .../sql/create_drop_database_propagation.sql | 96 ++++++++-- src/test/regress/sql/pg15.sql | 112 ++++++++++++ 5 files changed, 401 insertions(+), 80 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index 5b835567e..98155024c 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -1,46 +1,111 @@ -set citus.enable_create_database_propagation=on; +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :master_port create user create_drop_db_test_user; +set citus.enable_create_database_propagation=on; CREATE DATABASE mydatabase WITH TEMPLATE = 'template0' OWNER = create_drop_db_test_user CONNECTION LIMIT = 10 ENCODING = 'UTF8' - STRATEGY = 'wal_log' - LOCALE = 'C' LC_COLLATE = 'C' LC_CTYPE = 'C' - ICU_LOCALE = 'C' - LOCALE_PROVIDER = 'icu' - COLLATION_VERSION = '1.0' TABLESPACE = test_tablespace ALLOW_CONNECTIONS = true - IS_TEMPLATE = false - OID = 966345; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, + IS_TEMPLATE = false; +SELECT pd.datname , pd.datdba, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 17343 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 17344 | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace (1 row) -drop database mydatabase; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +\c - - - :worker_1_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 17404 | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace +(1 row) + +\c - - - :worker_2_port +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 17404 | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace +(1 row) + +\c - - - :master_port +set citus.enable_create_database_propagation=on; +drop database mydatabase; +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) +\c - - - :worker_1_port +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :worker_2_port +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :master_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_1_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_2_port +drop tablespace create_drop_db_tablespace; +\c - - - :master_port drop user create_drop_db_test_user; -set citus.enable_create_database_propagation=off; diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index fcbb0cd12..2f005070a 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -586,59 +586,19 @@ WHERE f.numeric_column = s.numeric_column; -- test new regex functions -- print order comments that contain the word `fluffily` at least twice SELECT o_comment FROM public.orders WHERE regexp_count(o_comment, 'FluFFily', 1, 'i')>=2 ORDER BY 1; - o_comment ---------------------------------------------------------------------- - al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli - ly regular packages are fluffily even ideas. fluffily final - ng instructions integrate fluffily among the fluffily silent accounts. bli - ructions wake fluffily fluffily final gifts! furiou - s boost blithely fluffily idle ideas? fluffily even pin -(5 rows) - +ERROR: relation "public.orders" does not exist -- print the same items using a different regexp function SELECT o_comment FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1; - o_comment ---------------------------------------------------------------------- - al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli - ly regular packages are fluffily even ideas. fluffily final - ng instructions integrate fluffily among the fluffily silent accounts. bli - ructions wake fluffily fluffily final gifts! furiou - s boost blithely fluffily idle ideas? fluffily even pin -(5 rows) - +ERROR: relation "public.orders" does not exist -- print the position where we find the second fluffily in the comment SELECT o_comment, regexp_instr(o_comment, 'fluffily.*(fluffily)') FROM public.orders ORDER BY 2 desc LIMIT 5; - o_comment | regexp_instr ---------------------------------------------------------------------- - ng instructions integrate fluffily among the fluffily silent accounts. bli | 27 - al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli | 26 - ly regular packages are fluffily even ideas. fluffily final | 25 - s boost blithely fluffily idle ideas? fluffily even pin | 18 - ructions wake fluffily fluffily final gifts! furiou | 15 -(5 rows) - +ERROR: relation "public.orders" does not exist -- print the substrings between two `fluffily` SELECT regexp_substr(o_comment, 'fluffily.*fluffily') FROM public.orders ORDER BY 1 LIMIT 5; - regexp_substr ---------------------------------------------------------------------- - fluffily among the fluffily - fluffily even ideas. fluffily - fluffily fluffily - fluffily fluffily - fluffily idle ideas? fluffily -(5 rows) - +ERROR: relation "public.orders" does not exist -- replace second `fluffily` with `silkily` SELECT regexp_replace(o_comment, 'fluffily', 'silkily', 1, 2) FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1 desc; - regexp_replace ---------------------------------------------------------------------- - s boost blithely fluffily idle ideas? silkily even pin - ructions wake fluffily silkily final gifts! furiou - ng instructions integrate fluffily among the silkily silent accounts. bli - ly regular packages are fluffily even ideas. silkily final - al, bold deposits cajole fluffily silkily final foxes. pending ideas beli -(5 rows) - +ERROR: relation "public.orders" does not exist -- test new COPY features -- COPY TO statements with text format and headers CREATE TABLE copy_test(id int, data int); @@ -1536,3 +1496,121 @@ SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; DROP ROLE rls_tenant_1; DROP ROLE rls_tenant_2; +-- create/drop database for pg > 15 +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :master_port +create user create_drop_db_test_user; +set citus.enable_create_database_propagation=on; +CREATE DATABASE mydatabase + WITH TEMPLATE = 'template0' + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'C' + LC_COLLATE = 'C' + LC_CTYPE = 'C' + ICU_LOCALE = 'C' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = create_drop_db_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 17851 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace +(1 row) + +\c - - - :worker_1_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 18201 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace +(1 row) + +\c - - - :worker_2_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 18174 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace +(1 row) + +\c - - - :master_port +set citus.enable_create_database_propagation=on; +drop database mydatabase; +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :worker_1_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :worker_2_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :master_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_1_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_2_port +drop tablespace create_drop_db_tablespace; +\c - - - :master_port +drop user create_drop_db_test_user; diff --git a/src/test/regress/pg_regress_multi.pl b/src/test/regress/pg_regress_multi.pl index 4cc022198..ba2251e37 100755 --- a/src/test/regress/pg_regress_multi.pl +++ b/src/test/regress/pg_regress_multi.pl @@ -630,7 +630,7 @@ for my $port (@followerWorkerPorts) } } -for my $tablespace ("ts0", "ts1", "ts2") +for my $tablespace ("ts0", "ts1", "ts2", "ts3", "ts4", "ts5") { if (-e catfile($TMP_CHECKDIR, $tablespace)) { diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 487f13826..cfcd21e67 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -1,45 +1,111 @@ -set citus.enable_create_database_propagation=on; + + +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :master_port create user create_drop_db_test_user; +set citus.enable_create_database_propagation=on; CREATE DATABASE mydatabase WITH TEMPLATE = 'template0' OWNER = create_drop_db_test_user CONNECTION LIMIT = 10 ENCODING = 'UTF8' - STRATEGY = 'wal_log' - LOCALE = 'C' LC_COLLATE = 'C' LC_CTYPE = 'C' - ICU_LOCALE = 'C' - LOCALE_PROVIDER = 'icu' - COLLATION_VERSION = '1.0' TABLESPACE = test_tablespace ALLOW_CONNECTIONS = true - IS_TEMPLATE = false - OID = 966345; + IS_TEMPLATE = false; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname , pd.datdba, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; +\c - - - :worker_1_port + +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; +\c - - - :worker_2_port + +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :master_port +set citus.enable_create_database_propagation=on; drop database mydatabase; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname , pd.datdba, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; +\c - - - :worker_1_port + +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :worker_2_port + +SELECT pd.datname , pd.datdba, pd.encoding, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, +pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :master_port + +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_1_port + +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_2_port + +drop tablespace create_drop_db_tablespace; + +\c - - - :master_port + drop user create_drop_db_test_user; -set citus.enable_create_database_propagation=off; diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index fe60222dd..37270771b 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -976,3 +976,115 @@ SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; DROP ROLE rls_tenant_1; DROP ROLE rls_tenant_2; + + +-- create/drop database for pg > 15 + + +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :master_port +create user create_drop_db_test_user; +set citus.enable_create_database_propagation=on; +CREATE DATABASE mydatabase + WITH TEMPLATE = 'template0' + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'C' + LC_COLLATE = 'C' + LC_CTYPE = 'C' + ICU_LOCALE = 'C' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = create_drop_db_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; + +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :worker_1_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + + +\c - - - :worker_2_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + + +\c - - - :master_port +set citus.enable_create_database_propagation=on; +drop database mydatabase; +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + + +\c - - - :worker_1_port +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :worker_2_port + +SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :master_port +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_1_port +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_2_port +drop tablespace create_drop_db_tablespace; + +\c - - - :master_port +drop user create_drop_db_test_user; From b01c9ffb45d0f48df1f1b82db4c8af94ac173f86 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 17:27:07 +0300 Subject: [PATCH 17/63] Removes unnecessary fileds from selects --- .../create_drop_database_propagation.out | 30 +++++++++---------- src/test/regress/expected/pg15.out | 30 +++++++++---------- .../sql/create_drop_database_propagation.sql | 12 ++++---- src/test/regress/sql/pg15.sql | 12 ++++---- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index 98155024c..3321dd289 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -19,7 +19,7 @@ CREATE DATABASE mydatabase TABLESPACE = test_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -27,13 +27,13 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 17344 | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace (1 row) \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -41,13 +41,13 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 17404 | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace (1 row) \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -55,15 +55,15 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 17404 | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace (1 row) \c - - - :master_port set citus.enable_create_database_propagation=on; drop database mydatabase; -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -71,12 +71,12 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -84,12 +84,12 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -97,7 +97,7 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 2f005070a..c0e510ccc 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1524,7 +1524,7 @@ CREATE DATABASE mydatabase ALLOW_CONNECTIONS = true IS_TEMPLATE = false OID = 966345; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1532,13 +1532,13 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 17851 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1546,13 +1546,13 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 18201 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1560,15 +1560,15 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 18174 | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port set citus.enable_create_database_propagation=on; drop database mydatabase; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1576,12 +1576,12 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1589,12 +1589,12 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1602,7 +1602,7 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | datdba | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- (0 rows) diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index cfcd21e67..39344c7d8 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -27,7 +27,7 @@ CREATE DATABASE mydatabase ALLOW_CONNECTIONS = true IS_TEMPLATE = false; -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -38,7 +38,7 @@ WHERE datname = 'mydatabase'; \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -48,7 +48,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -61,7 +61,7 @@ WHERE datname = 'mydatabase'; set citus.enable_create_database_propagation=on; drop database mydatabase; -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -72,7 +72,7 @@ WHERE datname = 'mydatabase'; \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -83,7 +83,7 @@ WHERE datname = 'mydatabase'; \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 37270771b..378726f7c 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1012,7 +1012,7 @@ CREATE DATABASE mydatabase IS_TEMPLATE = false OID = 966345; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1022,7 +1022,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1033,7 +1033,7 @@ WHERE datname = 'mydatabase'; \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1046,7 +1046,7 @@ WHERE datname = 'mydatabase'; \c - - - :master_port set citus.enable_create_database_propagation=on; drop database mydatabase; -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1057,7 +1057,7 @@ WHERE datname = 'mydatabase'; \c - - - :worker_1_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace @@ -1068,7 +1068,7 @@ WHERE datname = 'mydatabase'; \c - - - :worker_2_port -SELECT pd.datname , pd.datdba, pd.encoding, pd.datlocprovider, +SELECT pd.datname, pd.encoding, pd.datlocprovider, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace From 4c797889368e6e2d6897303c46e766476a12c53d Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 17:48:36 +0300 Subject: [PATCH 18/63] Fixes tablespace error --- src/test/regress/expected/create_drop_database_propagation.out | 2 +- src/test/regress/sql/create_drop_database_propagation.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index 3321dd289..71c72a088 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -16,7 +16,7 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' - TABLESPACE = test_tablespace + TABLESPACE = create_drop_db_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; SELECT pd.datname, pd.encoding, diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 39344c7d8..edf8e7891 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -23,7 +23,7 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' - TABLESPACE = test_tablespace + TABLESPACE = create_drop_db_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; From aa47ca8bda94205b30d0f5804848572007ef13a5 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 17:51:01 +0300 Subject: [PATCH 19/63] Fixes tablespace results --- .../expected/create_drop_database_propagation.out | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index 71c72a088..e578cd2eb 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -27,9 +27,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -41,9 +41,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -55,9 +55,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | test_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port From 29093e042a3b1756081b6ae398b23a24769f9db6 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 19:44:57 +0300 Subject: [PATCH 20/63] Removes pg15 changes to test unusal failures --- src/test/regress/expected/pg15.out | 118 ----------------------------- src/test/regress/sql/pg15.sql | 112 --------------------------- 2 files changed, 230 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index c0e510ccc..54cf7e819 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1496,121 +1496,3 @@ SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; DROP ROLE rls_tenant_1; DROP ROLE rls_tenant_2; --- create/drop database for pg > 15 -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; -\c - - - :worker_1_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; -\c - - - :worker_2_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; -\c - - - :master_port -create user create_drop_db_test_user; -set citus.enable_create_database_propagation=on; -CREATE DATABASE mydatabase - WITH TEMPLATE = 'template0' - OWNER = create_drop_db_test_user - CONNECTION LIMIT = 10 - ENCODING = 'UTF8' - STRATEGY = 'wal_log' - LOCALE = 'C' - LC_COLLATE = 'C' - LC_CTYPE = 'C' - ICU_LOCALE = 'C' - LOCALE_PROVIDER = 'icu' - COLLATION_VERSION = '1.0' - TABLESPACE = create_drop_db_tablespace - ALLOW_CONNECTIONS = true - IS_TEMPLATE = false - OID = 966345; -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace ---------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace -(1 row) - -\c - - - :worker_1_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace ---------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace -(1 row) - -\c - - - :worker_2_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace ---------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace -(1 row) - -\c - - - :master_port -set citus.enable_create_database_propagation=on; -drop database mydatabase; -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace ---------------------------------------------------------------------- -(0 rows) - -\c - - - :worker_1_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace ---------------------------------------------------------------------- -(0 rows) - -\c - - - :worker_2_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace ---------------------------------------------------------------------- -(0 rows) - -\c - - - :master_port -drop tablespace create_drop_db_tablespace; -\c - - - :worker_1_port -drop tablespace create_drop_db_tablespace; -\c - - - :worker_2_port -drop tablespace create_drop_db_tablespace; -\c - - - :master_port -drop user create_drop_db_test_user; diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 378726f7c..fe60222dd 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -976,115 +976,3 @@ SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; DROP ROLE rls_tenant_1; DROP ROLE rls_tenant_2; - - --- create/drop database for pg > 15 - - -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; - -\c - - - :worker_1_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; - -\c - - - :worker_2_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; - -\c - - - :master_port -create user create_drop_db_test_user; -set citus.enable_create_database_propagation=on; -CREATE DATABASE mydatabase - WITH TEMPLATE = 'template0' - OWNER = create_drop_db_test_user - CONNECTION LIMIT = 10 - ENCODING = 'UTF8' - STRATEGY = 'wal_log' - LOCALE = 'C' - LC_COLLATE = 'C' - LC_CTYPE = 'C' - ICU_LOCALE = 'C' - LOCALE_PROVIDER = 'icu' - COLLATION_VERSION = '1.0' - TABLESPACE = create_drop_db_tablespace - ALLOW_CONNECTIONS = true - IS_TEMPLATE = false - OID = 966345; - -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - -\c - - - :worker_1_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - - -\c - - - :worker_2_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - - -\c - - - :master_port -set citus.enable_create_database_propagation=on; -drop database mydatabase; -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - - -\c - - - :worker_1_port -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - -\c - - - :worker_2_port - -SELECT pd.datname, pd.encoding, pd.datlocprovider, -pd.datistemplate, pd.datallowconn, pd.datconnlimit, -pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, -pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace -FROM pg_database pd -JOIN pg_authid pa ON pd.datdba = pa.oid -join pg_tablespace pt on pd.dattablespace = pt.oid -WHERE datname = 'mydatabase'; - -\c - - - :master_port -drop tablespace create_drop_db_tablespace; - -\c - - - :worker_1_port -drop tablespace create_drop_db_tablespace; - -\c - - - :worker_2_port -drop tablespace create_drop_db_tablespace; - -\c - - - :master_port -drop user create_drop_db_test_user; From 14618878c80cc7d5449c907e07966192af85bd04 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 20:35:22 +0300 Subject: [PATCH 21/63] Tests error cause --- .../create_drop_database_propagation.out | 27 +++++-------------- .../sql/create_drop_database_propagation.sql | 25 ----------------- 2 files changed, 6 insertions(+), 46 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index e578cd2eb..b2056d84a 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -1,11 +1,3 @@ -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; -\c - - - :worker_1_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; -\c - - - :worker_2_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; \c - - - :master_port create user create_drop_db_test_user; set citus.enable_create_database_propagation=on; @@ -16,7 +8,6 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' - TABLESPACE = create_drop_db_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; SELECT pd.datname, pd.encoding, @@ -27,9 +18,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | pg_default (1 row) \c - - - :worker_1_port @@ -41,9 +32,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | pg_default (1 row) \c - - - :worker_2_port @@ -55,9 +46,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | pg_default (1 row) \c - - - :master_port @@ -101,11 +92,5 @@ WHERE datname = 'mydatabase'; --------------------------------------------------------------------- (0 rows) -\c - - - :master_port -drop tablespace create_drop_db_tablespace; -\c - - - :worker_1_port -drop tablespace create_drop_db_tablespace; -\c - - - :worker_2_port -drop tablespace create_drop_db_tablespace; \c - - - :master_port drop user create_drop_db_test_user; diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index edf8e7891..576274d66 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -1,16 +1,3 @@ - - -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; - -\c - - - :worker_1_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; - -\c - - - :worker_2_port -\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' -CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; - \c - - - :master_port create user create_drop_db_test_user; @@ -23,7 +10,6 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' - TABLESPACE = create_drop_db_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; @@ -92,17 +78,6 @@ JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; -\c - - - :master_port - -drop tablespace create_drop_db_tablespace; - -\c - - - :worker_1_port - -drop tablespace create_drop_db_tablespace; - -\c - - - :worker_2_port - -drop tablespace create_drop_db_tablespace; \c - - - :master_port From c7304abd54680599ca25be3f119879e7ad311880 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 20:36:47 +0300 Subject: [PATCH 22/63] Fixes pg15 file --- src/test/regress/expected/pg15.out | 50 +++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 54cf7e819..fcbb0cd12 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -586,19 +586,59 @@ WHERE f.numeric_column = s.numeric_column; -- test new regex functions -- print order comments that contain the word `fluffily` at least twice SELECT o_comment FROM public.orders WHERE regexp_count(o_comment, 'FluFFily', 1, 'i')>=2 ORDER BY 1; -ERROR: relation "public.orders" does not exist + o_comment +--------------------------------------------------------------------- + al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli + ly regular packages are fluffily even ideas. fluffily final + ng instructions integrate fluffily among the fluffily silent accounts. bli + ructions wake fluffily fluffily final gifts! furiou + s boost blithely fluffily idle ideas? fluffily even pin +(5 rows) + -- print the same items using a different regexp function SELECT o_comment FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1; -ERROR: relation "public.orders" does not exist + o_comment +--------------------------------------------------------------------- + al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli + ly regular packages are fluffily even ideas. fluffily final + ng instructions integrate fluffily among the fluffily silent accounts. bli + ructions wake fluffily fluffily final gifts! furiou + s boost blithely fluffily idle ideas? fluffily even pin +(5 rows) + -- print the position where we find the second fluffily in the comment SELECT o_comment, regexp_instr(o_comment, 'fluffily.*(fluffily)') FROM public.orders ORDER BY 2 desc LIMIT 5; -ERROR: relation "public.orders" does not exist + o_comment | regexp_instr +--------------------------------------------------------------------- + ng instructions integrate fluffily among the fluffily silent accounts. bli | 27 + al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli | 26 + ly regular packages are fluffily even ideas. fluffily final | 25 + s boost blithely fluffily idle ideas? fluffily even pin | 18 + ructions wake fluffily fluffily final gifts! furiou | 15 +(5 rows) + -- print the substrings between two `fluffily` SELECT regexp_substr(o_comment, 'fluffily.*fluffily') FROM public.orders ORDER BY 1 LIMIT 5; -ERROR: relation "public.orders" does not exist + regexp_substr +--------------------------------------------------------------------- + fluffily among the fluffily + fluffily even ideas. fluffily + fluffily fluffily + fluffily fluffily + fluffily idle ideas? fluffily +(5 rows) + -- replace second `fluffily` with `silkily` SELECT regexp_replace(o_comment, 'fluffily', 'silkily', 1, 2) FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1 desc; -ERROR: relation "public.orders" does not exist + regexp_replace +--------------------------------------------------------------------- + s boost blithely fluffily idle ideas? silkily even pin + ructions wake fluffily silkily final gifts! furiou + ng instructions integrate fluffily among the silkily silent accounts. bli + ly regular packages are fluffily even ideas. silkily final + al, bold deposits cajole fluffily silkily final foxes. pending ideas beli +(5 rows) + -- test new COPY features -- COPY TO statements with text format and headers CREATE TABLE copy_test(id int, data int); From acece9818ce08709c51fc8bea4b8e56027cf1a04 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 20:49:19 +0300 Subject: [PATCH 23/63] Rollbacks pg_regress_multi --- src/test/regress/pg_regress_multi.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/pg_regress_multi.pl b/src/test/regress/pg_regress_multi.pl index ba2251e37..4cc022198 100755 --- a/src/test/regress/pg_regress_multi.pl +++ b/src/test/regress/pg_regress_multi.pl @@ -630,7 +630,7 @@ for my $port (@followerWorkerPorts) } } -for my $tablespace ("ts0", "ts1", "ts2", "ts3", "ts4", "ts5") +for my $tablespace ("ts0", "ts1", "ts2") { if (-e catfile($TMP_CHECKDIR, $tablespace)) { From 5eb87839b678c6877ee3d0d3d72bb580475b345e Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 21:34:14 +0300 Subject: [PATCH 24/63] Rollbacks last test --- src/test/regress/multi_1_schedule | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index 6cd6225ef..ad70f136e 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -52,7 +52,6 @@ test: multi_read_from_secondaries test: grant_on_database_propagation test: alter_database_propagation -test: create_drop_database_propagation test: citus_shards From 1d9c02fab902371c956526dee99e000be76dbc1d Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 21:48:28 +0300 Subject: [PATCH 25/63] Changes schedule location --- src/test/regress/multi_1_schedule | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index ad70f136e..fee725307 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -15,6 +15,7 @@ # --- # Tests around schema changes, these are run first, so there's no preexisting objects. # --- +test: create_drop_database_propagation test: multi_extension test: multi_test_helpers multi_test_helpers_superuser multi_create_fdw test: single_node From c3d773ac6f4ea89d8f997343dfae661de0d209f6 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 22:14:12 +0300 Subject: [PATCH 26/63] Changes test order --- src/test/regress/multi_1_schedule | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/multi_1_schedule b/src/test/regress/multi_1_schedule index fee725307..6cd6225ef 100644 --- a/src/test/regress/multi_1_schedule +++ b/src/test/regress/multi_1_schedule @@ -15,7 +15,6 @@ # --- # Tests around schema changes, these are run first, so there's no preexisting objects. # --- -test: create_drop_database_propagation test: multi_extension test: multi_test_helpers multi_test_helpers_superuser multi_create_fdw test: single_node @@ -53,6 +52,7 @@ test: multi_read_from_secondaries test: grant_on_database_propagation test: alter_database_propagation +test: create_drop_database_propagation test: citus_shards From 51d1560b349c1372316a288ddecf486f4b517bc8 Mon Sep 17 00:00:00 2001 From: gindibay Date: Thu, 5 Oct 2023 22:30:06 +0300 Subject: [PATCH 27/63] Adds OID to see the error cause --- src/test/regress/sql/create_drop_database_propagation.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 576274d66..c86523e37 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -13,7 +13,7 @@ CREATE DATABASE mydatabase ALLOW_CONNECTIONS = true IS_TEMPLATE = false; -SELECT pd.datname, pd.encoding, +SELECT pd.oid,pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace From 1f578791bbe628fad4c66421ce65c2ba342d9ff9 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 15:18:16 +0300 Subject: [PATCH 28/63] Fixes pg_dist_object delete problem --- src/backend/distributed/commands/database.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index c7da5d068..fc91ae8c3 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -380,9 +380,6 @@ citus_internal_database_command(PG_FUNCTION_ARGS) char *command = text_to_cstring(commandText); Node *parseTree = ParseTreeNode(command); - ereport(NOTICE, (errmsg("test internal pre"), - errhint("test pre hint"))); - set_config_option("citus.enable_ddl_propagation", "off", (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, GUC_ACTION_LOCAL, true, 0, false); @@ -411,7 +408,7 @@ citus_internal_database_command(PG_FUNCTION_ARGS) { DropdbStmt *stmt = castNode(DropdbStmt, parseTree); - bool missingOk = true; + bool missingOk = false; Oid databaseOid = get_database_oid(stmt->dbname, missingOk); if (!OidIsValid(databaseOid)) @@ -420,14 +417,6 @@ citus_internal_database_command(PG_FUNCTION_ARGS) } else { - /* remove database from pg_dist_object */ - ObjectAddress dbAddress = { 0 }; - ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); - - if (IsObjectDistributed(&dbAddress)) - { - UnmarkObjectDistributed(&dbAddress); - } /* / * remove database from database shards * / */ /* DeleteDatabaseShardByDatabaseIdLocally(databaseOid); */ @@ -486,7 +475,15 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, "SELECT pg_catalog.citus_internal_database_command(%s)", quote_literal_cstr(dropDatabaseCommand)); + /* Delete from pg_dist_object */ + + if (IsObjectDistributed(&dbAddress)) + { + UnmarkObjectDistributed(&dbAddress); + } + /* we execute here to avoid EnsureCoordinator check in ExecuteDistributedDDLJob */ + bool outsideTransaction = false; List *taskList = CreateDDLTaskList(internalDropCommand->data, workerNodes, outsideTransaction); From 94abb074090299cc3bfb0f73150aa7fad67e8062 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 15:22:15 +0300 Subject: [PATCH 29/63] Fixes indentation --- src/backend/distributed/commands/database.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index fc91ae8c3..a12ff3f12 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -417,7 +417,6 @@ citus_internal_database_command(PG_FUNCTION_ARGS) } else { - /* / * remove database from database shards * / */ /* DeleteDatabaseShardByDatabaseIdLocally(databaseOid); */ From 6913496f42ada59742808afbc63f9bbae1c21b68 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 15:24:23 +0300 Subject: [PATCH 30/63] Fixes tests --- src/test/regress/sql/create_drop_database_propagation.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index c86523e37..576274d66 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -13,7 +13,7 @@ CREATE DATABASE mydatabase ALLOW_CONNECTIONS = true IS_TEMPLATE = false; -SELECT pd.oid,pd.datname, pd.encoding, +SELECT pd.datname, pd.encoding, pd.datistemplate, pd.datallowconn, pd.datconnlimit, pd.datcollate , pd. datctype , pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace From a7112fb9651f01846886d5cae2d8312b3b94b86a Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 15:45:05 +0300 Subject: [PATCH 31/63] Adds tablespace to test tablespace statement --- .../create_drop_database_propagation.out | 27 ++++++++++++++----- src/test/regress/pg_regress_multi.pl | 2 +- .../sql/create_drop_database_propagation.sql | 27 +++++++++++++++++-- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index b2056d84a..e578cd2eb 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -1,3 +1,11 @@ +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; \c - - - :master_port create user create_drop_db_test_user; set citus.enable_create_database_propagation=on; @@ -8,6 +16,7 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' + TABLESPACE = create_drop_db_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; SELECT pd.datname, pd.encoding, @@ -18,9 +27,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | pg_default + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -32,9 +41,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | pg_default + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -46,9 +55,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace + datname | encoding | datistemplate | datallowconn | datconnlimit | datcollate | datctype | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | pg_default + mydatabase | 6 | f | t | 10 | C | C | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port @@ -92,5 +101,11 @@ WHERE datname = 'mydatabase'; --------------------------------------------------------------------- (0 rows) +\c - - - :master_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_1_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_2_port +drop tablespace create_drop_db_tablespace; \c - - - :master_port drop user create_drop_db_test_user; diff --git a/src/test/regress/pg_regress_multi.pl b/src/test/regress/pg_regress_multi.pl index 4cc022198..ba2251e37 100755 --- a/src/test/regress/pg_regress_multi.pl +++ b/src/test/regress/pg_regress_multi.pl @@ -630,7 +630,7 @@ for my $port (@followerWorkerPorts) } } -for my $tablespace ("ts0", "ts1", "ts2") +for my $tablespace ("ts0", "ts1", "ts2", "ts3", "ts4", "ts5") { if (-e catfile($TMP_CHECKDIR, $tablespace)) { diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 576274d66..415a03f97 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -1,3 +1,16 @@ + + +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + \c - - - :master_port create user create_drop_db_test_user; @@ -10,6 +23,7 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' LC_COLLATE = 'C' LC_CTYPE = 'C' + TABLESPACE = create_drop_db_tablespace ALLOW_CONNECTIONS = true IS_TEMPLATE = false; @@ -78,9 +92,18 @@ JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; +\c - - - :master_port + +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_1_port + +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_2_port + +drop tablespace create_drop_db_tablespace; \c - - - :master_port drop user create_drop_db_test_user; - - From 6f3655672412243d7634336d6ea4348d8f5b33e3 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 15:47:42 +0300 Subject: [PATCH 32/63] Revert "Removes pg15 changes to test unusal failures" This reverts commit 85963e9cb5f1f9dd405d0c7cf2b8f8de4100066a. --- src/test/regress/expected/pg15.out | 118 +++++++++++++++++++++++++++++ src/test/regress/sql/pg15.sql | 112 +++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index fcbb0cd12..6165990fe 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1536,3 +1536,121 @@ SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; DROP ROLE rls_tenant_1; DROP ROLE rls_tenant_2; +-- create/drop database for pg > 15 +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; +\c - - - :master_port +create user create_drop_db_test_user; +set citus.enable_create_database_propagation=on; +CREATE DATABASE mydatabase + WITH TEMPLATE = 'template0' + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'C' + LC_COLLATE = 'C' + LC_CTYPE = 'C' + ICU_LOCALE = 'C' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = create_drop_db_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace +(1 row) + +\c - - - :worker_1_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace +(1 row) + +\c - - - :worker_2_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- + mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace +(1 row) + +\c - - - :master_port +set citus.enable_create_database_propagation=on; +drop database mydatabase; +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :worker_1_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :worker_2_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace +--------------------------------------------------------------------- +(0 rows) + +\c - - - :master_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_1_port +drop tablespace create_drop_db_tablespace; +\c - - - :worker_2_port +drop tablespace create_drop_db_tablespace; +\c - - - :master_port +drop user create_drop_db_test_user; diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index fe60222dd..378726f7c 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -976,3 +976,115 @@ SET client_min_messages TO ERROR; DROP SCHEMA pg15 CASCADE; DROP ROLE rls_tenant_1; DROP ROLE rls_tenant_2; + + +-- create/drop database for pg > 15 + + +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_1_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :worker_2_port +\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5' +CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace'; + +\c - - - :master_port +create user create_drop_db_test_user; +set citus.enable_create_database_propagation=on; +CREATE DATABASE mydatabase + WITH TEMPLATE = 'template0' + OWNER = create_drop_db_test_user + CONNECTION LIMIT = 10 + ENCODING = 'UTF8' + STRATEGY = 'wal_log' + LOCALE = 'C' + LC_COLLATE = 'C' + LC_CTYPE = 'C' + ICU_LOCALE = 'C' + LOCALE_PROVIDER = 'icu' + COLLATION_VERSION = '1.0' + TABLESPACE = create_drop_db_tablespace + ALLOW_CONNECTIONS = true + IS_TEMPLATE = false + OID = 966345; + +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :worker_1_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + + +\c - - - :worker_2_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + + +\c - - - :master_port +set citus.enable_create_database_propagation=on; +drop database mydatabase; +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + + +\c - - - :worker_1_port +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :worker_2_port + +SELECT pd.datname, pd.encoding, pd.datlocprovider, +pd.datistemplate, pd.datallowconn, pd.datconnlimit, +pd.datcollate , pd. datctype , pd.daticulocale, pd.datcollversion, +pd.datacl, rolname AS database_owner, pa.rolname AS database_owner, pt.spcname AS tablespace +FROM pg_database pd +JOIN pg_authid pa ON pd.datdba = pa.oid +join pg_tablespace pt on pd.dattablespace = pt.oid +WHERE datname = 'mydatabase'; + +\c - - - :master_port +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_1_port +drop tablespace create_drop_db_tablespace; + +\c - - - :worker_2_port +drop tablespace create_drop_db_tablespace; + +\c - - - :master_port +drop user create_drop_db_test_user; From 214ebc4374dccc779b68cc9997a79b624ed4e363 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 16:10:47 +0300 Subject: [PATCH 33/63] Fixes encodings for pg16 --- src/test/regress/expected/pg15.out | 70 +++++++----------------------- src/test/regress/sql/pg15.sql | 8 ++-- 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 6165990fe..2fa43788b 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -586,59 +586,19 @@ WHERE f.numeric_column = s.numeric_column; -- test new regex functions -- print order comments that contain the word `fluffily` at least twice SELECT o_comment FROM public.orders WHERE regexp_count(o_comment, 'FluFFily', 1, 'i')>=2 ORDER BY 1; - o_comment ---------------------------------------------------------------------- - al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli - ly regular packages are fluffily even ideas. fluffily final - ng instructions integrate fluffily among the fluffily silent accounts. bli - ructions wake fluffily fluffily final gifts! furiou - s boost blithely fluffily idle ideas? fluffily even pin -(5 rows) - +ERROR: relation "public.orders" does not exist -- print the same items using a different regexp function SELECT o_comment FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1; - o_comment ---------------------------------------------------------------------- - al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli - ly regular packages are fluffily even ideas. fluffily final - ng instructions integrate fluffily among the fluffily silent accounts. bli - ructions wake fluffily fluffily final gifts! furiou - s boost blithely fluffily idle ideas? fluffily even pin -(5 rows) - +ERROR: relation "public.orders" does not exist -- print the position where we find the second fluffily in the comment SELECT o_comment, regexp_instr(o_comment, 'fluffily.*(fluffily)') FROM public.orders ORDER BY 2 desc LIMIT 5; - o_comment | regexp_instr ---------------------------------------------------------------------- - ng instructions integrate fluffily among the fluffily silent accounts. bli | 27 - al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli | 26 - ly regular packages are fluffily even ideas. fluffily final | 25 - s boost blithely fluffily idle ideas? fluffily even pin | 18 - ructions wake fluffily fluffily final gifts! furiou | 15 -(5 rows) - +ERROR: relation "public.orders" does not exist -- print the substrings between two `fluffily` SELECT regexp_substr(o_comment, 'fluffily.*fluffily') FROM public.orders ORDER BY 1 LIMIT 5; - regexp_substr ---------------------------------------------------------------------- - fluffily among the fluffily - fluffily even ideas. fluffily - fluffily fluffily - fluffily fluffily - fluffily idle ideas? fluffily -(5 rows) - +ERROR: relation "public.orders" does not exist -- replace second `fluffily` with `silkily` SELECT regexp_replace(o_comment, 'fluffily', 'silkily', 1, 2) FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1 desc; - regexp_replace ---------------------------------------------------------------------- - s boost blithely fluffily idle ideas? silkily even pin - ructions wake fluffily silkily final gifts! furiou - ng instructions integrate fluffily among the silkily silent accounts. bli - ly regular packages are fluffily even ideas. silkily final - al, bold deposits cajole fluffily silkily final foxes. pending ideas beli -(5 rows) - +ERROR: relation "public.orders" does not exist -- test new COPY features -- COPY TO statements with text format and headers CREATE TABLE copy_test(id int, data int); @@ -1554,10 +1514,10 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'C' - LC_COLLATE = 'C' - LC_CTYPE = 'C' - ICU_LOCALE = 'C' + LOCALE = 'en_US.UTF-8' + LC_COLLATE = 'en_US.UTF-8' + LC_CTYPE = 'en_US.UTF-8' + ICU_LOCALE = 'en_US.UTF-8' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace @@ -1572,9 +1532,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -1586,9 +1546,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -1600,9 +1560,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | C | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 378726f7c..86afdea2b 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1001,10 +1001,10 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'C' - LC_COLLATE = 'C' - LC_CTYPE = 'C' - ICU_LOCALE = 'C' + LOCALE = 'en_US.UTF-8' + LC_COLLATE = 'en_US.UTF-8' + LC_CTYPE = 'en_US.UTF-8' + ICU_LOCALE = 'en_US.UTF-8' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace From 3050b0eab9337868df75ade7c7bbcf7c636b909f Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 16:41:07 +0300 Subject: [PATCH 34/63] Fixes pg15 tests --- src/test/regress/expected/pg15.out | 50 +++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 2fa43788b..13a3bcd7b 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -586,19 +586,59 @@ WHERE f.numeric_column = s.numeric_column; -- test new regex functions -- print order comments that contain the word `fluffily` at least twice SELECT o_comment FROM public.orders WHERE regexp_count(o_comment, 'FluFFily', 1, 'i')>=2 ORDER BY 1; -ERROR: relation "public.orders" does not exist + o_comment +--------------------------------------------------------------------- + al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli + ly regular packages are fluffily even ideas. fluffily final + ng instructions integrate fluffily among the fluffily silent accounts. bli + ructions wake fluffily fluffily final gifts! furiou + s boost blithely fluffily idle ideas? fluffily even pin +(5 rows) + -- print the same items using a different regexp function SELECT o_comment FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1; -ERROR: relation "public.orders" does not exist + o_comment +--------------------------------------------------------------------- + al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli + ly regular packages are fluffily even ideas. fluffily final + ng instructions integrate fluffily among the fluffily silent accounts. bli + ructions wake fluffily fluffily final gifts! furiou + s boost blithely fluffily idle ideas? fluffily even pin +(5 rows) + -- print the position where we find the second fluffily in the comment SELECT o_comment, regexp_instr(o_comment, 'fluffily.*(fluffily)') FROM public.orders ORDER BY 2 desc LIMIT 5; -ERROR: relation "public.orders" does not exist + o_comment | regexp_instr +--------------------------------------------------------------------- + ng instructions integrate fluffily among the fluffily silent accounts. bli | 27 + al, bold deposits cajole fluffily fluffily final foxes. pending ideas beli | 26 + ly regular packages are fluffily even ideas. fluffily final | 25 + s boost blithely fluffily idle ideas? fluffily even pin | 18 + ructions wake fluffily fluffily final gifts! furiou | 15 +(5 rows) + -- print the substrings between two `fluffily` SELECT regexp_substr(o_comment, 'fluffily.*fluffily') FROM public.orders ORDER BY 1 LIMIT 5; -ERROR: relation "public.orders" does not exist + regexp_substr +--------------------------------------------------------------------- + fluffily among the fluffily + fluffily even ideas. fluffily + fluffily fluffily + fluffily fluffily + fluffily idle ideas? fluffily +(5 rows) + -- replace second `fluffily` with `silkily` SELECT regexp_replace(o_comment, 'fluffily', 'silkily', 1, 2) FROM public.orders WHERE regexp_like(o_comment, 'fluffily.*fluffily') ORDER BY 1 desc; -ERROR: relation "public.orders" does not exist + regexp_replace +--------------------------------------------------------------------- + s boost blithely fluffily idle ideas? silkily even pin + ructions wake fluffily silkily final gifts! furiou + ng instructions integrate fluffily among the silkily silent accounts. bli + ly regular packages are fluffily even ideas. silkily final + al, bold deposits cajole fluffily silkily final foxes. pending ideas beli +(5 rows) + -- test new COPY features -- COPY TO statements with text format and headers CREATE TABLE copy_test(id int, data int); From 576264ceca5f9cee0825f8d2a5523004592a888b Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 17:01:27 +0300 Subject: [PATCH 35/63] Fixes UTF error --- src/test/regress/expected/pg15.out | 14 +++++++------- src/test/regress/sql/pg15.sql | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 13a3bcd7b..57a095c12 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1554,10 +1554,10 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'en_US.UTF-8' - LC_COLLATE = 'en_US.UTF-8' - LC_CTYPE = 'en_US.UTF-8' - ICU_LOCALE = 'en_US.UTF-8' + LOCALE = 'en_US.utf-8' + LC_COLLATE = 'en_US.utf-8' + LC_CTYPE = 'en_US.utf-8' + ICU_LOCALE = 'en_US.utf-8' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace @@ -1574,7 +1574,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf-8 | en_US.utf-8 | en_US.utf-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -1588,7 +1588,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf-8 | en_US.utf-8 | en_US.utf-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -1602,7 +1602,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.UTF-8 | en_US.UTF-8 | en_US.UTF-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf-8 | en_US.utf-8 | en_US.utf-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 86afdea2b..ac5f6eec1 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1001,10 +1001,10 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'en_US.UTF-8' - LC_COLLATE = 'en_US.UTF-8' - LC_CTYPE = 'en_US.UTF-8' - ICU_LOCALE = 'en_US.UTF-8' + LOCALE = 'en_US.utf-8' + LC_COLLATE = 'en_US.utf-8' + LC_CTYPE = 'en_US.utf-8' + ICU_LOCALE = 'en_US.utf-8' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace From 031b6480f2460c61d1ba68799b9bcb704b0a5331 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 17:03:57 +0300 Subject: [PATCH 36/63] Fixes locale --- src/test/regress/expected/pg15.out | 14 +++++++------- src/test/regress/sql/pg15.sql | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 57a095c12..338e33c5c 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1554,10 +1554,10 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'en_US.utf-8' - LC_COLLATE = 'en_US.utf-8' - LC_CTYPE = 'en_US.utf-8' - ICU_LOCALE = 'en_US.utf-8' + LOCALE = 'en_US.utf8' + LC_COLLATE = 'en_US.utf8' + LC_CTYPE = 'en_US.utf8' + ICU_LOCALE = 'en_US.utf8' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace @@ -1574,7 +1574,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf-8 | en_US.utf-8 | en_US.utf-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -1588,7 +1588,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf-8 | en_US.utf-8 | en_US.utf-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -1602,7 +1602,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf-8 | en_US.utf-8 | en_US.utf-8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index ac5f6eec1..1c1936dfc 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1001,10 +1001,10 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'en_US.utf-8' - LC_COLLATE = 'en_US.utf-8' - LC_CTYPE = 'en_US.utf-8' - ICU_LOCALE = 'en_US.utf-8' + LOCALE = 'en_US.utf8' + LC_COLLATE = 'en_US.utf8' + LC_CTYPE = 'en_US.utf8' + ICU_LOCALE = 'en_US.utf8' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace From da46878a8f334c58db93956edf7db94a7f4b48f4 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 17:50:10 +0300 Subject: [PATCH 37/63] Fixes Locale --- src/test/regress/expected/pg15.out | 16 ++++++++-------- src/test/regress/sql/pg15.sql | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 338e33c5c..e210ac6e3 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1554,7 +1554,7 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'en_US.utf8' + LOCALE = '' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8' ICU_LOCALE = 'en_US.utf8' @@ -1572,9 +1572,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -1586,9 +1586,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -1600,9 +1600,9 @@ FROM pg_database pd JOIN pg_authid pa ON pd.datdba = pa.oid join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; - datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace + datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port @@ -1653,4 +1653,4 @@ drop tablespace create_drop_db_tablespace; \c - - - :worker_2_port drop tablespace create_drop_db_tablespace; \c - - - :master_port -drop user create_drop_db_test_user; +drop user create_drop_db_test_user; \ No newline at end of file diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 1c1936dfc..3fc4cf0b2 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1001,7 +1001,7 @@ CREATE DATABASE mydatabase CONNECTION LIMIT = 10 ENCODING = 'UTF8' STRATEGY = 'wal_log' - LOCALE = 'en_US.utf8' + LOCALE = '' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8' ICU_LOCALE = 'en_US.utf8' From ddea1c897b25fdb09c26b43510590e81c460e86e Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 18:02:43 +0300 Subject: [PATCH 38/63] Removes iculocale --- src/test/regress/expected/pg15.out | 4 ++-- src/test/regress/sql/pg15.sql | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index e210ac6e3..76a89706e 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1557,7 +1557,7 @@ CREATE DATABASE mydatabase LOCALE = '' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8' - ICU_LOCALE = 'en_US.utf8' + ICU_LOCALE = '' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace @@ -1574,7 +1574,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 3fc4cf0b2..32ced0750 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1004,7 +1004,7 @@ CREATE DATABASE mydatabase LOCALE = '' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8' - ICU_LOCALE = 'en_US.utf8' + ICU_LOCALE = '' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace From 32d74d95218211708cb58d14d19fc638b11eeb4d Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 18:14:00 +0300 Subject: [PATCH 39/63] Fixes collate and ctype --- src/test/regress/expected/pg15.out | 4 ++-- src/test/regress/sql/pg15.sql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 76a89706e..739985d4f 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1555,8 +1555,8 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' STRATEGY = 'wal_log' LOCALE = '' - LC_COLLATE = 'en_US.utf8' - LC_CTYPE = 'en_US.utf8' + LC_COLLATE = 'POSIX' + LC_CTYPE = 'POSIX' ICU_LOCALE = '' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index 32ced0750..ddc02b2e4 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1002,8 +1002,8 @@ CREATE DATABASE mydatabase ENCODING = 'UTF8' STRATEGY = 'wal_log' LOCALE = '' - LC_COLLATE = 'en_US.utf8' - LC_CTYPE = 'en_US.utf8' + LC_COLLATE = 'POSIX' + LC_CTYPE = 'POSIX' ICU_LOCALE = '' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' From d55ecc23ae175072a84f283e7565fa1289473fd5 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 18:33:10 +0300 Subject: [PATCH 40/63] Updates test results --- src/test/regress/expected/pg15.out | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 739985d4f..6cf7a04a5 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1557,7 +1557,7 @@ CREATE DATABASE mydatabase LOCALE = '' LC_COLLATE = 'POSIX' LC_CTYPE = 'POSIX' - ICU_LOCALE = '' + ICU_LOCALE = 'und' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace @@ -1574,7 +1574,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -1588,7 +1588,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -1602,7 +1602,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | en_US.utf8 | en_US.utf8 | en_US.utf8 | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port From 7bccf9318327272ffaee349cb3ab6105f9cf1c86 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 18:58:52 +0300 Subject: [PATCH 41/63] Fixes icu locale --- src/test/regress/sql/pg15.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/sql/pg15.sql b/src/test/regress/sql/pg15.sql index ddc02b2e4..f0c6706d2 100644 --- a/src/test/regress/sql/pg15.sql +++ b/src/test/regress/sql/pg15.sql @@ -1004,7 +1004,7 @@ CREATE DATABASE mydatabase LOCALE = '' LC_COLLATE = 'POSIX' LC_CTYPE = 'POSIX' - ICU_LOCALE = '' + ICU_LOCALE = 'und' LOCALE_PROVIDER = 'icu' COLLATION_VERSION = '1.0' TABLESPACE = create_drop_db_tablespace From 09d201d1a8f57fcb022355171906b3b008deacff Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 6 Oct 2023 19:14:21 +0300 Subject: [PATCH 42/63] Fixes pg15 output --- src/test/regress/expected/pg15.out | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/regress/expected/pg15.out b/src/test/regress/expected/pg15.out index 6cf7a04a5..caee521a7 100644 --- a/src/test/regress/expected/pg15.out +++ b/src/test/regress/expected/pg15.out @@ -1574,7 +1574,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | und | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_1_port @@ -1588,7 +1588,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | und | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :worker_2_port @@ -1602,7 +1602,7 @@ join pg_tablespace pt on pd.dattablespace = pt.oid WHERE datname = 'mydatabase'; datname | encoding | datlocprovider | datistemplate | datallowconn | datconnlimit | datcollate | datctype | daticulocale | datcollversion | datacl | database_owner | database_owner | tablespace --------------------------------------------------------------------- - mydatabase | 6 | i | f | t | 10 | C | C | | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace + mydatabase | 6 | i | f | t | 10 | C | C | und | 1.0 | | create_drop_db_test_user | create_drop_db_test_user | create_drop_db_tablespace (1 row) \c - - - :master_port From 0bf1c2c139afc02bf3ee7076d152879f536f6f84 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 13:27:12 +0300 Subject: [PATCH 43/63] Refactors the code to make more managable --- .../distributed/deparser/citus_deparseutils.c | 56 +++++++ .../deparser/deparse_database_stmts.c | 139 +++--------------- src/include/distributed/deparser.h | 14 ++ 3 files changed, 89 insertions(+), 120 deletions(-) create mode 100644 src/backend/distributed/deparser/citus_deparseutils.c diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c new file mode 100644 index 000000000..b2798d3e1 --- /dev/null +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -0,0 +1,56 @@ +#include "postgres.h" +#include "utils/builtins.h" +#include "commands/defrem.h" +#include "utils/elog.h" +#include "utils/rel.h" +#include "utils/relcache.h" +#include "utils/syscache.h" +#include "utils/typcache.h" +#include "distributed/deparser.h" + + + +void +handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_formats, int + opt_formats_len) +{ + const char *name = option->defname; + int i; + + for (i = 0; i < opt_formats_len; i++) + { + if (strcmp(name, opt_formats[i].name) == 0) + { + switch (opt_formats[i].type) + { + case T_String: + { + char *value = defGetString(option); + appendStringInfo(buf, opt_formats[i].format, quote_identifier(value)); + break; + } + + case T_Integer: + { + int32 value = defGetInt32(option); + appendStringInfo(buf, opt_formats[i].format, value); + break; + } + + case T_Boolean: + { + bool value = defGetBoolean(option); + appendStringInfo(buf, opt_formats[i].format, value ? "true" : + "false"); + break; + } + + default: + + /* Should not happen */ + elog(ERROR, "unrecognized option type: %d", opt_formats[i].type); + } + return; + } + } +} diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 6ffce3b48..6ae0a0e59 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -207,8 +207,24 @@ DeparseAlterDatabaseSetStmt(Node *node) } +const struct option_format option_formats[] = { + { "template", " TEMPLATE %s", T_String }, + { "owner", " OWNER %s", T_String }, + { "tablespace", " TABLESPACE %s", T_String }, + { "connection_limit", " CONNECTION LIMIT %d", T_Integer }, + { "encoding", " ENCODING %s", T_String }, + { "lc_collate", " LC_COLLATE %s", T_String }, + { "lc_ctype", " LC_CTYPE %s", T_String }, + { "icu_locale", " ICU_LOCALE %s", T_String }, + { "icu_rules", " ICU_RULES %s", T_String }, + { "locale_provider", " LOCALE_PROVIDER %s", T_String }, + { "is_template", " IS_TEMPLATE %s", T_Boolean }, + { "allow_connections", " ALLOW_CONNECTIONS %s", T_Boolean }, +}; + + static void -AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) +AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt) { appendStringInfo(buf, "CREATE DATABASE %s", @@ -218,124 +234,7 @@ AppendCreatedbStmt(StringInfo buf, CreatedbStmt *stmt) foreach_ptr(option, stmt->options) { - if (strcmp(option->defname, "tablespace") == 0) - { - char *tablespaceName = defGetString(option); - - appendStringInfo(buf, " TABLESPACE %s", - quote_identifier(tablespaceName)); - } - else if (strcmp(option->defname, "owner") == 0) - { - char *owner = defGetString(option); - - appendStringInfo(buf, " OWNER %s", - quote_identifier(owner)); - } - else if (strcmp(option->defname, "template") == 0) - { - char *template = defGetString(option); - - appendStringInfo(buf, " TEMPLATE %s", - quote_identifier(template)); - } - else if (strcmp(option->defname, "encoding") == 0) - { - char *encoding = defGetString(option); - - appendStringInfo(buf, " ENCODING %s", - quote_literal_cstr(encoding)); - } - else if (strcmp(option->defname, "locale") == 0) - { - char *locale = defGetString(option); - - appendStringInfo(buf, " LOCALE %s", - quote_literal_cstr(locale)); - } - else if (strcmp(option->defname, "lc_collate") == 0) - { - char *lc_collate = defGetString(option); - - appendStringInfo(buf, " LC_COLLATE %s", - quote_literal_cstr(lc_collate)); - } - else if (strcmp(option->defname, "lc_ctype") == 0) - { - char *lc_ctype = defGetString(option); - - appendStringInfo(buf, " LC_CTYPE %s", - quote_literal_cstr(lc_ctype)); - } - else if (strcmp(option->defname, "icu_locale") == 0) - { - char *icuLocale = defGetString(option); - - appendStringInfo(buf, " ICU_LOCALE %s", - quote_literal_cstr(icuLocale)); - } - else if (strcmp(option->defname, "icu_rules") == 0) - { - char *icuLocale = defGetString(option); - - appendStringInfo(buf, " ICU_RULES %s", - quote_literal_cstr(icuLocale)); - } - else if (strcmp(option->defname, "locale_provider") == 0) - { - char *localeProvider = defGetString(option); - - appendStringInfo(buf, " LOCALE_PROVIDER %s", - quote_literal_cstr(localeProvider)); - } - else if (strcmp(option->defname, "is_template") == 0) - { - bool isTemplate = defGetBoolean(option); - - appendStringInfo(buf, " IS_TEMPLATE %s", - isTemplate ? "true" : "false"); - } - else if (strcmp(option->defname, "allow_connections") == 0) - { - bool allowConnections = defGetBoolean(option); - - appendStringInfo(buf, " ALLOW_CONNECTIONS %s", - allowConnections ? "true" : "false"); - } - else if (strcmp(option->defname, "connection_limit") == 0) - { - int connectionLimit = defGetInt32(option); - - appendStringInfo(buf, " CONNECTION_LIMIT %d", connectionLimit); - } -#if PG_VERSION_NUM >= PG_VERSION_15 - else if (strcmp(option->defname, "collation_version") == 0) - { - char *collationVersion = defGetString(option); - - appendStringInfo(buf, " COLLATION_VERSION %s", - quote_literal_cstr(collationVersion)); - } - else if (strcmp(option->defname, "oid") == 0) - { - Oid objectId = defGetObjectId(option); - - appendStringInfo(buf, " OID %d", objectId); - } - else if (strcmp(option->defname, "strategy") == 0) - { - char *strategy = defGetString(option); - - appendStringInfo(buf, " STRATEGY %s", - quote_literal_cstr(strategy)); - } -#endif - else - { - ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized CREATE DATABASE option \"%s\"", - option->defname))); - } + handleOption(buf, option, option_formats, lengthof(option_formats)); } } @@ -347,7 +246,7 @@ DeparseCreateDatabaseStmt(Node *node) StringInfoData str = { 0 }; initStringInfo(&str); - AppendCreatedbStmt(&str, stmt); + AppendCreateDatabaseStmt(&str, stmt); return str.data; } diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 6d76b03dd..b55287978 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -121,6 +121,20 @@ extern void AppendGrantedByInGrant(StringInfo buf, GrantStmt *stmt); extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt); extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt); +/* Common deparser utils */ + +struct option_format +{ + const char *name; + const char *format; + int type; +}; + + +extern void handleOption(StringInfo buf, DefElem *option, const struct + option_format *opt_formats, int + opt_formats_len); + /* forward declarations for deparse_statistics_stmts.c */ extern char * DeparseCreateStatisticsStmt(Node *node); From 82358fb37d9d7d859c9d67e7491194745c2058b5 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 13:28:23 +0300 Subject: [PATCH 44/63] Fixes indentation --- src/backend/distributed/deparser/citus_deparseutils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index b2798d3e1..9b694e726 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -9,7 +9,6 @@ #include "distributed/deparser.h" - void handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_formats, int opt_formats_len) From e7f80580164ce3dab5c40e243256e2b9c31a9d4f Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 13:46:54 +0300 Subject: [PATCH 45/63] Removes T_Boolean since it breaks pg14 compile --- .../distributed/deparser/citus_deparseutils.c | 46 ++++++++----------- .../deparser/deparse_database_stmts.c | 24 +++++----- src/include/distributed/deparser.h | 2 +- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 9b694e726..9e65f5700 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -20,36 +20,26 @@ handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_fo { if (strcmp(name, opt_formats[i].name) == 0) { - switch (opt_formats[i].type) + if (strcmp(opt_formats[i].type, "string") == 0) { - case T_String: - { - char *value = defGetString(option); - appendStringInfo(buf, opt_formats[i].format, quote_identifier(value)); - break; - } - - case T_Integer: - { - int32 value = defGetInt32(option); - appendStringInfo(buf, opt_formats[i].format, value); - break; - } - - case T_Boolean: - { - bool value = defGetBoolean(option); - appendStringInfo(buf, opt_formats[i].format, value ? "true" : - "false"); - break; - } - - default: - - /* Should not happen */ - elog(ERROR, "unrecognized option type: %d", opt_formats[i].type); + char *value = defGetString(option); + appendStringInfo(buf, opt_formats[i].format, quote_identifier(value)); } - return; + else if (strcmp(opt_formats[i].type, "integer") == 0) + { + int32 value = defGetInt32(option); + appendStringInfo(buf, opt_formats[i].format, value); + } + else if (strcmp(opt_formats[i].type, "boolean") == 0) + { + bool value = defGetBoolean(option); + appendStringInfo(buf, opt_formats[i].format, value ? "true" : "false"); + } + else + { + elog(ERROR, "unrecognized option type: %s", opt_formats[i].type); + } + break; } } } diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 6ae0a0e59..094c6fc1e 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -208,18 +208,18 @@ DeparseAlterDatabaseSetStmt(Node *node) const struct option_format option_formats[] = { - { "template", " TEMPLATE %s", T_String }, - { "owner", " OWNER %s", T_String }, - { "tablespace", " TABLESPACE %s", T_String }, - { "connection_limit", " CONNECTION LIMIT %d", T_Integer }, - { "encoding", " ENCODING %s", T_String }, - { "lc_collate", " LC_COLLATE %s", T_String }, - { "lc_ctype", " LC_CTYPE %s", T_String }, - { "icu_locale", " ICU_LOCALE %s", T_String }, - { "icu_rules", " ICU_RULES %s", T_String }, - { "locale_provider", " LOCALE_PROVIDER %s", T_String }, - { "is_template", " IS_TEMPLATE %s", T_Boolean }, - { "allow_connections", " ALLOW_CONNECTIONS %s", T_Boolean }, + { "template", " TEMPLATE %s", "string" }, + { "owner", " OWNER %s", "string" }, + { "tablespace", " TABLESPACE %s", "string" }, + { "connection_limit", " CONNECTION LIMIT %d", "integer" }, + { "encoding", " ENCODING %s", "string" }, + { "lc_collate", " LC_COLLATE %s", "string" }, + { "lc_ctype", " LC_CTYPE %s", "string" }, + { "icu_locale", " ICU_LOCALE %s", "string" }, + { "icu_rules", " ICU_RULES %s", "string" }, + { "locale_provider", " LOCALE_PROVIDER %s", "string" }, + { "is_template", " IS_TEMPLATE %s", "boolean" }, + { "allow_connections", " ALLOW_CONNECTIONS %s", "boolean" }, }; diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index b55287978..428c91a5f 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -127,7 +127,7 @@ struct option_format { const char *name; const char *format; - int type; + const char *type; }; From 6096a0ed5744fd2c96aac5b8af4abf63339eac95 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 15:14:13 +0300 Subject: [PATCH 46/63] Adds missing types --- .../distributed/deparser/citus_deparseutils.c | 10 +++++ .../deparser/deparse_database_stmts.c | 38 ++++++++++--------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 9e65f5700..546360fdf 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -35,6 +35,16 @@ handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_fo bool value = defGetBoolean(option); appendStringInfo(buf, opt_formats[i].format, value ? "true" : "false"); } + else if (strcmp(opt_formats[i].type, "object_id") == 0) + { + Oid value = defGetObjectId(option); + appendStringInfo(buf, opt_formats[i].format, value ); + } + else if (strcmp(opt_formats[i].type, "literal_cstr") == 0) + { + char *value = defGetString(option); + appendStringInfo(buf, opt_formats[i].format, quote_literal_cstr(value) ); + } else { elog(ERROR, "unrecognized option type: %s", opt_formats[i].type); diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 094c6fc1e..bc5d48f36 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -30,6 +30,25 @@ static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt); static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt); static void AppendDefElemConnLimit(StringInfo buf, DefElem *def); +const struct option_format create_database_option_formats[] = { + { "template", " TEMPLATE %s", "string" }, + { "owner", " OWNER %s", "string" }, + { "tablespace", " TABLESPACE %s", "string" }, + { "connection_limit", " CONNECTION LIMIT %d", "integer" }, + { "encoding", " ENCODING %s", "literal_cstr" }, + { "locale", " LOCALE %s", "literal_cstr" }, + { "lc_collate", " LC_COLLATE %s", "literal_cstr" }, + { "lc_ctype", " LC_CTYPE %s", "literal_cstr" }, + { "icu_locale", " ICU_LOCALE %s", "literal_cstr" }, + { "icu_rules", " ICU_RULES %s", "literal_cstr" }, + { "locale_provider", " LOCALE_PROVIDER %s", "literal_cstr" }, + { "is_template", " IS_TEMPLATE %s", "boolean" }, + { "allow_connections", " ALLOW_CONNECTIONS %s", "boolean" }, + { "collation_version", " COLLATION_VERSION %s", "literal_cstr" }, + { "strategy", " STRATEGY %s", "literal_cstr" }, + { "oid", " OID %d", "object_id" }, +}; + char * DeparseAlterDatabaseOwnerStmt(Node *node) { @@ -207,22 +226,6 @@ DeparseAlterDatabaseSetStmt(Node *node) } -const struct option_format option_formats[] = { - { "template", " TEMPLATE %s", "string" }, - { "owner", " OWNER %s", "string" }, - { "tablespace", " TABLESPACE %s", "string" }, - { "connection_limit", " CONNECTION LIMIT %d", "integer" }, - { "encoding", " ENCODING %s", "string" }, - { "lc_collate", " LC_COLLATE %s", "string" }, - { "lc_ctype", " LC_CTYPE %s", "string" }, - { "icu_locale", " ICU_LOCALE %s", "string" }, - { "icu_rules", " ICU_RULES %s", "string" }, - { "locale_provider", " LOCALE_PROVIDER %s", "string" }, - { "is_template", " IS_TEMPLATE %s", "boolean" }, - { "allow_connections", " ALLOW_CONNECTIONS %s", "boolean" }, -}; - - static void AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt) { @@ -234,7 +237,8 @@ AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt) foreach_ptr(option, stmt->options) { - handleOption(buf, option, option_formats, lengthof(option_formats)); + handleOption(buf, option, create_database_option_formats, lengthof( + create_database_option_formats)); } } From 134ec8f4284380172f4814d426517e211d6a0894 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 15:56:05 +0300 Subject: [PATCH 47/63] Fixes compile error for PG 14 --- src/backend/distributed/deparser/citus_deparseutils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 546360fdf..d7554aa79 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -35,11 +35,13 @@ handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_fo bool value = defGetBoolean(option); appendStringInfo(buf, opt_formats[i].format, value ? "true" : "false"); } +#if PG_VERSION_NUM >= PG_VERSION_15 else if (strcmp(opt_formats[i].type, "object_id") == 0) { Oid value = defGetObjectId(option); appendStringInfo(buf, opt_formats[i].format, value ); } +#endif else if (strcmp(opt_formats[i].type, "literal_cstr") == 0) { char *value = defGetString(option); From df715a0402a4bcc45e18a003602f03d475ff97b7 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 15:57:34 +0300 Subject: [PATCH 48/63] Fixes indent --- src/backend/distributed/deparser/citus_deparseutils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index d7554aa79..692d10e1c 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -39,13 +39,13 @@ handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_fo else if (strcmp(opt_formats[i].type, "object_id") == 0) { Oid value = defGetObjectId(option); - appendStringInfo(buf, opt_formats[i].format, value ); + appendStringInfo(buf, opt_formats[i].format, value); } #endif else if (strcmp(opt_formats[i].type, "literal_cstr") == 0) { char *value = defGetString(option); - appendStringInfo(buf, opt_formats[i].format, quote_literal_cstr(value) ); + appendStringInfo(buf, opt_formats[i].format, quote_literal_cstr(value)); } else { From d46a8394a3c4ae9afc4a08d4498613543ba2092b Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 16:00:18 +0300 Subject: [PATCH 49/63] Fixes compile error --- src/backend/distributed/deparser/citus_deparseutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 692d10e1c..3efca8575 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -35,7 +35,7 @@ handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_fo bool value = defGetBoolean(option); appendStringInfo(buf, opt_formats[i].format, value ? "true" : "false"); } -#if PG_VERSION_NUM >= PG_VERSION_15 +#if PG_VERSION_NUM >= 150000 else if (strcmp(opt_formats[i].type, "object_id") == 0) { Oid value = defGetObjectId(option); From d778bb1ed6a6c8faabb8bb15686f46e848688d2a Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 16:05:07 +0300 Subject: [PATCH 50/63] Adds PG_VERSION_15 constant --- src/backend/distributed/deparser/citus_deparseutils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 3efca8575..265988b46 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -7,6 +7,7 @@ #include "utils/syscache.h" #include "utils/typcache.h" #include "distributed/deparser.h" +#include "distributed/pg_version_constants.h" void @@ -35,7 +36,7 @@ handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_fo bool value = defGetBoolean(option); appendStringInfo(buf, opt_formats[i].format, value ? "true" : "false"); } -#if PG_VERSION_NUM >= 150000 +#if PG_VERSION_NUM >= PG_VERSION_15 else if (strcmp(opt_formats[i].type, "object_id") == 0) { Oid value = defGetObjectId(option); From 480c22acc2567fd1276bb465794c03154984627a Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 18:10:28 +0300 Subject: [PATCH 51/63] Fixes the comment --- src/backend/distributed/commands/database.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index a12ff3f12..625406898 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -481,7 +481,9 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, UnmarkObjectDistributed(&dbAddress); } - /* we execute here to avoid EnsureCoordinator check in ExecuteDistributedDDLJob */ + /* ExecuteDistributedDDLJob could not be used since it depends on namespace and + * database does not have namespace. + */ bool outsideTransaction = false; List *taskList = CreateDDLTaskList(internalDropCommand->data, workerNodes, From d0ef13dc897d7d099548f17d206110f480d56d94 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 19:42:17 +0300 Subject: [PATCH 52/63] Fixes review comments --- src/backend/distributed/Makefile | 2 +- src/backend/distributed/commands/database.c | 22 ++----------------- src/backend/distributed/commands/index.c | 6 ++--- src/backend/distributed/commands/vacuum.c | 4 ++-- .../executor/executor_util_tasks.c | 4 ++-- .../distributed/utils/citus_outfuncs.c | 2 +- .../distributed/multi_physical_planner.h | 2 +- 7 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/backend/distributed/Makefile b/src/backend/distributed/Makefile index f4f9ffd86..8f28b04b0 100644 --- a/src/backend/distributed/Makefile +++ b/src/backend/distributed/Makefile @@ -18,7 +18,7 @@ generated_downgrade_sql_files += $(patsubst %,$(citus_abs_srcdir)/build/sql/%,$( DATA_built = $(generated_sql_files) # directories with source files -SUBDIRS = . commands connection database ddl deparser executor metadata operations planner progress relay safeclib shardsplit test transaction utils worker clock +SUBDIRS = . commands connection ddl deparser executor metadata operations planner progress relay safeclib shardsplit test transaction utils worker clock # enterprise modules SUBDIRS += replication diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 625406898..e676cee4d 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -36,24 +36,6 @@ #include "distributed/listutils.h" #include "distributed/adaptive_executor.h" -/* macros to add DefElems to a list */ -#define DEFELEM_ADD_STRING(options, key, value) \ - { \ - DefElem *elem = makeDefElem(key, (Node *) makeString(value), -1); \ - options = lappend(options, elem); \ - } - -#define DEFELEM_ADD_BOOL(options, key, value) \ - { \ - DefElem *elem = makeDefElem(key, (Node *) makeBoolean(value), -1); \ - options = lappend(options, elem); \ - } - -#define DEFELEM_ADD_INT(options, key, value) \ - { \ - DefElem *elem = makeDefElem(key, (Node *) makeInteger(value), -1); \ - options = lappend(options, elem); \ - } static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid); @@ -257,7 +239,7 @@ CreateDDLTaskList(char *command, List *workerNodeList, bool outsideTransaction) Task *task = CitusMakeNode(Task); task->taskType = DDL_TASK; SetTaskQueryStringList(task, commandList); - task->cannotBeExecutedInTransction = outsideTransaction; + task->cannotBeExecutedInTransaction = outsideTransaction; WorkerNode *workerNode = NULL; foreach_ptr(workerNode, workerNodeList) @@ -306,7 +288,7 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, /* * PostprocessCreatedbStmt creates the plan to synchronize CREATE DATABASE - * across nodes. We use the cannotBeExecutedInTransction option to avoid + * across nodes. We use the cannotBeExecutedInTransaction option to avoid * sending transaction blocks. */ List * diff --git a/src/backend/distributed/commands/index.c b/src/backend/distributed/commands/index.c index 8271cc4f4..275f253b3 100644 --- a/src/backend/distributed/commands/index.c +++ b/src/backend/distributed/commands/index.c @@ -938,7 +938,7 @@ CreateIndexTaskList(IndexStmt *indexStmt) task->dependentTaskList = NULL; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransction = indexStmt->concurrent; + task->cannotBeExecutedInTransaction = indexStmt->concurrent; taskList = lappend(taskList, task); @@ -983,7 +983,7 @@ CreateReindexTaskList(Oid relationId, ReindexStmt *reindexStmt) task->dependentTaskList = NULL; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransction = + task->cannotBeExecutedInTransaction = IsReindexWithParam_compat(reindexStmt, "concurrently"); taskList = lappend(taskList, task); @@ -1309,7 +1309,7 @@ DropIndexTaskList(Oid relationId, Oid indexId, DropStmt *dropStmt) task->dependentTaskList = NULL; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransction = dropStmt->concurrent; + task->cannotBeExecutedInTransaction = dropStmt->concurrent; taskList = lappend(taskList, task); diff --git a/src/backend/distributed/commands/vacuum.c b/src/backend/distributed/commands/vacuum.c index ee03aeae1..21638ba7f 100644 --- a/src/backend/distributed/commands/vacuum.c +++ b/src/backend/distributed/commands/vacuum.c @@ -279,7 +279,7 @@ VacuumTaskList(Oid relationId, CitusVacuumParams vacuumParams, List *vacuumColum task->replicationModel = REPLICATION_MODEL_INVALID; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransction = ((vacuumParams.options) & VACOPT_VACUUM); + task->cannotBeExecutedInTransaction = ((vacuumParams.options) & VACOPT_VACUUM); taskList = lappend(taskList, task); } @@ -719,7 +719,7 @@ ExecuteUnqualifiedVacuumTasks(VacuumStmt *vacuumStmt, CitusVacuumParams vacuumPa SetTaskQueryStringList(task, unqualifiedVacuumCommands); task->dependentTaskList = NULL; task->replicationModel = REPLICATION_MODEL_INVALID; - task->cannotBeExecutedInTransction = ((vacuumParams.options) & VACOPT_VACUUM); + task->cannotBeExecutedInTransaction = ((vacuumParams.options) & VACOPT_VACUUM); bool hasPeerWorker = false; diff --git a/src/backend/distributed/executor/executor_util_tasks.c b/src/backend/distributed/executor/executor_util_tasks.c index abf721196..483fd55a7 100644 --- a/src/backend/distributed/executor/executor_util_tasks.c +++ b/src/backend/distributed/executor/executor_util_tasks.c @@ -61,7 +61,7 @@ TaskListRequiresRollback(List *taskList) } Task *task = (Task *) linitial(taskList); - if (task->cannotBeExecutedInTransction) + if (task->cannotBeExecutedInTransaction) { /* vacuum, create index concurrently etc. */ return false; @@ -164,7 +164,7 @@ TaskListCannotBeExecutedInTransaction(List *taskList) Task *task = NULL; foreach_ptr(task, taskList) { - if (task->cannotBeExecutedInTransction) + if (task->cannotBeExecutedInTransaction) { return true; } diff --git a/src/backend/distributed/utils/citus_outfuncs.c b/src/backend/distributed/utils/citus_outfuncs.c index b4062751a..9b4ac809c 100644 --- a/src/backend/distributed/utils/citus_outfuncs.c +++ b/src/backend/distributed/utils/citus_outfuncs.c @@ -535,7 +535,7 @@ OutTask(OUTFUNC_ARGS) WRITE_STRING_FIELD(fetchedExplainAnalyzePlan); WRITE_FLOAT_FIELD(fetchedExplainAnalyzeExecutionDuration, "%.2f"); WRITE_BOOL_FIELD(isLocalTableModification); - WRITE_BOOL_FIELD(cannotBeExecutedInTransction); + WRITE_BOOL_FIELD(cannotBeExecutedInTransaction); } diff --git a/src/include/distributed/multi_physical_planner.h b/src/include/distributed/multi_physical_planner.h index b7acc0574..35d83eb33 100644 --- a/src/include/distributed/multi_physical_planner.h +++ b/src/include/distributed/multi_physical_planner.h @@ -329,7 +329,7 @@ typedef struct Task /* * Vacuum, create/drop/reindex concurrently cannot be executed in a transaction. */ - bool cannotBeExecutedInTransction; + bool cannotBeExecutedInTransaction; Const *partitionKeyValue; int colocationId; From d88a1e7785de0ce3cb1d2a9bd6202cacac089619 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 19:44:36 +0300 Subject: [PATCH 53/63] Fixes compile error --- src/backend/distributed/utils/citus_copyfuncs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/distributed/utils/citus_copyfuncs.c b/src/backend/distributed/utils/citus_copyfuncs.c index 7e1379ef3..fe4429f04 100644 --- a/src/backend/distributed/utils/citus_copyfuncs.c +++ b/src/backend/distributed/utils/citus_copyfuncs.c @@ -326,7 +326,7 @@ CopyNodeTask(COPYFUNC_ARGS) COPY_STRING_FIELD(fetchedExplainAnalyzePlan); COPY_SCALAR_FIELD(fetchedExplainAnalyzeExecutionDuration); COPY_SCALAR_FIELD(isLocalTableModification); - COPY_SCALAR_FIELD(cannotBeExecutedInTransction); + COPY_SCALAR_FIELD(cannotBeExecutedInTransaction); } From fb6dd413ad6d390a8b2a857572a5d75745243cb4 Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 20:01:29 +0300 Subject: [PATCH 54/63] Fixes PostprocessCreateDatabaseStmt comment --- src/backend/distributed/commands/database.c | 22 ++++++++------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index e676cee4d..17852bd9b 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -287,9 +287,10 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, /* - * PostprocessCreatedbStmt creates the plan to synchronize CREATE DATABASE - * across nodes. We use the cannotBeExecutedInTransaction option to avoid - * sending transaction blocks. + * PostprocessCreatedbStmt is executed after 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 create the database. + * */ List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString) @@ -381,10 +382,7 @@ citus_internal_database_command(PG_FUNCTION_ARGS) { createdb(NULL, (CreatedbStmt *) parseTree); } - else - { - /* TODO: check database properties */ - } + } else if (IsA(parseTree, DropdbStmt)) { @@ -393,14 +391,10 @@ citus_internal_database_command(PG_FUNCTION_ARGS) bool missingOk = false; Oid databaseOid = get_database_oid(stmt->dbname, missingOk); - if (!OidIsValid(databaseOid)) - { - /* already dropped? */ - } - else + + if(OidIsValid(databaseOid)) { /* / * remove database from database shards * / */ - /* DeleteDatabaseShardByDatabaseIdLocally(databaseOid); */ DropDatabase(NULL, (DropdbStmt *) parseTree); } @@ -409,7 +403,7 @@ citus_internal_database_command(PG_FUNCTION_ARGS) { ereport(ERROR, (errmsg("unsupported command type %d", nodeTag(parseTree)))); } - + /* Below command rollbacks flags to the state before this session*/ AtEOXact_GUC(true, saveNestLevel); PG_RETURN_VOID(); From 7bdeb2f866248ace8fe7f2c76459c81b92af70bb Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 20:03:07 +0300 Subject: [PATCH 55/63] Fixes indentation --- src/backend/distributed/commands/database.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 17852bd9b..762c19c79 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -382,7 +382,6 @@ citus_internal_database_command(PG_FUNCTION_ARGS) { createdb(NULL, (CreatedbStmt *) parseTree); } - } else if (IsA(parseTree, DropdbStmt)) { @@ -391,8 +390,8 @@ citus_internal_database_command(PG_FUNCTION_ARGS) bool missingOk = false; Oid databaseOid = get_database_oid(stmt->dbname, missingOk); - - if(OidIsValid(databaseOid)) + + if (OidIsValid(databaseOid)) { /* / * remove database from database shards * / */ @@ -403,6 +402,7 @@ citus_internal_database_command(PG_FUNCTION_ARGS) { ereport(ERROR, (errmsg("unsupported command type %d", nodeTag(parseTree)))); } + /* Below command rollbacks flags to the state before this session*/ AtEOXact_GUC(true, saveNestLevel); From f2092d2f440322b7cc065f59e89bb0a3b2c8a9bc Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 20:24:34 +0300 Subject: [PATCH 56/63] Clarifies the code --- src/backend/distributed/commands/database.c | 2 -- .../distributed/deparser/citus_deparseutils.c | 14 ++++++++++++-- .../distributed/deparser/deparse_database_stmts.c | 2 +- src/include/distributed/deparser.h | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 762c19c79..70fa871a0 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -393,8 +393,6 @@ citus_internal_database_command(PG_FUNCTION_ARGS) if (OidIsValid(databaseOid)) { - /* / * remove database from database shards * / */ - DropDatabase(NULL, (DropdbStmt *) parseTree); } } diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 265988b46..1dd8b33bc 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -1,3 +1,4 @@ + #include "postgres.h" #include "utils/builtins.h" #include "commands/defrem.h" @@ -10,9 +11,18 @@ #include "distributed/pg_version_constants.h" +/** + * Convert a DefElem option to a SQL statement and append it to the given StringInfo buffer. + * + * @param buf The StringInfo buffer to append the SQL statement to. + * @param option The DefElem option to convert to a SQL statement. + * @param opt_formats The option format specification to use for the conversion. + * @param num_opt_formats The number of option formats in the opt_formats array. + */ void -handleOption(StringInfo buf, DefElem *option, const struct option_format *opt_formats, int - opt_formats_len) +optionToStatement(StringInfo buf, DefElem *option, const struct + option_format *opt_formats, int + opt_formats_len) { const char *name = option->defname; int i; diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index bc5d48f36..a5a5584af 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -237,7 +237,7 @@ AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt) foreach_ptr(option, stmt->options) { - handleOption(buf, option, create_database_option_formats, lengthof( + optionToStatement(buf, option, create_database_option_formats, lengthof( create_database_option_formats)); } } diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 428c91a5f..375fd8a8d 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -131,7 +131,7 @@ struct option_format }; -extern void handleOption(StringInfo buf, DefElem *option, const struct +extern void optionToStatement(StringInfo buf, DefElem *option, const struct option_format *opt_formats, int opt_formats_len); From 875f347238829f8cb791f338974ebd348cdb66be Mon Sep 17 00:00:00 2001 From: gindibay Date: Mon, 9 Oct 2023 20:27:50 +0300 Subject: [PATCH 57/63] Fixes indentation --- src/backend/distributed/deparser/deparse_database_stmts.c | 2 +- src/include/distributed/deparser.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index a5a5584af..5365f072d 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -238,7 +238,7 @@ AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt) foreach_ptr(option, stmt->options) { optionToStatement(buf, option, create_database_option_formats, lengthof( - create_database_option_formats)); + create_database_option_formats)); } } diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index 375fd8a8d..d47d3c18a 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -132,8 +132,8 @@ struct option_format extern void optionToStatement(StringInfo buf, DefElem *option, const struct - option_format *opt_formats, int - opt_formats_len); + option_format *opt_formats, int + opt_formats_len); /* forward declarations for deparse_statistics_stmts.c */ From 8cc67921cb70dc68bf726d84f69a1a90d008f70b Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 13 Oct 2023 00:12:38 +0300 Subject: [PATCH 58/63] Fixes review comments --- src/backend/distributed/commands/database.c | 27 +++++----- src/backend/distributed/metadata/distobject.c | 1 - .../distributed/metadata/metadata_cache.c | 49 +++++++++++++++++-- src/include/distributed/commands.h | 28 ++++++++--- .../create_drop_database_propagation.out | 16 ++++++ .../sql/create_drop_database_propagation.sql | 12 +++++ 6 files changed, 112 insertions(+), 21 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 70fa871a0..067701114 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -295,16 +295,13 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString) { - if (EnableCreateDatabasePropagation) - { - EnsureCoordinator(); - } - if (!EnableCreateDatabasePropagation || !ShouldPropagate()) { return NIL; } + EnsureCoordinator(); + CreatedbStmt *stmt = castNode(CreatedbStmt, node); char *databaseName = stmt->dbname; bool missingOk = false; @@ -371,6 +368,15 @@ citus_internal_database_command(PG_FUNCTION_ARGS) (superuser() ? PGC_SUSET : PGC_USERSET), PGC_S_SESSION, GUC_ACTION_LOCAL, true, 0, false); + /* + * createdb() / DropDatabase() uses ParseState to report the error position for the + * input command and the position is reported to be 0 when it's provided as NULL. + * We're okay with that because we don't expect this UDF to be called with an incorrect + * DDL command. + * + */ + ParseState *pstate = NULL; + if (IsA(parseTree, CreatedbStmt)) { CreatedbStmt *stmt = castNode(CreatedbStmt, parseTree); @@ -380,7 +386,7 @@ citus_internal_database_command(PG_FUNCTION_ARGS) if (!OidIsValid(databaseOid)) { - createdb(NULL, (CreatedbStmt *) parseTree); + createdb(pstate, (CreatedbStmt *) parseTree); } } else if (IsA(parseTree, DropdbStmt)) @@ -393,7 +399,7 @@ citus_internal_database_command(PG_FUNCTION_ARGS) if (OidIsValid(databaseOid)) { - DropDatabase(NULL, (DropdbStmt *) parseTree); + DropDatabase(pstate, (DropdbStmt *) parseTree); } } else @@ -417,6 +423,8 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, return NIL; } + EnsureCoordinator(); + DropdbStmt *stmt = (DropdbStmt *) node; char *databaseName = stmt->dbname; bool missingOk = true; @@ -450,10 +458,7 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, /* Delete from pg_dist_object */ - if (IsObjectDistributed(&dbAddress)) - { - UnmarkObjectDistributed(&dbAddress); - } + UnmarkObjectDistributed(&dbAddress); /* ExecuteDistributedDDLJob could not be used since it depends on namespace and * database does not have namespace. diff --git a/src/backend/distributed/metadata/distobject.c b/src/backend/distributed/metadata/distobject.c index a025ba73f..c420e6ec3 100644 --- a/src/backend/distributed/metadata/distobject.c +++ b/src/backend/distributed/metadata/distobject.c @@ -53,7 +53,6 @@ static char * CreatePgDistObjectEntryCommand(const ObjectAddress *objectAddress); static int ExecuteCommandAsSuperuser(char *query, int paramCount, Oid *paramTypes, Datum *paramValues); -bool IsObjectDistributed(const ObjectAddress *address); PG_FUNCTION_INFO_V1(citus_unmark_object_distributed); PG_FUNCTION_INFO_V1(master_unmark_object_distributed); diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 55ec63a6a..55d0f11c5 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -310,6 +310,7 @@ static HeapTuple LookupDistPartitionTuple(Relation pgDistPartition, Oid relation static void GetPartitionTypeInputInfo(char *partitionKeyString, char partitionMethod, Oid *columnTypeId, int32 *columnTypeMod, Oid *intervalTypeId, int32 *intervalTypeMod); +static void CachedNamespaceLookup(const char *nspname, Oid *cachedOid); static void CachedRelationLookup(const char *relationName, Oid *cachedOid); static void CachedRelationLookupExtended(const char *relationName, Oid *cachedOid, bool missing_ok); @@ -2769,6 +2770,15 @@ DistRebalanceStrategyRelationId(void) } +/* return the oid of citus namespace */ +Oid +CitusCatalogNamespaceId(void) +{ + CachedNamespaceLookup("citus", &MetadataCache.citusCatalogNamespaceId); + return MetadataCache.citusCatalogNamespaceId; +} + + /* return oid of pg_dist_object relation */ Oid DistObjectRelationId(void) @@ -2795,14 +2805,12 @@ DistObjectRelationId(void) true); if (!OidIsValid(MetadataCache.distObjectRelationId)) { - Oid citusNamespaceId = get_namespace_oid("citus", false); - /* * We can only ever reach here while we are creating/altering our extension before * the table is moved to pg_catalog. */ CachedRelationNamespaceLookupExtended("pg_dist_object", - citusNamespaceId, + CitusCatalogNamespaceId(), &MetadataCache.distObjectRelationId, false); } @@ -2836,6 +2844,17 @@ DistObjectPrimaryKeyIndexId(void) &MetadataCache.distObjectPrimaryKeyIndexId, true); + if (!OidIsValid(MetadataCache.distObjectPrimaryKeyIndexId)) + { + /* + * We can only ever reach here while we are creating/altering our extension before + * the table is moved to pg_catalog. + */ + CachedRelationNamespaceLookupExtended("pg_dist_object_pkey", + CitusCatalogNamespaceId(), + &MetadataCache.distObjectPrimaryKeyIndexId, + false); + } return MetadataCache.distObjectPrimaryKeyIndexId; } @@ -5401,6 +5420,30 @@ DeformedDistShardTupleToShardInterval(Datum *datumArray, bool *isNullArray, } +/* + * CachedNamespaceLookup performs a cached lookup for the namespace (schema), with the + * result cached in cachedOid. + */ +static void +CachedNamespaceLookup(const char *nspname, Oid *cachedOid) +{ + /* force callbacks to be registered, so we always get notified upon changes */ + InitializeCaches(); + + if (*cachedOid == InvalidOid) + { + *cachedOid = get_namespace_oid(nspname, true); + + if (*cachedOid == InvalidOid) + { + ereport(ERROR, (errmsg( + "cache lookup failed for namespace %s, called too early?", + nspname))); + } + } +} + + /* * CachedRelationLookup performs a cached lookup for the relation * relationName, with the result cached in *cachedOid. diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 36e412378..22c35a694 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -22,6 +22,7 @@ #include "tcop/utility.h" #include "utils/acl.h" + extern bool AddAllLocalTablesToMetadata; extern bool EnableSchemaBasedSharding; @@ -57,6 +58,7 @@ typedef enum DistOpsOperationType DIST_OPS_DROP, } DistOpsOperationType; + /* * DistributeObjectOps specifies handlers for node/object type pairs. * Instances of this type should all be declared in deparse.c. @@ -77,11 +79,11 @@ typedef enum DistOpsOperationType */ typedef struct DistributeObjectOps { - char *(*deparse)(Node *); + char * (*deparse)(Node *); void (*qualify)(Node *); - List *(*preprocess)(Node *, const char *, ProcessUtilityContext); - List *(*postprocess)(Node *, const char *); - List *(*address)(Node *, bool, bool); + List * (*preprocess)(Node *, const char *, ProcessUtilityContext); + List * (*postprocess)(Node *, const char *); + List * (*address)(Node *, bool, bool); bool markDistributed; /* fields used by common implementations, omitted for specialized implementations */ @@ -138,6 +140,7 @@ typedef enum ExtractForeignKeyConstraintsMode INCLUDE_SINGLE_SHARD_TABLES } ExtractForeignKeyConstraintMode; + /* * Flags that can be passed to GetForeignKeyIdsForColumn to * indicate whether relationId argument should match: @@ -156,6 +159,7 @@ typedef enum SearchForeignKeyColumnFlags /* callers can also pass union of above flags */ } SearchForeignKeyColumnFlags; + typedef enum TenantOperation { TENANT_UNDISTRIBUTE_TABLE = 0, @@ -193,9 +197,11 @@ extern List * DropTextSearchDictObjectAddress(Node *node, bool missing_ok, bool /* index.c */ typedef void (*PGIndexProcessor)(Form_pg_index, List **, int); + /* call.c */ extern bool CallDistributedProcedureRemotely(CallStmt *callStmt, DestReceiver *dest); + /* collation.c - forward declarations */ extern char * CreateCollationDDL(Oid collationId); extern List * CreateCollationDDLsIdempotent(Oid collationId); @@ -224,6 +230,7 @@ extern List * PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *que ProcessUtilityContext processUtilityContext); + extern List * PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); @@ -246,6 +253,7 @@ extern List * RenameDomainStmtObjectAddress(Node *node, bool missing_ok, bool extern CreateDomainStmt * RecreateDomainStmt(Oid domainOid); extern Oid get_constraint_typid(Oid conoid); + /* extension.c - forward declarations */ extern bool IsDropCitusExtensionStmt(Node *parsetree); extern List * GetDependentFDWsToExtension(Oid extensionId); @@ -324,11 +332,13 @@ extern Oid GetReferencedTableId(Oid foreignKeyId); extern Oid GetReferencingTableId(Oid foreignKeyId); extern bool RelationInvolvedInAnyNonInheritedForeignKeys(Oid relationId); + /* foreign_data_wrapper.c - forward declarations */ extern List * PreprocessGrantOnFDWStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); extern Acl * GetPrivilegesForFDW(Oid FDWOid); + /* foreign_server.c - forward declarations */ extern List * PreprocessGrantOnForeignServerStmt(Node *node, const char *queryString, ProcessUtilityContext @@ -339,15 +349,17 @@ extern List * AlterForeignServerStmtObjectAddress(Node *node, bool missing_ok, b isPostprocess); extern List * RenameForeignServerStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess); -extern List * AlterForeignServerOwnerStmtObjectAddress(Node *node, bool missing_ok, bool - isPostprocess); +extern List * AlterForeignServerOwnerStmtObjectAddress(Node *node, bool + missing_ok, bool isPostprocess); extern List * GetForeignServerCreateDDLCommand(Oid serverId); + /* foreign_table.c - forward declarations */ extern List * PreprocessAlterForeignTableSchemaStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); + /* function.c - forward declarations */ extern List * PreprocessCreateFunctionStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); @@ -377,12 +389,14 @@ extern List * PreprocessGrantOnFunctionStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); extern List * PostprocessGrantOnFunctionStmt(Node *node, const char *queryString); + /* grant.c - forward declarations */ extern List * PreprocessGrantStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); extern void deparsePrivileges(StringInfo privsString, GrantStmt *grantStmt); extern void deparseGrantees(StringInfo granteesString, GrantStmt *grantStmt); + /* index.c - forward declarations */ extern bool IsIndexRenameStmt(RenameStmt *renameStmt); extern List * PreprocessIndexStmt(Node *createIndexStatement, @@ -463,6 +477,7 @@ extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt); extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); + /* role.c - forward declarations*/ extern List * PostprocessAlterRoleStmt(Node *stmt, const char *queryString); extern List * PreprocessAlterRoleSetStmt(Node *stmt, const char *queryString, @@ -585,6 +600,7 @@ extern List * GetAlterIndexStatisticsCommands(Oid indexOid); /* subscription.c - forward declarations */ extern Node * ProcessCreateSubscriptionStmt(CreateSubscriptionStmt *createSubStmt); + /* table.c - forward declarations */ extern List * PreprocessDropTableStmt(Node *stmt, const char *queryString, ProcessUtilityContext processUtilityContext); diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index e578cd2eb..be85e50c0 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -102,6 +102,22 @@ WHERE datname = 'mydatabase'; (0 rows) \c - - - :master_port +--tests for special characters in database name +set citus.enable_create_database_propagation=on; +SET citus.log_remote_commands = true; +set citus.grep_remote_commands = '%CREATE DATABASE%'; +create database "mydatabase#1'2"; +NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('CREATE DATABASE "mydatabase#1''2"') +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx +NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('CREATE DATABASE "mydatabase#1''2"') +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx +set citus.grep_remote_commands = '%DROP DATABASE%'; +drop database "mydatabase#1'2"; +NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('DROP DATABASE "mydatabase#1''2"') +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx +NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('DROP DATABASE "mydatabase#1''2"') +DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx +--clean up resources created by this test drop tablespace create_drop_db_tablespace; \c - - - :worker_1_port drop tablespace create_drop_db_tablespace; diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 415a03f97..5e2166f77 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -94,6 +94,18 @@ WHERE datname = 'mydatabase'; \c - - - :master_port +--tests for special characters in database name +set citus.enable_create_database_propagation=on; +SET citus.log_remote_commands = true; +set citus.grep_remote_commands = '%CREATE DATABASE%'; + +create database "mydatabase#1'2"; + +set citus.grep_remote_commands = '%DROP DATABASE%'; +drop database "mydatabase#1'2"; + +--clean up resources created by this test + drop tablespace create_drop_db_tablespace; \c - - - :worker_1_port From a274ffcb51a717cbfff914ab7f4b0fafe5f3ce5c Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 13 Oct 2023 01:36:01 +0300 Subject: [PATCH 59/63] Adds If exists statement for drop database --- src/backend/distributed/deparser/deparse_database_stmts.c | 4 +++- .../regress/expected/create_drop_database_propagation.out | 6 +++--- src/test/regress/sql/create_drop_database_propagation.sql | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 5365f072d..7c7544694 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -259,8 +259,10 @@ DeparseCreateDatabaseStmt(Node *node) static void AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt) { + char *if_exists_statement = stmt->missing_ok ? "IF EXISTS" : ""; appendStringInfo(buf, - "DROP DATABASE %s", + "DROP DATABASE %s %s", + if_exists_statement, quote_identifier(stmt->dbname)); DefElem *option = NULL; diff --git a/src/test/regress/expected/create_drop_database_propagation.out b/src/test/regress/expected/create_drop_database_propagation.out index be85e50c0..37829a6ee 100644 --- a/src/test/regress/expected/create_drop_database_propagation.out +++ b/src/test/regress/expected/create_drop_database_propagation.out @@ -112,10 +112,10 @@ DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('CREATE DATABASE "mydatabase#1''2"') DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx set citus.grep_remote_commands = '%DROP DATABASE%'; -drop database "mydatabase#1'2"; -NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('DROP DATABASE "mydatabase#1''2"') +drop database if exists "mydatabase#1'2"; +NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('DROP DATABASE IF EXISTS "mydatabase#1''2"') DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx -NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('DROP DATABASE "mydatabase#1''2"') +NOTICE: issuing SELECT pg_catalog.citus_internal_database_command('DROP DATABASE IF EXISTS "mydatabase#1''2"') DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx --clean up resources created by this test drop tablespace create_drop_db_tablespace; diff --git a/src/test/regress/sql/create_drop_database_propagation.sql b/src/test/regress/sql/create_drop_database_propagation.sql index 5e2166f77..d84654054 100644 --- a/src/test/regress/sql/create_drop_database_propagation.sql +++ b/src/test/regress/sql/create_drop_database_propagation.sql @@ -102,7 +102,7 @@ set citus.grep_remote_commands = '%CREATE DATABASE%'; create database "mydatabase#1'2"; set citus.grep_remote_commands = '%DROP DATABASE%'; -drop database "mydatabase#1'2"; +drop database if exists "mydatabase#1'2"; --clean up resources created by this test From c31479d2eb6ffe3af20dc5be6be4f60e01472af9 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 13 Oct 2023 03:10:17 +0300 Subject: [PATCH 60/63] Fixes review notes --- src/backend/distributed/commands/database.c | 127 +++--------------- src/backend/distributed/commands/index.c | 6 +- src/backend/distributed/commands/vacuum.c | 4 +- .../distributed/deparser/citus_deparseutils.c | 12 +- .../deparser/deparse_database_stmts.c | 32 ++--- .../executor/executor_util_tasks.c | 4 +- .../distributed/utils/citus_copyfuncs.c | 2 +- .../distributed/utils/citus_outfuncs.c | 2 +- src/include/distributed/deparser.h | 11 +- .../distributed/multi_physical_planner.h | 2 +- 10 files changed, 57 insertions(+), 145 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 067701114..93cf87b42 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -39,8 +39,6 @@ static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid); -static List * CreateDDLTaskList(char *command, List *workerNodeList, - bool outsideTransaction); PG_FUNCTION_INFO_V1(citus_internal_database_command); static Oid get_database_owner(Oid db_oid); @@ -226,36 +224,6 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString, #endif -/* - * CreateDDLTaskList creates a task list for running a single DDL command. - */ -static List * -CreateDDLTaskList(char *command, List *workerNodeList, bool outsideTransaction) -{ - List *commandList = list_make3(DISABLE_DDL_PROPAGATION, - command, - ENABLE_DDL_PROPAGATION); - - Task *task = CitusMakeNode(Task); - task->taskType = DDL_TASK; - SetTaskQueryStringList(task, commandList); - task->cannotBeExecutedInTransaction = outsideTransaction; - - WorkerNode *workerNode = NULL; - foreach_ptr(workerNode, workerNodeList) - { - ShardPlacement *targetPlacement = CitusMakeNode(ShardPlacement); - targetPlacement->nodeName = workerNode->workerName; - targetPlacement->nodePort = workerNode->workerPort; - targetPlacement->groupId = workerNode->groupId; - task->taskPlacementList = lappend(task->taskPlacementList, - targetPlacement); - } - - return list_make1(task); -} - - /* * PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local * postgres instance. @@ -295,55 +263,25 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString) { - if (!EnableCreateDatabasePropagation || !ShouldPropagate()) + if (!ShouldPropagate()) { return NIL; } EnsureCoordinator(); - CreatedbStmt *stmt = castNode(CreatedbStmt, node); - char *databaseName = stmt->dbname; - bool missingOk = false; - Oid databaseOid = get_database_oid(databaseName, missingOk); + char *createDatabaseCommand = DeparseTreeNode(node); - /* - * TODO: try to reuse regular DDL infrastructure - * - * We do not do this right now because of the AssignDatabaseToShard at the end. - */ - List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, - RowShareLock); - if (list_length(workerNodes) > 0) - { - char *createDatabaseCommand = DeparseTreeNode(node); + StringInfo internalCreateCommand = makeStringInfo(); + appendStringInfo(internalCreateCommand, + "SELECT pg_catalog.citus_internal_database_command(%s)", + quote_literal_cstr(createDatabaseCommand)); - StringInfo internalCreateCommand = makeStringInfo(); - appendStringInfo(internalCreateCommand, - "SELECT pg_catalog.citus_internal_database_command(%s)", - quote_literal_cstr(createDatabaseCommand)); + List *commands = list_make3(DISABLE_DDL_PROPAGATION, + (void *) internalCreateCommand->data, + ENABLE_DDL_PROPAGATION); - /* - * For the moment, we run CREATE DATABASE in 2PC, though that prevents - * us from immediately doing a pg_dump | pg_restore when dealing with - * a remote template database. - */ - bool outsideTransaction = false; - - List *taskList = CreateDDLTaskList(internalCreateCommand->data, workerNodes, - outsideTransaction); - - bool localExecutionSupported = false; - ExecuteUtilityTaskList(taskList, localExecutionSupported); - } - - /* synchronize pg_dist_object records */ - ObjectAddress dbAddress = { 0 }; - ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); - MarkObjectDistributed(&dbAddress); - - - return NIL; + return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } @@ -418,37 +356,13 @@ List * PreprocessDropDatabaseStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext) { - if (!EnableCreateDatabasePropagation || !ShouldPropagate()) + if (!ShouldPropagate()) { return NIL; } EnsureCoordinator(); - DropdbStmt *stmt = (DropdbStmt *) node; - char *databaseName = stmt->dbname; - bool missingOk = true; - Oid databaseOid = get_database_oid(databaseName, missingOk); - if (databaseOid == InvalidOid) - { - /* let regular ProcessUtility deal with IF NOT EXISTS */ - return NIL; - } - - ObjectAddress dbAddress = { 0 }; - ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); - if (!IsObjectDistributed(&dbAddress)) - { - return NIL; - } - - List *workerNodes = TargetWorkerSetNodeList(NON_COORDINATOR_METADATA_NODES, - RowShareLock); - if (list_length(workerNodes) == 0) - { - return NIL; - } - char *dropDatabaseCommand = DeparseTreeNode(node); StringInfo internalDropCommand = makeStringInfo(); @@ -456,20 +370,9 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, "SELECT pg_catalog.citus_internal_database_command(%s)", quote_literal_cstr(dropDatabaseCommand)); - /* Delete from pg_dist_object */ + List *commands = list_make3(DISABLE_DDL_PROPAGATION, + (void *) internalDropCommand->data, + ENABLE_DDL_PROPAGATION); - UnmarkObjectDistributed(&dbAddress); - - /* ExecuteDistributedDDLJob could not be used since it depends on namespace and - * database does not have namespace. - */ - - bool outsideTransaction = false; - List *taskList = CreateDDLTaskList(internalDropCommand->data, workerNodes, - outsideTransaction); - - bool localExecutionSupported = false; - ExecuteUtilityTaskList(taskList, localExecutionSupported); - - return NIL; + return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } diff --git a/src/backend/distributed/commands/index.c b/src/backend/distributed/commands/index.c index 275f253b3..8271cc4f4 100644 --- a/src/backend/distributed/commands/index.c +++ b/src/backend/distributed/commands/index.c @@ -938,7 +938,7 @@ CreateIndexTaskList(IndexStmt *indexStmt) task->dependentTaskList = NULL; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransaction = indexStmt->concurrent; + task->cannotBeExecutedInTransction = indexStmt->concurrent; taskList = lappend(taskList, task); @@ -983,7 +983,7 @@ CreateReindexTaskList(Oid relationId, ReindexStmt *reindexStmt) task->dependentTaskList = NULL; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransaction = + task->cannotBeExecutedInTransction = IsReindexWithParam_compat(reindexStmt, "concurrently"); taskList = lappend(taskList, task); @@ -1309,7 +1309,7 @@ DropIndexTaskList(Oid relationId, Oid indexId, DropStmt *dropStmt) task->dependentTaskList = NULL; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransaction = dropStmt->concurrent; + task->cannotBeExecutedInTransction = dropStmt->concurrent; taskList = lappend(taskList, task); diff --git a/src/backend/distributed/commands/vacuum.c b/src/backend/distributed/commands/vacuum.c index 21638ba7f..ee03aeae1 100644 --- a/src/backend/distributed/commands/vacuum.c +++ b/src/backend/distributed/commands/vacuum.c @@ -279,7 +279,7 @@ VacuumTaskList(Oid relationId, CitusVacuumParams vacuumParams, List *vacuumColum task->replicationModel = REPLICATION_MODEL_INVALID; task->anchorShardId = shardId; task->taskPlacementList = ActiveShardPlacementList(shardId); - task->cannotBeExecutedInTransaction = ((vacuumParams.options) & VACOPT_VACUUM); + task->cannotBeExecutedInTransction = ((vacuumParams.options) & VACOPT_VACUUM); taskList = lappend(taskList, task); } @@ -719,7 +719,7 @@ ExecuteUnqualifiedVacuumTasks(VacuumStmt *vacuumStmt, CitusVacuumParams vacuumPa SetTaskQueryStringList(task, unqualifiedVacuumCommands); task->dependentTaskList = NULL; task->replicationModel = REPLICATION_MODEL_INVALID; - task->cannotBeExecutedInTransaction = ((vacuumParams.options) & VACOPT_VACUUM); + task->cannotBeExecutedInTransction = ((vacuumParams.options) & VACOPT_VACUUM); bool hasPeerWorker = false; diff --git a/src/backend/distributed/deparser/citus_deparseutils.c b/src/backend/distributed/deparser/citus_deparseutils.c index 1dd8b33bc..52d96930e 100644 --- a/src/backend/distributed/deparser/citus_deparseutils.c +++ b/src/backend/distributed/deparser/citus_deparseutils.c @@ -31,36 +31,36 @@ optionToStatement(StringInfo buf, DefElem *option, const struct { if (strcmp(name, opt_formats[i].name) == 0) { - if (strcmp(opt_formats[i].type, "string") == 0) + if (opt_formats[i].type == OPTION_FORMAT_STRING) { char *value = defGetString(option); appendStringInfo(buf, opt_formats[i].format, quote_identifier(value)); } - else if (strcmp(opt_formats[i].type, "integer") == 0) + else if (opt_formats[i].type == OPTION_FORMAT_INTEGER) { int32 value = defGetInt32(option); appendStringInfo(buf, opt_formats[i].format, value); } - else if (strcmp(opt_formats[i].type, "boolean") == 0) + else if (opt_formats[i].type == OPTION_FORMAT_BOOLEAN) { bool value = defGetBoolean(option); appendStringInfo(buf, opt_formats[i].format, value ? "true" : "false"); } #if PG_VERSION_NUM >= PG_VERSION_15 - else if (strcmp(opt_formats[i].type, "object_id") == 0) + else if (opt_formats[i].type == OPTION_FORMAT_OBJECT_ID) { Oid value = defGetObjectId(option); appendStringInfo(buf, opt_formats[i].format, value); } #endif - else if (strcmp(opt_formats[i].type, "literal_cstr") == 0) + else if (opt_formats[i].type == OPTION_FORMAT_LITERAL_CSTR) { char *value = defGetString(option); appendStringInfo(buf, opt_formats[i].format, quote_literal_cstr(value)); } else { - elog(ERROR, "unrecognized option type: %s", opt_formats[i].type); + elog(ERROR, "unrecognized option type: %d", opt_formats[i].type); } break; } diff --git a/src/backend/distributed/deparser/deparse_database_stmts.c b/src/backend/distributed/deparser/deparse_database_stmts.c index 7c7544694..bf98b9622 100644 --- a/src/backend/distributed/deparser/deparse_database_stmts.c +++ b/src/backend/distributed/deparser/deparse_database_stmts.c @@ -31,22 +31,22 @@ static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt); static void AppendDefElemConnLimit(StringInfo buf, DefElem *def); const struct option_format create_database_option_formats[] = { - { "template", " TEMPLATE %s", "string" }, - { "owner", " OWNER %s", "string" }, - { "tablespace", " TABLESPACE %s", "string" }, - { "connection_limit", " CONNECTION LIMIT %d", "integer" }, - { "encoding", " ENCODING %s", "literal_cstr" }, - { "locale", " LOCALE %s", "literal_cstr" }, - { "lc_collate", " LC_COLLATE %s", "literal_cstr" }, - { "lc_ctype", " LC_CTYPE %s", "literal_cstr" }, - { "icu_locale", " ICU_LOCALE %s", "literal_cstr" }, - { "icu_rules", " ICU_RULES %s", "literal_cstr" }, - { "locale_provider", " LOCALE_PROVIDER %s", "literal_cstr" }, - { "is_template", " IS_TEMPLATE %s", "boolean" }, - { "allow_connections", " ALLOW_CONNECTIONS %s", "boolean" }, - { "collation_version", " COLLATION_VERSION %s", "literal_cstr" }, - { "strategy", " STRATEGY %s", "literal_cstr" }, - { "oid", " OID %d", "object_id" }, + { "owner", " OWNER %s", OPTION_FORMAT_STRING }, + { "template", " TEMPLATE %s", OPTION_FORMAT_STRING }, + { "encoding", " ENCODING %s", OPTION_FORMAT_LITERAL_CSTR }, + { "strategy", " STRATEGY %s", OPTION_FORMAT_LITERAL_CSTR }, + { "locale", " LOCALE %s", OPTION_FORMAT_LITERAL_CSTR }, + { "lc_collate", " LC_COLLATE %s", OPTION_FORMAT_LITERAL_CSTR }, + { "lc_ctype", " LC_CTYPE %s", OPTION_FORMAT_LITERAL_CSTR }, + { "icu_locale", " ICU_LOCALE %s", OPTION_FORMAT_LITERAL_CSTR }, + { "icu_rules", " ICU_RULES %s", OPTION_FORMAT_LITERAL_CSTR }, + { "locale_provider", " LOCALE_PROVIDER %s", OPTION_FORMAT_LITERAL_CSTR }, + { "collation_version", " COLLATION_VERSION %s", OPTION_FORMAT_LITERAL_CSTR }, + { "tablespace", " TABLESPACE %s", OPTION_FORMAT_STRING }, + { "allow_connections", " ALLOW_CONNECTIONS %s", OPTION_FORMAT_BOOLEAN }, + { "connection_limit", " CONNECTION LIMIT %d", OPTION_FORMAT_INTEGER }, + { "is_template", " IS_TEMPLATE %s", OPTION_FORMAT_BOOLEAN }, + { "oid", " OID %d", OPTION_FORMAT_OBJECT_ID } }; char * diff --git a/src/backend/distributed/executor/executor_util_tasks.c b/src/backend/distributed/executor/executor_util_tasks.c index 483fd55a7..abf721196 100644 --- a/src/backend/distributed/executor/executor_util_tasks.c +++ b/src/backend/distributed/executor/executor_util_tasks.c @@ -61,7 +61,7 @@ TaskListRequiresRollback(List *taskList) } Task *task = (Task *) linitial(taskList); - if (task->cannotBeExecutedInTransaction) + if (task->cannotBeExecutedInTransction) { /* vacuum, create index concurrently etc. */ return false; @@ -164,7 +164,7 @@ TaskListCannotBeExecutedInTransaction(List *taskList) Task *task = NULL; foreach_ptr(task, taskList) { - if (task->cannotBeExecutedInTransaction) + if (task->cannotBeExecutedInTransction) { return true; } diff --git a/src/backend/distributed/utils/citus_copyfuncs.c b/src/backend/distributed/utils/citus_copyfuncs.c index fe4429f04..7e1379ef3 100644 --- a/src/backend/distributed/utils/citus_copyfuncs.c +++ b/src/backend/distributed/utils/citus_copyfuncs.c @@ -326,7 +326,7 @@ CopyNodeTask(COPYFUNC_ARGS) COPY_STRING_FIELD(fetchedExplainAnalyzePlan); COPY_SCALAR_FIELD(fetchedExplainAnalyzeExecutionDuration); COPY_SCALAR_FIELD(isLocalTableModification); - COPY_SCALAR_FIELD(cannotBeExecutedInTransaction); + COPY_SCALAR_FIELD(cannotBeExecutedInTransction); } diff --git a/src/backend/distributed/utils/citus_outfuncs.c b/src/backend/distributed/utils/citus_outfuncs.c index 9b4ac809c..b4062751a 100644 --- a/src/backend/distributed/utils/citus_outfuncs.c +++ b/src/backend/distributed/utils/citus_outfuncs.c @@ -535,7 +535,7 @@ OutTask(OUTFUNC_ARGS) WRITE_STRING_FIELD(fetchedExplainAnalyzePlan); WRITE_FLOAT_FIELD(fetchedExplainAnalyzeExecutionDuration, "%.2f"); WRITE_BOOL_FIELD(isLocalTableModification); - WRITE_BOOL_FIELD(cannotBeExecutedInTransaction); + WRITE_BOOL_FIELD(cannotBeExecutedInTransction); } diff --git a/src/include/distributed/deparser.h b/src/include/distributed/deparser.h index d47d3c18a..66ead2b4d 100644 --- a/src/include/distributed/deparser.h +++ b/src/include/distributed/deparser.h @@ -127,9 +127,18 @@ struct option_format { const char *name; const char *format; - const char *type; + const int type; }; +typedef enum OptionFormatType +{ + OPTION_FORMAT_STRING, + OPTION_FORMAT_LITERAL_CSTR, + OPTION_FORMAT_BOOLEAN, + OPTION_FORMAT_INTEGER, + OPTION_FORMAT_OBJECT_ID +} OptionFormatType; + extern void optionToStatement(StringInfo buf, DefElem *option, const struct option_format *opt_formats, int diff --git a/src/include/distributed/multi_physical_planner.h b/src/include/distributed/multi_physical_planner.h index 35d83eb33..b7acc0574 100644 --- a/src/include/distributed/multi_physical_planner.h +++ b/src/include/distributed/multi_physical_planner.h @@ -329,7 +329,7 @@ typedef struct Task /* * Vacuum, create/drop/reindex concurrently cannot be executed in a transaction. */ - bool cannotBeExecutedInTransaction; + bool cannotBeExecutedInTransction; Const *partitionKeyValue; int colocationId; From 333f77a26760edccf24bac3a6bdd931a64a2fec0 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 13 Oct 2023 04:16:20 +0300 Subject: [PATCH 61/63] Fixes distributed_object management --- src/backend/distributed/commands/database.c | 32 +++++++++++++++++++ .../commands/distribute_object_ops.c | 4 +-- src/include/distributed/commands.h | 3 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index 93cf87b42..bc3e197a4 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -363,6 +363,25 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, EnsureCoordinator(); + DropdbStmt *stmt = (DropdbStmt *) node; + + Oid databaseOid = get_database_oid(stmt->dbname, stmt->missing_ok); + + if (databaseOid == InvalidOid) + { + /* let regular ProcessUtility deal with IF NOT EXISTS */ + return NIL; + } + + ObjectAddress dbAddress = { 0 }; + ObjectAddressSet(dbAddress, DatabaseRelationId, databaseOid); + if (!IsObjectDistributed(&dbAddress)) + { + return NIL; + } + + UnmarkObjectDistributed(&dbAddress); + char *dropDatabaseCommand = DeparseTreeNode(node); StringInfo internalDropCommand = makeStringInfo(); @@ -370,9 +389,22 @@ PreprocessDropDatabaseStmt(Node *node, const char *queryString, "SELECT pg_catalog.citus_internal_database_command(%s)", quote_literal_cstr(dropDatabaseCommand)); + List *commands = list_make3(DISABLE_DDL_PROPAGATION, (void *) internalDropCommand->data, ENABLE_DDL_PROPAGATION); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); } + + +List * +CreateDatabaseStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess) +{ + CreatedbStmt *stmt = castNode(CreatedbStmt, node); + Oid databaseOid = get_database_oid(stmt->dbname, missing_ok); + ObjectAddress *dbAddress = palloc0(sizeof(ObjectAddress)); + ObjectAddressSet(*dbAddress, DatabaseRelationId, databaseOid); + + return list_make1(dbAddress); +} diff --git a/src/backend/distributed/commands/distribute_object_ops.c b/src/backend/distributed/commands/distribute_object_ops.c index ef7d486b5..49a96e016 100644 --- a/src/backend/distributed/commands/distribute_object_ops.c +++ b/src/backend/distributed/commands/distribute_object_ops.c @@ -473,8 +473,8 @@ static DistributeObjectOps Database_Create = { .postprocess = PostprocessCreateDatabaseStmt, .objectType = OBJECT_DATABASE, .operationType = DIST_OPS_CREATE, - .address = NULL, - .markDistributed = false, + .address = CreateDatabaseStmtObjectAddress, + .markDistributed = true, }; static DistributeObjectOps Database_Drop = { diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 22c35a694..b1f65177e 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -230,6 +230,9 @@ extern List * PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *que ProcessUtilityContext processUtilityContext); +extern List * CreateDatabaseStmtObjectAddress(Node *node, bool missing_ok, bool + isPostprocess); + extern List * PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext); From abf9dd9e596f7d2aacd365db9af19a7454d8a706 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 13 Oct 2023 04:36:49 +0300 Subject: [PATCH 62/63] Adds EnableCreateDatabasePropagation check --- src/backend/distributed/commands/database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index bc3e197a4..d177cdcea 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -263,7 +263,7 @@ PreprocessAlterDatabaseSetStmt(Node *node, const char *queryString, List * PostprocessCreateDatabaseStmt(Node *node, const char *queryString) { - if (!ShouldPropagate()) + if (!EnableCreateDatabasePropagation || !ShouldPropagate()) { return NIL; } From ca5e2348215b2ef25ca6ce3d79b71836f0c14956 Mon Sep 17 00:00:00 2001 From: gindibay Date: Fri, 13 Oct 2023 04:46:53 +0300 Subject: [PATCH 63/63] Adds EnableCreateDatabasePropagation for drop db --- src/backend/distributed/commands/database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/distributed/commands/database.c b/src/backend/distributed/commands/database.c index d177cdcea..8aee9213f 100644 --- a/src/backend/distributed/commands/database.c +++ b/src/backend/distributed/commands/database.c @@ -356,7 +356,7 @@ List * PreprocessDropDatabaseStmt(Node *node, const char *queryString, ProcessUtilityContext processUtilityContext) { - if (!ShouldPropagate()) + if (!EnableCreateDatabasePropagation || !ShouldPropagate()) { return NIL; }