mirror of https://github.com/citusdata/citus.git
Merge pull request #1948 from citusdata/feature/alter-index
Add support for Alter Index Commands, and Storage Parameters on tables and indexes.pull/1962/head
commit
bff44394fb
|
@ -139,6 +139,7 @@ static void ErrorIfUnstableCreateOrAlterExtensionStmt(Node *parsetree);
|
||||||
static void ErrorIfUnsupportedIndexStmt(IndexStmt *createIndexStatement);
|
static void ErrorIfUnsupportedIndexStmt(IndexStmt *createIndexStatement);
|
||||||
static void ErrorIfUnsupportedDropIndexStmt(DropStmt *dropIndexStatement);
|
static void ErrorIfUnsupportedDropIndexStmt(DropStmt *dropIndexStatement);
|
||||||
static void ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement);
|
static void ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement);
|
||||||
|
static void ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement);
|
||||||
static void ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement);
|
static void ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement);
|
||||||
static void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
|
static void ErrorIfUnsupportedSeqStmt(CreateSeqStmt *createSeqStmt);
|
||||||
static void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt);
|
static void ErrorIfDistributedAlterSeqOwnedBy(AlterSeqStmt *alterSeqStmt);
|
||||||
|
@ -155,6 +156,7 @@ static void ErrorIfUnsupportedForeignConstraint(Relation relation,
|
||||||
static char * ExtractNewExtensionVersion(Node *parsetree);
|
static char * ExtractNewExtensionVersion(Node *parsetree);
|
||||||
static void CreateLocalTable(RangeVar *relation, char *nodeName, int32 nodePort);
|
static void CreateLocalTable(RangeVar *relation, char *nodeName, int32 nodePort);
|
||||||
static bool IsAlterTableRenameStmt(RenameStmt *renameStmt);
|
static bool IsAlterTableRenameStmt(RenameStmt *renameStmt);
|
||||||
|
static bool IsIndexRenameStmt(RenameStmt *renameStmt);
|
||||||
static bool AlterInvolvesPartitionColumn(AlterTableStmt *alterTableStatement,
|
static bool AlterInvolvesPartitionColumn(AlterTableStmt *alterTableStatement,
|
||||||
AlterTableCmd *command);
|
AlterTableCmd *command);
|
||||||
static void ExecuteDistributedDDLJob(DDLJob *ddlJob);
|
static void ExecuteDistributedDDLJob(DDLJob *ddlJob);
|
||||||
|
@ -365,7 +367,8 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
if (IsA(parsetree, AlterTableStmt))
|
if (IsA(parsetree, AlterTableStmt))
|
||||||
{
|
{
|
||||||
AlterTableStmt *alterTableStmt = (AlterTableStmt *) parsetree;
|
AlterTableStmt *alterTableStmt = (AlterTableStmt *) parsetree;
|
||||||
if (alterTableStmt->relkind == OBJECT_TABLE)
|
if (alterTableStmt->relkind == OBJECT_TABLE ||
|
||||||
|
alterTableStmt->relkind == OBJECT_INDEX)
|
||||||
{
|
{
|
||||||
ddlJobs = PlanAlterTableStmt(alterTableStmt, queryString);
|
ddlJobs = PlanAlterTableStmt(alterTableStmt, queryString);
|
||||||
}
|
}
|
||||||
|
@ -1237,6 +1240,7 @@ PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCo
|
||||||
LOCKMODE lockmode = 0;
|
LOCKMODE lockmode = 0;
|
||||||
Oid leftRelationId = InvalidOid;
|
Oid leftRelationId = InvalidOid;
|
||||||
Oid rightRelationId = InvalidOid;
|
Oid rightRelationId = InvalidOid;
|
||||||
|
char leftRelationKind;
|
||||||
bool isDistributedRelation = false;
|
bool isDistributedRelation = false;
|
||||||
List *commandList = NIL;
|
List *commandList = NIL;
|
||||||
ListCell *commandCell = NULL;
|
ListCell *commandCell = NULL;
|
||||||
|
@ -1254,13 +1258,38 @@ PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCo
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AlterTableStmt applies also to INDEX relations, and we have support for
|
||||||
|
* SET/SET storage parameters in Citus, so we might have to check for
|
||||||
|
* another relation here.
|
||||||
|
*/
|
||||||
|
leftRelationKind = get_rel_relkind(leftRelationId);
|
||||||
|
if (leftRelationKind == RELKIND_INDEX)
|
||||||
|
{
|
||||||
|
leftRelationId = IndexGetRelation(leftRelationId, false);
|
||||||
|
}
|
||||||
|
|
||||||
isDistributedRelation = IsDistributedTable(leftRelationId);
|
isDistributedRelation = IsDistributedTable(leftRelationId);
|
||||||
if (!isDistributedRelation)
|
if (!isDistributedRelation)
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorIfUnsupportedAlterTableStmt(alterTableStatement);
|
/*
|
||||||
|
* The PostgreSQL parser dispatches several commands into the node type
|
||||||
|
* AlterTableStmt, from ALTER INDEX to ALTER SEQUENCE or ALTER VIEW. Here
|
||||||
|
* we have a special implementation for ALTER INDEX, and a specific error
|
||||||
|
* message in case of unsupported sub-command.
|
||||||
|
*/
|
||||||
|
if (leftRelationKind == RELKIND_INDEX)
|
||||||
|
{
|
||||||
|
ErrorIfUnsupportedAlterIndexStmt(alterTableStatement);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* this function also accepts more than just RELKIND_RELATION... */
|
||||||
|
ErrorIfUnsupportedAlterTableStmt(alterTableStatement);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We check if there is a ADD FOREIGN CONSTRAINT command in sub commands list.
|
* We check if there is a ADD FOREIGN CONSTRAINT command in sub commands list.
|
||||||
|
@ -1371,11 +1400,17 @@ PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCo
|
||||||
static List *
|
static List *
|
||||||
PlanRenameStmt(RenameStmt *renameStmt, const char *renameCommand)
|
PlanRenameStmt(RenameStmt *renameStmt, const char *renameCommand)
|
||||||
{
|
{
|
||||||
Oid relationId = InvalidOid;
|
Oid objectRelationId = InvalidOid; /* SQL Object OID */
|
||||||
|
Oid tableRelationId = InvalidOid; /* Relation OID, maybe not the same. */
|
||||||
bool isDistributedRelation = false;
|
bool isDistributedRelation = false;
|
||||||
DDLJob *ddlJob = NULL;
|
DDLJob *ddlJob = NULL;
|
||||||
|
|
||||||
if (!IsAlterTableRenameStmt(renameStmt))
|
/*
|
||||||
|
* We only support some of the PostgreSQL supported RENAME statements, and
|
||||||
|
* our list include only renaming table and index (related) objects.
|
||||||
|
*/
|
||||||
|
if (!IsAlterTableRenameStmt(renameStmt) &&
|
||||||
|
!IsIndexRenameStmt(renameStmt))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
@ -1385,32 +1420,70 @@ PlanRenameStmt(RenameStmt *renameStmt, const char *renameCommand)
|
||||||
* RenameRelation(), renameatt() and RenameConstraint(). However, since all
|
* RenameRelation(), renameatt() and RenameConstraint(). However, since all
|
||||||
* three statements have identical lock levels, we just use a single statement.
|
* three statements have identical lock levels, we just use a single statement.
|
||||||
*/
|
*/
|
||||||
relationId = RangeVarGetRelid(renameStmt->relation, AccessExclusiveLock,
|
objectRelationId = RangeVarGetRelid(renameStmt->relation,
|
||||||
renameStmt->missing_ok);
|
AccessExclusiveLock,
|
||||||
|
renameStmt->missing_ok);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the table does not exist, don't do anything here to allow PostgreSQL
|
* If the table does not exist, don't do anything here to allow PostgreSQL
|
||||||
* to throw the appropriate error or notice message later.
|
* to throw the appropriate error or notice message later.
|
||||||
*/
|
*/
|
||||||
if (!OidIsValid(relationId))
|
if (!OidIsValid(objectRelationId))
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we have no planning to do unless the table is distributed */
|
/* we have no planning to do unless the table is distributed */
|
||||||
isDistributedRelation = IsDistributedTable(relationId);
|
switch (renameStmt->renameType)
|
||||||
|
{
|
||||||
|
case OBJECT_TABLE:
|
||||||
|
case OBJECT_COLUMN:
|
||||||
|
case OBJECT_TABCONSTRAINT:
|
||||||
|
{
|
||||||
|
/* the target object is our tableRelationId. */
|
||||||
|
tableRelationId = objectRelationId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OBJECT_INDEX:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* here, objRelationId points to the index relation entry, and we
|
||||||
|
* are interested into the entry of the table on which the index is
|
||||||
|
* defined.
|
||||||
|
*/
|
||||||
|
tableRelationId = IndexGetRelation(objectRelationId, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nodes that are not supported by Citus: we pass-through to the
|
||||||
|
* main PostgreSQL executor. Any Citus-supported RenameStmt
|
||||||
|
* renameType must appear above in the switch, explicitly.
|
||||||
|
*/
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDistributedRelation = IsDistributedTable(tableRelationId);
|
||||||
if (!isDistributedRelation)
|
if (!isDistributedRelation)
|
||||||
{
|
{
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We might ERROR out on some commands, but only for Citus tables where
|
||||||
|
* isDistributedRelation is true. That's why this test comes this late in
|
||||||
|
* the function.
|
||||||
|
*/
|
||||||
ErrorIfUnsupportedRenameStmt(renameStmt);
|
ErrorIfUnsupportedRenameStmt(renameStmt);
|
||||||
|
|
||||||
ddlJob = palloc0(sizeof(DDLJob));
|
ddlJob = palloc0(sizeof(DDLJob));
|
||||||
ddlJob->targetRelationId = relationId;
|
ddlJob->targetRelationId = tableRelationId;
|
||||||
ddlJob->concurrentIndexCmd = false;
|
ddlJob->concurrentIndexCmd = false;
|
||||||
ddlJob->commandString = renameCommand;
|
ddlJob->commandString = renameCommand;
|
||||||
ddlJob->taskList = DDLTaskList(relationId, renameCommand);
|
ddlJob->taskList = DDLTaskList(tableRelationId, renameCommand);
|
||||||
|
|
||||||
return list_make1(ddlJob);
|
return list_make1(ddlJob);
|
||||||
}
|
}
|
||||||
|
@ -1966,9 +2039,9 @@ ErrorIfUnsupportedDropIndexStmt(DropStmt *dropIndexStatement)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ErrorIfUnsupportedAlterTableStmt checks if the corresponding alter table statement
|
* ErrorIfUnsupportedAlterTableStmt checks if the corresponding alter table
|
||||||
* is supported for distributed tables and errors out if it is not. Currently,
|
* statement is supported for distributed tables and errors out if it is not.
|
||||||
* only the following commands are supported.
|
* Currently, only the following commands are supported.
|
||||||
*
|
*
|
||||||
* ALTER TABLE ADD|DROP COLUMN
|
* ALTER TABLE ADD|DROP COLUMN
|
||||||
* ALTER TABLE ALTER COLUMN SET DATA TYPE
|
* ALTER TABLE ALTER COLUMN SET DATA TYPE
|
||||||
|
@ -1976,6 +2049,8 @@ ErrorIfUnsupportedDropIndexStmt(DropStmt *dropIndexStatement)
|
||||||
* ALTER TABLE SET|DROP DEFAULT
|
* ALTER TABLE SET|DROP DEFAULT
|
||||||
* ALTER TABLE ADD|DROP CONSTRAINT
|
* ALTER TABLE ADD|DROP CONSTRAINT
|
||||||
* ALTER TABLE REPLICA IDENTITY
|
* ALTER TABLE REPLICA IDENTITY
|
||||||
|
* ALTER TABLE SET ()
|
||||||
|
* ALTER TABLE RESET ()
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
|
@ -2125,14 +2200,71 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AT_SetRelOptions: /* SET (...) */
|
||||||
|
case AT_ResetRelOptions: /* RESET (...) */
|
||||||
|
case AT_ReplaceRelOptions: /* replace entire option list */
|
||||||
|
{
|
||||||
|
/* this command is supported by Citus */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
ereport(ERROR,
|
||||||
errmsg("alter table command is currently unsupported"),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errdetail("Only ADD|DROP COLUMN, SET|DROP NOT NULL, "
|
errmsg("alter table command is currently unsupported"),
|
||||||
"SET|DROP DEFAULT, ADD|DROP CONSTRAINT, "
|
errdetail("Only ADD|DROP COLUMN, SET|DROP NOT NULL, "
|
||||||
"ATTACH|DETACH PARTITION and TYPE subcommands "
|
"SET|DROP DEFAULT, ADD|DROP CONSTRAINT, "
|
||||||
"are supported.")));
|
"SET (), RESET (), "
|
||||||
|
"ATTACH|DETACH PARTITION and TYPE subcommands "
|
||||||
|
"are supported.")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorIfUnsupportedAlterIndexStmt checks if the corresponding alter index
|
||||||
|
* statement is supported for distributed tables and errors out if it is not.
|
||||||
|
* Currently, only the following commands are supported.
|
||||||
|
*
|
||||||
|
* ALTER INDEX SET ()
|
||||||
|
* ALTER INDEX RESET ()
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement)
|
||||||
|
{
|
||||||
|
List *commandList = alterTableStatement->cmds;
|
||||||
|
ListCell *commandCell = NULL;
|
||||||
|
|
||||||
|
/* error out if any of the subcommands are unsupported */
|
||||||
|
foreach(commandCell, commandList)
|
||||||
|
{
|
||||||
|
AlterTableCmd *command = (AlterTableCmd *) lfirst(commandCell);
|
||||||
|
AlterTableType alterTableType = command->subtype;
|
||||||
|
|
||||||
|
switch (alterTableType)
|
||||||
|
{
|
||||||
|
case AT_SetRelOptions: /* SET (...) */
|
||||||
|
case AT_ResetRelOptions: /* RESET (...) */
|
||||||
|
case AT_ReplaceRelOptions: /* replace entire option list */
|
||||||
|
{
|
||||||
|
/* this command is supported by Citus */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unsupported create index statements */
|
||||||
|
case AT_SetTableSpace:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("alter index ... set tablespace ... "
|
||||||
|
"is currently unsupported"),
|
||||||
|
errdetail("Only RENAME TO, SET (), and RESET () "
|
||||||
|
"are supported.")));
|
||||||
|
return; /* keep compiler happy */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2733,14 +2865,14 @@ OptionsSpecifyOwnedBy(List *optionList, Oid *ownedByTableId)
|
||||||
* ErrorIfDistributedRenameStmt errors out if the corresponding rename statement
|
* ErrorIfDistributedRenameStmt errors out if the corresponding rename statement
|
||||||
* operates on any part of a distributed table other than a column.
|
* operates on any part of a distributed table other than a column.
|
||||||
*
|
*
|
||||||
* Note: This function handles only those rename statements which operate on tables.
|
* Note: This function handles RenameStmt applied to relations handed by Citus.
|
||||||
|
* At the moment of writing this comment, it could be either tables or indexes.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt)
|
ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt)
|
||||||
{
|
{
|
||||||
Assert(IsAlterTableRenameStmt(renameStmt));
|
if (IsAlterTableRenameStmt(renameStmt) &&
|
||||||
|
renameStmt->renameType == OBJECT_TABCONSTRAINT)
|
||||||
if (renameStmt->renameType == OBJECT_TABCONSTRAINT)
|
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("renaming constraints belonging to distributed tables is "
|
errmsg("renaming constraints belonging to distributed tables is "
|
||||||
|
@ -2860,6 +2992,26 @@ IsAlterTableRenameStmt(RenameStmt *renameStmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IsIndexRenameStmt returns whether the passed-in RenameStmt is the following
|
||||||
|
* form:
|
||||||
|
*
|
||||||
|
* - ALTER INDEX RENAME
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
IsIndexRenameStmt(RenameStmt *renameStmt)
|
||||||
|
{
|
||||||
|
bool isIndexRenameStmt = false;
|
||||||
|
|
||||||
|
if (renameStmt->renameType == OBJECT_INDEX)
|
||||||
|
{
|
||||||
|
isIndexRenameStmt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isIndexRenameStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AlterInvolvesPartitionColumn checks if the given alter table command
|
* AlterInvolvesPartitionColumn checks if the given alter table command
|
||||||
* involves relation's partition column.
|
* involves relation's partition column.
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "catalog/pg_extension.h"
|
#include "catalog/pg_extension.h"
|
||||||
#include "catalog/pg_foreign_data_wrapper.h"
|
#include "catalog/pg_foreign_data_wrapper.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "commands/extension.h"
|
#include "commands/extension.h"
|
||||||
#include "distributed/citus_ruleutils.h"
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
#include "parser/parse_utilcmd.h"
|
#include "parser/parse_utilcmd.h"
|
||||||
|
#include "parser/parser.h"
|
||||||
#include "storage/lock.h"
|
#include "storage/lock.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/array.h"
|
#include "utils/array.h"
|
||||||
|
@ -61,8 +63,11 @@
|
||||||
|
|
||||||
|
|
||||||
static void AppendOptionListToString(StringInfo stringData, List *options);
|
static void AppendOptionListToString(StringInfo stringData, List *options);
|
||||||
|
static void AppendStorageParametersToString(StringInfo stringBuffer,
|
||||||
|
List *optionList);
|
||||||
static const char * convert_aclright_to_string(int aclright);
|
static const char * convert_aclright_to_string(int aclright);
|
||||||
|
static void simple_quote_literal(StringInfo buf, const char *val);
|
||||||
|
static char * flatten_reloptions(Oid relid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pg_get_extensiondef_string finds the foreign data wrapper that corresponds to
|
* pg_get_extensiondef_string finds the foreign data wrapper that corresponds to
|
||||||
|
@ -474,6 +479,20 @@ pg_get_tableschemadef_string(Oid tableRelationId, bool includeSequenceDefaults)
|
||||||
appendStringInfo(&buffer, " PARTITION BY %s ", partitioningInformation);
|
appendStringInfo(&buffer, " PARTITION BY %s ", partitioningInformation);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add any reloptions (storage parameters) defined on the table in a WITH
|
||||||
|
* clause.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char *reloptions = flatten_reloptions(tableRelationId);
|
||||||
|
if (reloptions)
|
||||||
|
{
|
||||||
|
appendStringInfo(&buffer, " WITH (%s)", reloptions);
|
||||||
|
pfree(reloptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
relation_close(relation, AccessShareLock);
|
relation_close(relation, AccessShareLock);
|
||||||
|
|
||||||
return (buffer.data);
|
return (buffer.data);
|
||||||
|
@ -738,11 +757,7 @@ deparse_shard_index_statement(IndexStmt *origStmt, Oid distrelid, int64 shardid,
|
||||||
|
|
||||||
appendStringInfoString(buffer, ") ");
|
appendStringInfoString(buffer, ") ");
|
||||||
|
|
||||||
if (indexStmt->options != NIL)
|
AppendStorageParametersToString(buffer, indexStmt->options);
|
||||||
{
|
|
||||||
appendStringInfoString(buffer, "WITH ");
|
|
||||||
AppendOptionListToString(buffer, indexStmt->options);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indexStmt->whereClause != NULL)
|
if (indexStmt->whereClause != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1004,6 +1019,44 @@ AppendOptionListToString(StringInfo stringBuffer, List *optionList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AppendStorageParametersToString converts the storage parameter list to its
|
||||||
|
* textual format, and appends this text to the given string buffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AppendStorageParametersToString(StringInfo stringBuffer, List *optionList)
|
||||||
|
{
|
||||||
|
ListCell *optionCell = NULL;
|
||||||
|
bool firstOptionPrinted = false;
|
||||||
|
|
||||||
|
if (optionList == NIL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appendStringInfo(stringBuffer, " WITH (");
|
||||||
|
|
||||||
|
foreach(optionCell, optionList)
|
||||||
|
{
|
||||||
|
DefElem *option = (DefElem *) lfirst(optionCell);
|
||||||
|
char *optionName = option->defname;
|
||||||
|
char *optionValue = defGetString(option);
|
||||||
|
|
||||||
|
if (firstOptionPrinted)
|
||||||
|
{
|
||||||
|
appendStringInfo(stringBuffer, ", ");
|
||||||
|
}
|
||||||
|
firstOptionPrinted = true;
|
||||||
|
|
||||||
|
appendStringInfo(stringBuffer, "%s = %s ",
|
||||||
|
quote_identifier(optionName),
|
||||||
|
quote_literal_cstr(optionValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
appendStringInfo(stringBuffer, ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* copy of postgresql's function, which is static as well */
|
/* copy of postgresql's function, which is static as well */
|
||||||
static const char *
|
static const char *
|
||||||
convert_aclright_to_string(int aclright)
|
convert_aclright_to_string(int aclright)
|
||||||
|
@ -1112,3 +1165,127 @@ pg_get_replica_identity_command(Oid tableRelationId)
|
||||||
|
|
||||||
return (buf->len > 0) ? buf->data : NULL;
|
return (buf->len > 0) ? buf->data : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate a C string representing a relation's reloptions, or NULL if none.
|
||||||
|
*
|
||||||
|
* This function comes from PostgreSQL source code in
|
||||||
|
* src/backend/utils/adt/ruleutils.c
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
flatten_reloptions(Oid relid)
|
||||||
|
{
|
||||||
|
char *result = NULL;
|
||||||
|
HeapTuple tuple;
|
||||||
|
Datum reloptions;
|
||||||
|
bool isnull;
|
||||||
|
|
||||||
|
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
{
|
||||||
|
elog(ERROR, "cache lookup failed for relation %u", relid);
|
||||||
|
}
|
||||||
|
|
||||||
|
reloptions = SysCacheGetAttr(RELOID, tuple,
|
||||||
|
Anum_pg_class_reloptions, &isnull);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
StringInfoData buf;
|
||||||
|
Datum *options;
|
||||||
|
int noptions;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
deconstruct_array(DatumGetArrayTypeP(reloptions),
|
||||||
|
TEXTOID, -1, false, 'i',
|
||||||
|
&options, NULL, &noptions);
|
||||||
|
|
||||||
|
for (i = 0; i < noptions; i++)
|
||||||
|
{
|
||||||
|
char *option = TextDatumGetCString(options[i]);
|
||||||
|
char *name;
|
||||||
|
char *separator;
|
||||||
|
char *value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each array element should have the form name=value. If the "="
|
||||||
|
* is missing for some reason, treat it like an empty value.
|
||||||
|
*/
|
||||||
|
name = option;
|
||||||
|
separator = strchr(option, '=');
|
||||||
|
if (separator)
|
||||||
|
{
|
||||||
|
*separator = '\0';
|
||||||
|
value = separator + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
appendStringInfoString(&buf, ", ");
|
||||||
|
}
|
||||||
|
appendStringInfo(&buf, "%s=", quote_identifier(name));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In general we need to quote the value; but to avoid unnecessary
|
||||||
|
* clutter, do not quote if it is an identifier that would not
|
||||||
|
* need quoting. (We could also allow numbers, but that is a bit
|
||||||
|
* trickier than it looks --- for example, are leading zeroes
|
||||||
|
* significant? We don't want to assume very much here about what
|
||||||
|
* custom reloptions might mean.)
|
||||||
|
*/
|
||||||
|
if (quote_identifier(value) == value)
|
||||||
|
{
|
||||||
|
appendStringInfoString(&buf, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
simple_quote_literal(&buf, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = buf.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* simple_quote_literal - Format a string as a SQL literal, append to buf
|
||||||
|
*
|
||||||
|
* This function comes from PostgreSQL source code in
|
||||||
|
* src/backend/utils/adt/ruleutils.c
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
simple_quote_literal(StringInfo buf, const char *val)
|
||||||
|
{
|
||||||
|
const char *valptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We form the string literal according to the prevailing setting of
|
||||||
|
* standard_conforming_strings; we never use E''. User is responsible for
|
||||||
|
* making sure result is used correctly.
|
||||||
|
*/
|
||||||
|
appendStringInfoChar(buf, '\'');
|
||||||
|
for (valptr = val; *valptr; valptr++)
|
||||||
|
{
|
||||||
|
char ch = *valptr;
|
||||||
|
|
||||||
|
if (SQL_STR_DOUBLE(ch, !standard_conforming_strings))
|
||||||
|
{
|
||||||
|
appendStringInfoChar(buf, ch);
|
||||||
|
}
|
||||||
|
appendStringInfoChar(buf, ch);
|
||||||
|
}
|
||||||
|
appendStringInfoChar(buf, '\'');
|
||||||
|
}
|
||||||
|
|
|
@ -1385,7 +1385,7 @@ SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='reference_sche
|
||||||
-- as we expect, setting WITH OIDS does not work for reference tables
|
-- as we expect, setting WITH OIDS does not work for reference tables
|
||||||
ALTER TABLE reference_schema.reference_table_ddl SET WITH OIDS;
|
ALTER TABLE reference_schema.reference_table_ddl SET WITH OIDS;
|
||||||
ERROR: alter table command is currently unsupported
|
ERROR: alter table command is currently unsupported
|
||||||
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
||||||
-- now test the renaming of the table, and back to the expected name
|
-- now test the renaming of the table, and back to the expected name
|
||||||
ALTER TABLE reference_schema.reference_table_ddl RENAME TO reference_table_ddl_test;
|
ALTER TABLE reference_schema.reference_table_ddl RENAME TO reference_table_ddl_test;
|
||||||
ALTER TABLE reference_schema.reference_table_ddl_test RENAME TO reference_table_ddl;
|
ALTER TABLE reference_schema.reference_table_ddl_test RENAME TO reference_table_ddl;
|
||||||
|
|
|
@ -26,10 +26,18 @@ CREATE TABLE lineitem_alter (
|
||||||
l_shipinstruct char(25) not null,
|
l_shipinstruct char(25) not null,
|
||||||
l_shipmode char(10) not null,
|
l_shipmode char(10) not null,
|
||||||
l_comment varchar(44) not null
|
l_comment varchar(44) not null
|
||||||
);
|
)
|
||||||
|
WITH ( fillfactor = 80 );
|
||||||
SELECT master_create_distributed_table('lineitem_alter', 'l_orderkey', 'append');
|
SELECT master_create_distributed_table('lineitem_alter', 'l_orderkey', 'append');
|
||||||
\copy lineitem_alter FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
|
\copy lineitem_alter FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
|
||||||
|
|
||||||
|
-- verify that the storage options made it to the table definitions
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
-- Verify that we can add columns
|
-- Verify that we can add columns
|
||||||
|
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
|
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
|
||||||
|
@ -372,9 +380,39 @@ ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
||||||
|
|
||||||
-- show rename worked on one worker, too
|
-- show rename worked on one worker, too
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220009' /* failed copy trails */ ORDER BY relname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- verify that we can set and reset storage parameters
|
||||||
|
ALTER TABLE lineitem_alter SET(fillfactor=40);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220009' /* failed copy trails */ ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
ALTER TABLE lineitem_alter RESET(fillfactor);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220009' /* failed copy trails */ ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- verify that we can rename indexes on distributed tables
|
||||||
|
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
|
||||||
|
ALTER INDEX temp_index_1 RENAME TO idx_lineitem_linenumber;
|
||||||
|
|
||||||
|
-- verify rename is performed
|
||||||
|
SELECT relname FROM pg_class WHERE relname = 'idx_lineitem_linenumber';
|
||||||
|
|
||||||
|
-- show rename worked on one worker, too
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'idx_lineitem_linenumber%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- now get rid of the index
|
||||||
|
DROP INDEX idx_lineitem_linenumber;
|
||||||
|
|
||||||
-- verify that we don't intercept DDL commands if propagation is turned off
|
-- verify that we don't intercept DDL commands if propagation is turned off
|
||||||
SET citus.enable_ddl_propagation to false;
|
SET citus.enable_ddl_propagation to false;
|
||||||
|
|
||||||
|
@ -502,3 +540,45 @@ END;
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
|
SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Test WITH options on a normal simple hash-distributed table
|
||||||
|
CREATE TABLE hash_dist(id bigint primary key, f1 text) WITH (fillfactor=40);
|
||||||
|
SELECT create_distributed_table('hash_dist','id');
|
||||||
|
|
||||||
|
-- verify that the storage options made it to the table definitions
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- verify that we can set and reset index storage parameters
|
||||||
|
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
ALTER INDEX hash_dist_pkey RESET(fillfactor);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
|
||||||
|
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
|
||||||
|
|
||||||
|
-- verify that we can add indexes with new storage options
|
||||||
|
CREATE UNIQUE INDEX another_index ON hash_dist(id) WITH (fillfactor=50);
|
||||||
|
|
||||||
|
-- show the index and its storage options on coordinator, then workers
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'another_index';
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- get rid of the index
|
||||||
|
DROP INDEX another_index;
|
||||||
|
|
|
@ -22,7 +22,8 @@ CREATE TABLE lineitem_alter (
|
||||||
l_shipinstruct char(25) not null,
|
l_shipinstruct char(25) not null,
|
||||||
l_shipmode char(10) not null,
|
l_shipmode char(10) not null,
|
||||||
l_comment varchar(44) not null
|
l_comment varchar(44) not null
|
||||||
);
|
)
|
||||||
|
WITH ( fillfactor = 80 );
|
||||||
SELECT master_create_distributed_table('lineitem_alter', 'l_orderkey', 'append');
|
SELECT master_create_distributed_table('lineitem_alter', 'l_orderkey', 'append');
|
||||||
master_create_distributed_table
|
master_create_distributed_table
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
@ -30,6 +31,24 @@ SELECT master_create_distributed_table('lineitem_alter', 'l_orderkey', 'append')
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
\copy lineitem_alter FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
|
\copy lineitem_alter FROM '@abs_srcdir@/data/lineitem.1.data' with delimiter '|'
|
||||||
|
-- verify that the storage options made it to the table definitions
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
relname | reloptions
|
||||||
|
----------------+-----------------
|
||||||
|
lineitem_alter | {fillfactor=80}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
-----------------------+-----------------
|
||||||
|
lineitem_alter_220000 | {fillfactor=80}
|
||||||
|
lineitem_alter_220001 | {fillfactor=80}
|
||||||
|
lineitem_alter_220002 | {fillfactor=80}
|
||||||
|
lineitem_alter_220003 | {fillfactor=80}
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
-- Verify that we can add columns
|
-- Verify that we can add columns
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
|
ALTER TABLE lineitem_alter ADD COLUMN float_column FLOAT;
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN date_column DATE;
|
ALTER TABLE lineitem_alter ADD COLUMN date_column DATE;
|
||||||
|
@ -328,7 +347,7 @@ SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineite
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
|
ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
|
||||||
ALTER COLUMN int_column1 SET STATISTICS 10;
|
ALTER COLUMN int_column1 SET STATISTICS 10;
|
||||||
ERROR: alter table command is currently unsupported
|
ERROR: alter table command is currently unsupported
|
||||||
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
||||||
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
|
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
|
||||||
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
|
||||||
Column | Type | Modifiers
|
Column | Type | Modifiers
|
||||||
|
@ -360,12 +379,12 @@ ERROR: cannot execute ALTER TABLE command involving partition column
|
||||||
-- Verify that we error out on unsupported statement types
|
-- Verify that we error out on unsupported statement types
|
||||||
ALTER TABLE lineitem_alter ALTER COLUMN l_orderkey SET STATISTICS 100;
|
ALTER TABLE lineitem_alter ALTER COLUMN l_orderkey SET STATISTICS 100;
|
||||||
ERROR: alter table command is currently unsupported
|
ERROR: alter table command is currently unsupported
|
||||||
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
||||||
ALTER TABLE lineitem_alter DROP CONSTRAINT IF EXISTS non_existent_contraint;
|
ALTER TABLE lineitem_alter DROP CONSTRAINT IF EXISTS non_existent_contraint;
|
||||||
NOTICE: constraint "non_existent_contraint" of relation "lineitem_alter" does not exist, skipping
|
NOTICE: constraint "non_existent_contraint" of relation "lineitem_alter" does not exist, skipping
|
||||||
ALTER TABLE lineitem_alter SET WITHOUT OIDS;
|
ALTER TABLE lineitem_alter SET WITHOUT OIDS;
|
||||||
ERROR: alter table command is currently unsupported
|
ERROR: alter table command is currently unsupported
|
||||||
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
|
||||||
-- Verify that we error out in case of postgres errors on supported statement
|
-- Verify that we error out in case of postgres errors on supported statement
|
||||||
-- types
|
-- types
|
||||||
ALTER TABLE lineitem_alter ADD COLUMN new_column non_existent_type;
|
ALTER TABLE lineitem_alter ADD COLUMN new_column non_existent_type;
|
||||||
|
@ -823,7 +842,7 @@ SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_renamed%' ORDER BY re
|
||||||
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
ALTER TABLE lineitem_renamed RENAME TO lineitem_alter;
|
||||||
-- show rename worked on one worker, too
|
-- show rename worked on one worker, too
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relname;
|
SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220009' /* failed copy trails */ ORDER BY relname;
|
||||||
relname
|
relname
|
||||||
-----------------------
|
-----------------------
|
||||||
lineitem_alter_220000
|
lineitem_alter_220000
|
||||||
|
@ -835,15 +854,105 @@ SELECT relname FROM pg_class WHERE relname LIKE 'lineitem_alter%' ORDER BY relna
|
||||||
lineitem_alter_220006
|
lineitem_alter_220006
|
||||||
lineitem_alter_220007
|
lineitem_alter_220007
|
||||||
lineitem_alter_220008
|
lineitem_alter_220008
|
||||||
lineitem_alter_220009
|
|
||||||
lineitem_alter_220010
|
lineitem_alter_220010
|
||||||
lineitem_alter_220011
|
lineitem_alter_220011
|
||||||
lineitem_alter_220012
|
lineitem_alter_220012
|
||||||
lineitem_alter_220013
|
lineitem_alter_220013
|
||||||
lineitem_alter_220014
|
lineitem_alter_220014
|
||||||
(15 rows)
|
(14 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
-- verify that we can set and reset storage parameters
|
||||||
|
ALTER TABLE lineitem_alter SET(fillfactor=40);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
relname | reloptions
|
||||||
|
----------------+-----------------
|
||||||
|
lineitem_alter | {fillfactor=40}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220009' /* failed copy trails */ ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
-----------------------+-----------------
|
||||||
|
lineitem_alter_220000 | {fillfactor=40}
|
||||||
|
lineitem_alter_220001 | {fillfactor=40}
|
||||||
|
lineitem_alter_220002 | {fillfactor=40}
|
||||||
|
lineitem_alter_220003 | {fillfactor=40}
|
||||||
|
lineitem_alter_220004 | {fillfactor=40}
|
||||||
|
lineitem_alter_220005 | {fillfactor=40}
|
||||||
|
lineitem_alter_220006 | {fillfactor=40}
|
||||||
|
lineitem_alter_220007 | {fillfactor=40}
|
||||||
|
lineitem_alter_220008 | {fillfactor=40}
|
||||||
|
lineitem_alter_220010 | {fillfactor=40}
|
||||||
|
lineitem_alter_220011 | {fillfactor=40}
|
||||||
|
lineitem_alter_220012 | {fillfactor=40}
|
||||||
|
lineitem_alter_220013 | {fillfactor=40}
|
||||||
|
lineitem_alter_220014 | {fillfactor=40}
|
||||||
|
(14 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
ALTER TABLE lineitem_alter RESET(fillfactor);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'lineitem_alter';
|
||||||
|
relname | reloptions
|
||||||
|
----------------+------------
|
||||||
|
lineitem_alter |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'lineitem_alter%' AND relname <> 'lineitem_alter_220009' /* failed copy trails */ ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
-----------------------+------------
|
||||||
|
lineitem_alter_220000 |
|
||||||
|
lineitem_alter_220001 |
|
||||||
|
lineitem_alter_220002 |
|
||||||
|
lineitem_alter_220003 |
|
||||||
|
lineitem_alter_220004 |
|
||||||
|
lineitem_alter_220005 |
|
||||||
|
lineitem_alter_220006 |
|
||||||
|
lineitem_alter_220007 |
|
||||||
|
lineitem_alter_220008 |
|
||||||
|
lineitem_alter_220010 |
|
||||||
|
lineitem_alter_220011 |
|
||||||
|
lineitem_alter_220012 |
|
||||||
|
lineitem_alter_220013 |
|
||||||
|
lineitem_alter_220014 |
|
||||||
|
(14 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- verify that we can rename indexes on distributed tables
|
||||||
|
CREATE INDEX temp_index_1 ON lineitem_alter(l_linenumber);
|
||||||
|
ALTER INDEX temp_index_1 RENAME TO idx_lineitem_linenumber;
|
||||||
|
-- verify rename is performed
|
||||||
|
SELECT relname FROM pg_class WHERE relname = 'idx_lineitem_linenumber';
|
||||||
|
relname
|
||||||
|
-------------------------
|
||||||
|
idx_lineitem_linenumber
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- show rename worked on one worker, too
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'idx_lineitem_linenumber%' ORDER BY relname;
|
||||||
|
relname
|
||||||
|
--------------------------------
|
||||||
|
idx_lineitem_linenumber_220000
|
||||||
|
idx_lineitem_linenumber_220001
|
||||||
|
idx_lineitem_linenumber_220002
|
||||||
|
idx_lineitem_linenumber_220003
|
||||||
|
idx_lineitem_linenumber_220004
|
||||||
|
idx_lineitem_linenumber_220005
|
||||||
|
idx_lineitem_linenumber_220006
|
||||||
|
idx_lineitem_linenumber_220007
|
||||||
|
idx_lineitem_linenumber_220008
|
||||||
|
idx_lineitem_linenumber_220010
|
||||||
|
idx_lineitem_linenumber_220011
|
||||||
|
idx_lineitem_linenumber_220012
|
||||||
|
idx_lineitem_linenumber_220013
|
||||||
|
idx_lineitem_linenumber_220014
|
||||||
|
(14 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- now get rid of the index
|
||||||
|
DROP INDEX idx_lineitem_linenumber;
|
||||||
-- verify that we don't intercept DDL commands if propagation is turned off
|
-- verify that we don't intercept DDL commands if propagation is turned off
|
||||||
SET citus.enable_ddl_propagation to false;
|
SET citus.enable_ddl_propagation to false;
|
||||||
-- table rename statement can be performed on the coordinator only now
|
-- table rename statement can be performed on the coordinator only now
|
||||||
|
@ -1021,3 +1130,92 @@ SELECT relname FROM pg_class WHERE relname LIKE 'test_table_1%';
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
|
-- Test WITH options on a normal simple hash-distributed table
|
||||||
|
CREATE TABLE hash_dist(id bigint primary key, f1 text) WITH (fillfactor=40);
|
||||||
|
SELECT create_distributed_table('hash_dist','id');
|
||||||
|
create_distributed_table
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that the storage options made it to the table definitions
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist';
|
||||||
|
relname | reloptions
|
||||||
|
-----------+-----------------
|
||||||
|
hash_dist | {fillfactor=40}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relkind = 'r' AND relname LIKE 'hash_dist%' ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
------------------+-----------------
|
||||||
|
hash_dist_220033 | {fillfactor=40}
|
||||||
|
hash_dist_220034 | {fillfactor=40}
|
||||||
|
hash_dist_220035 | {fillfactor=40}
|
||||||
|
hash_dist_220036 | {fillfactor=40}
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- verify that we can set and reset index storage parameters
|
||||||
|
ALTER INDEX hash_dist_pkey SET(fillfactor=40);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
|
relname | reloptions
|
||||||
|
----------------+-----------------
|
||||||
|
hash_dist_pkey | {fillfactor=40}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey%' ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
-----------------------+-----------------
|
||||||
|
hash_dist_pkey_220033 | {fillfactor=40}
|
||||||
|
hash_dist_pkey_220034 | {fillfactor=40}
|
||||||
|
hash_dist_pkey_220035 | {fillfactor=40}
|
||||||
|
hash_dist_pkey_220036 | {fillfactor=40}
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
ALTER INDEX hash_dist_pkey RESET(fillfactor);
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'hash_dist_pkey';
|
||||||
|
relname | reloptions
|
||||||
|
----------------+------------
|
||||||
|
hash_dist_pkey |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'hash_dist_pkey%' ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
-----------------------+------------
|
||||||
|
hash_dist_pkey_220033 |
|
||||||
|
hash_dist_pkey_220034 |
|
||||||
|
hash_dist_pkey_220035 |
|
||||||
|
hash_dist_pkey_220036 |
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- verify error message on ALTER INDEX, SET TABLESPACE is unsupported
|
||||||
|
ALTER INDEX hash_dist_pkey SET TABLESPACE foo;
|
||||||
|
ERROR: alter index ... set tablespace ... is currently unsupported
|
||||||
|
DETAIL: Only RENAME TO, SET (), and RESET () are supported.
|
||||||
|
-- verify that we can add indexes with new storage options
|
||||||
|
CREATE UNIQUE INDEX another_index ON hash_dist(id) WITH (fillfactor=50);
|
||||||
|
-- show the index and its storage options on coordinator, then workers
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname = 'another_index';
|
||||||
|
relname | reloptions
|
||||||
|
---------------+-----------------
|
||||||
|
another_index | {fillfactor=50}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname, reloptions FROM pg_class WHERE relname LIKE 'another_index%' ORDER BY relname;
|
||||||
|
relname | reloptions
|
||||||
|
----------------------+-----------------
|
||||||
|
another_index_220033 | {fillfactor=50}
|
||||||
|
another_index_220034 | {fillfactor=50}
|
||||||
|
another_index_220035 | {fillfactor=50}
|
||||||
|
another_index_220036 | {fillfactor=50}
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- get rid of the index
|
||||||
|
DROP INDEX another_index;
|
||||||
|
|
Loading…
Reference in New Issue