mirror of https://github.com/citusdata/citus.git
Merge pull request #783 from robin900/new-extend-names
Provides safe, backwards-compatible shard-extended names to any object namepull/821/head
commit
6c0fc0c970
|
@ -8,7 +8,7 @@ EXTENSION = citus
|
||||||
EXTVERSIONS = 5.0 5.0-1 5.0-2 \
|
EXTVERSIONS = 5.0 5.0-1 5.0-2 \
|
||||||
5.1-1 5.1-2 5.1-3 5.1-4 5.1-5 5.1-6 5.1-7 5.1-8 \
|
5.1-1 5.1-2 5.1-3 5.1-4 5.1-5 5.1-6 5.1-7 5.1-8 \
|
||||||
5.2-1 5.2-2 5.2-3 5.2-4 \
|
5.2-1 5.2-2 5.2-3 5.2-4 \
|
||||||
6.0-1
|
6.0-1 6.0-2
|
||||||
|
|
||||||
# All citus--*.sql files in the source directory
|
# All citus--*.sql files in the source directory
|
||||||
DATA = $(patsubst $(citus_abs_srcdir)/%.sql,%.sql,$(wildcard $(citus_abs_srcdir)/$(EXTENSION)--*--*.sql))
|
DATA = $(patsubst $(citus_abs_srcdir)/%.sql,%.sql,$(wildcard $(citus_abs_srcdir)/$(EXTENSION)--*--*.sql))
|
||||||
|
@ -60,6 +60,8 @@ $(EXTENSION)--5.2-4.sql: $(EXTENSION)--5.2-3.sql $(EXTENSION)--5.2-3--5.2-4.sql
|
||||||
cat $^ > $@
|
cat $^ > $@
|
||||||
$(EXTENSION)--6.0-1.sql: $(EXTENSION)--5.2-4.sql $(EXTENSION)--5.2-4--6.0-1.sql
|
$(EXTENSION)--6.0-1.sql: $(EXTENSION)--5.2-4.sql $(EXTENSION)--5.2-4--6.0-1.sql
|
||||||
cat $^ > $@
|
cat $^ > $@
|
||||||
|
$(EXTENSION)--6.0-2.sql: $(EXTENSION)--6.0-1.sql $(EXTENSION)--6.0-1--6.0-2.sql
|
||||||
|
cat $^ > $@
|
||||||
|
|
||||||
NO_PGXS = 1
|
NO_PGXS = 1
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* citus--6.0-1--6.0-2.sql */
|
||||||
|
|
||||||
|
CREATE FUNCTION pg_catalog.shard_name(object_name regclass, shard_id bigint)
|
||||||
|
RETURNS text
|
||||||
|
LANGUAGE C STABLE
|
||||||
|
AS 'MODULE_PATHNAME', $$shard_name$$;
|
||||||
|
COMMENT ON FUNCTION pg_catalog.shard_name(object_name regclass, shard_id bigint)
|
||||||
|
IS 'returns shard-extended version of object name';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Citus extension
|
# Citus extension
|
||||||
comment = 'Citus distributed database'
|
comment = 'Citus distributed database'
|
||||||
default_version = '6.0-1'
|
default_version = '6.0-2'
|
||||||
module_pathname = '$libdir/citus'
|
module_pathname = '$libdir/citus'
|
||||||
relocatable = false
|
relocatable = false
|
||||||
schema = pg_catalog
|
schema = pg_catalog
|
||||||
|
|
|
@ -317,14 +317,13 @@ DropShards(Oid relationId, char *schemaName, char *relationName,
|
||||||
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
|
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
|
||||||
uint64 shardId = shardInterval->shardId;
|
uint64 shardId = shardInterval->shardId;
|
||||||
char *quotedShardName = NULL;
|
char *quotedShardName = NULL;
|
||||||
StringInfo shardName = makeStringInfo();
|
char *shardRelationName = pnstrdup(relationName, NAMEDATALEN);
|
||||||
|
|
||||||
Assert(shardInterval->relationId == relationId);
|
Assert(shardInterval->relationId == relationId);
|
||||||
|
|
||||||
/* Build shard relation name. */
|
/* Build shard relation name. */
|
||||||
appendStringInfoString(shardName, relationName);
|
AppendShardIdToName(&shardRelationName, shardId);
|
||||||
AppendShardIdToStringInfo(shardName, shardId);
|
quotedShardName = quote_qualified_identifier(schemaName, shardRelationName);
|
||||||
quotedShardName = quote_qualified_identifier(schemaName, shardName->data);
|
|
||||||
|
|
||||||
shardPlacementList = ShardPlacementList(shardId);
|
shardPlacementList = ShardPlacementList(shardId);
|
||||||
foreach(shardPlacementCell, shardPlacementList)
|
foreach(shardPlacementCell, shardPlacementList)
|
||||||
|
@ -386,7 +385,7 @@ DropShards(Oid relationId, char *schemaName, char *relationName,
|
||||||
workerName, workerPort);
|
workerName, workerPort);
|
||||||
|
|
||||||
ereport(WARNING, (errmsg("could not delete shard \"%s\" on node \"%s:%u\"",
|
ereport(WARNING, (errmsg("could not delete shard \"%s\" on node \"%s:%u\"",
|
||||||
shardName->data, workerName, workerPort),
|
shardRelationName, workerName, workerPort),
|
||||||
errdetail("Marking this shard placement for deletion")));
|
errdetail("Marking this shard placement for deletion")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,6 @@ DropShardsFromWorker(WorkerNode *workerNode, Oid relationId, List *shardInterval
|
||||||
char *schemaName = get_namespace_name(schemaId);
|
char *schemaName = get_namespace_name(schemaId);
|
||||||
char *relationName = get_rel_name(relationId);
|
char *relationName = get_rel_name(relationId);
|
||||||
char relationKind = get_rel_relkind(relationId);
|
char relationKind = get_rel_relkind(relationId);
|
||||||
StringInfo shardName = makeStringInfo();
|
|
||||||
StringInfo workerCommand = makeStringInfo();
|
StringInfo workerCommand = makeStringInfo();
|
||||||
ListCell *shardIntervalCell = NULL;
|
ListCell *shardIntervalCell = NULL;
|
||||||
|
|
||||||
|
@ -170,12 +169,11 @@ DropShardsFromWorker(WorkerNode *workerNode, Oid relationId, List *shardInterval
|
||||||
foreach(shardIntervalCell, shardIntervalList)
|
foreach(shardIntervalCell, shardIntervalList)
|
||||||
{
|
{
|
||||||
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
|
ShardInterval *shardInterval = (ShardInterval *) lfirst(shardIntervalCell);
|
||||||
|
char *shardName = pnstrdup(relationName, NAMEDATALEN);
|
||||||
char *quotedShardName = NULL;
|
char *quotedShardName = NULL;
|
||||||
|
|
||||||
resetStringInfo(shardName);
|
AppendShardIdToName(&shardName, shardInterval->shardId);
|
||||||
appendStringInfo(shardName, "%s", relationName);
|
quotedShardName = quote_qualified_identifier(schemaName, shardName);
|
||||||
AppendShardIdToStringInfo(shardName, shardInterval->shardId);
|
|
||||||
quotedShardName = quote_qualified_identifier(schemaName, shardName->data);
|
|
||||||
appendStringInfo(workerCommand, "%s", quotedShardName);
|
appendStringInfo(workerCommand, "%s", quotedShardName);
|
||||||
|
|
||||||
/* append a comma after the shard name if there are more shards */
|
/* append a comma after the shard name if there are more shards */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
|
#include "access/hash.h"
|
||||||
#include "access/htup.h"
|
#include "access/htup.h"
|
||||||
#include "access/skey.h"
|
#include "access/skey.h"
|
||||||
#include "access/stratnum.h"
|
#include "access/stratnum.h"
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "distributed/relay_utility.h"
|
#include "distributed/relay_utility.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
|
#include "mb/pg_wchar.h"
|
||||||
#include "nodes/nodes.h"
|
#include "nodes/nodes.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
|
@ -36,9 +38,11 @@
|
||||||
#include "nodes/primnodes.h"
|
#include "nodes/primnodes.h"
|
||||||
#include "nodes/value.h"
|
#include "nodes/value.h"
|
||||||
#include "storage/lock.h"
|
#include "storage/lock.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
#include "utils/elog.h"
|
#include "utils/elog.h"
|
||||||
#include "utils/errcodes.h"
|
#include "utils/errcodes.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/palloc.h"
|
#include "utils/palloc.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
|
|
||||||
|
@ -50,6 +54,9 @@ static void AppendShardIdToConstraintName(AlterTableCmd *command, uint64 shardId
|
||||||
static void SetSchemaNameIfNotExist(char **schemaName, char *newSchemaName);
|
static void SetSchemaNameIfNotExist(char **schemaName, char *newSchemaName);
|
||||||
static bool UpdateWholeRowColumnReferencesWalker(Node *node, uint64 *shardId);
|
static bool UpdateWholeRowColumnReferencesWalker(Node *node, uint64 *shardId);
|
||||||
|
|
||||||
|
/* exports for SQL callable functions */
|
||||||
|
PG_FUNCTION_INFO_V1(shard_name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelayEventExtendNames extends relation names in the given parse tree for
|
* RelayEventExtendNames extends relation names in the given parse tree for
|
||||||
* certain utility commands. The function more specifically extends table and
|
* certain utility commands. The function more specifically extends table and
|
||||||
|
@ -624,32 +631,120 @@ AppendShardIdToName(char **name, uint64 shardId)
|
||||||
{
|
{
|
||||||
char extendedName[NAMEDATALEN];
|
char extendedName[NAMEDATALEN];
|
||||||
uint32 extendedNameLength = 0;
|
uint32 extendedNameLength = 0;
|
||||||
|
int nameLength = strlen(*name);
|
||||||
|
char shardIdAndSeparator[NAMEDATALEN];
|
||||||
|
int shardIdAndSeparatorLength;
|
||||||
|
uint32 longNameHash = 0;
|
||||||
|
int multiByteClipLength = 0;
|
||||||
|
|
||||||
snprintf(extendedName, NAMEDATALEN, "%s%c" UINT64_FORMAT,
|
snprintf(shardIdAndSeparator, NAMEDATALEN, "%c" UINT64_FORMAT,
|
||||||
(*name), SHARD_NAME_SEPARATOR, shardId);
|
SHARD_NAME_SEPARATOR, shardId);
|
||||||
|
shardIdAndSeparatorLength = strlen(shardIdAndSeparator);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parser should have already checked that the table name has enough space
|
* If *name strlen is < (NAMEDATALEN - shardIdAndSeparatorLength),
|
||||||
* reserved for appending shardIds. Nonetheless, we perform an additional
|
* it is safe merely to append the separator and shardId.
|
||||||
* check here to verify that the appended name does not overflow.
|
|
||||||
*/
|
*/
|
||||||
extendedNameLength = strlen(extendedName) + 1;
|
|
||||||
if (extendedNameLength >= NAMEDATALEN)
|
if (nameLength < (NAMEDATALEN - shardIdAndSeparatorLength))
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("shard name too long to extend: \"%s\"", (*name))));
|
snprintf(extendedName, NAMEDATALEN, "%s%s", (*name), shardIdAndSeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise, we need to truncate the name further to accommodate
|
||||||
|
* a sufficient hash value. The resulting name will avoid collision
|
||||||
|
* with other hashed names such that for any given schema with
|
||||||
|
* 90 distinct object names that are long enough to require hashing
|
||||||
|
* (typically 57-63 characters), the chance of a collision existing is:
|
||||||
|
*
|
||||||
|
* If randomly generated UTF8 names:
|
||||||
|
* (1e-6) * (9.39323783788e-114) ~= (9.39e-120)
|
||||||
|
* If random case-insensitive ASCII names (letter first, 37 useful characters):
|
||||||
|
* (1e-6) * (2.80380202421e-74) ~= (2.8e-80)
|
||||||
|
* If names sharing only N distinct 45- to 47-character prefixes:
|
||||||
|
* (1e-6) * (1/N) = (1e-6/N)
|
||||||
|
* 1e-7 for 10 distinct prefixes
|
||||||
|
* 5e-8 for 20 distinct prefixes
|
||||||
|
*
|
||||||
|
* In practice, since shard IDs are globally unique, the risk of name collision
|
||||||
|
* exists only amongst objects that pertain to a single distributed table
|
||||||
|
* and are created for each shard: the table name and the names of any indexes
|
||||||
|
* or index-backed constraints. Since there are typically less than five such
|
||||||
|
* names, and almost never more than ten, the expected collision rate even in
|
||||||
|
* the worst case (ten names share same 45- to 47-character prefix) is roughly
|
||||||
|
* 1e-8: one in 100 million schemas will experience a name collision only if ALL
|
||||||
|
* 100 million schemas present the worst-case scenario.
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
longNameHash = hash_any((unsigned char *) (*name), nameLength);
|
||||||
|
multiByteClipLength = pg_mbcliplen(*name, nameLength, (NAMEDATALEN -
|
||||||
|
shardIdAndSeparatorLength -
|
||||||
|
10));
|
||||||
|
snprintf(extendedName, NAMEDATALEN, "%.*s%c%.8x%s",
|
||||||
|
multiByteClipLength, (*name),
|
||||||
|
SHARD_NAME_SEPARATOR, longNameHash,
|
||||||
|
shardIdAndSeparator);
|
||||||
|
}
|
||||||
|
extendedNameLength = strlen(extendedName) + 1;
|
||||||
|
Assert(extendedNameLength <= NAMEDATALEN);
|
||||||
|
|
||||||
(*name) = (char *) repalloc((*name), extendedNameLength);
|
(*name) = (char *) repalloc((*name), extendedNameLength);
|
||||||
snprintf((*name), extendedNameLength, "%s", extendedName);
|
snprintf((*name), extendedNameLength, "%s", extendedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AppendShardIdToStringInfo appends shardId to the given name, represented
|
* shard_name() provides a PG function interface to AppendShardNameToId above.
|
||||||
* by a StringInfo.
|
|
||||||
*/
|
*/
|
||||||
void
|
Datum
|
||||||
AppendShardIdToStringInfo(StringInfo name, uint64 shardId)
|
shard_name(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
appendStringInfo(name, "%c" UINT64_FORMAT, SHARD_NAME_SEPARATOR, shardId);
|
Oid relationId = InvalidOid;
|
||||||
|
int64 shardId = 0;
|
||||||
|
char *relationName = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Have to check arguments for NULLness as it can't be declared STRICT
|
||||||
|
* because of min/max arguments, which have to be NULLable for new shards.
|
||||||
|
*/
|
||||||
|
if (PG_ARGISNULL(0))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("object_name cannot be null")));
|
||||||
|
}
|
||||||
|
if (PG_ARGISNULL(1))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("shard_id cannot be null")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
relationId = PG_GETARG_OID(0);
|
||||||
|
shardId = PG_GETARG_INT64(1);
|
||||||
|
|
||||||
|
if (shardId <= 0)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("shard_id cannot be zero or negative value")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!OidIsValid(relationId))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("object_name does not reference a valid relation")));
|
||||||
|
}
|
||||||
|
|
||||||
|
relationName = get_rel_name(relationId);
|
||||||
|
|
||||||
|
if (relationName == NULL)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("object_name does not reference a valid relation")));
|
||||||
|
}
|
||||||
|
|
||||||
|
AppendShardIdToName(&relationName, shardId);
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(relationName));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#ifndef RELAY_UTILITY_H
|
#ifndef RELAY_UTILITY_H
|
||||||
#define RELAY_UTILITY_H
|
#define RELAY_UTILITY_H
|
||||||
|
|
||||||
|
#include "fmgr.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
#include "nodes/nodes.h"
|
#include "nodes/nodes.h"
|
||||||
|
|
||||||
|
@ -41,7 +42,5 @@ typedef enum
|
||||||
/* Function declarations to extend names in DDL commands */
|
/* Function declarations to extend names in DDL commands */
|
||||||
extern void RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId);
|
extern void RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId);
|
||||||
extern void AppendShardIdToName(char **name, uint64 shardId);
|
extern void AppendShardIdToName(char **name, uint64 shardId);
|
||||||
extern void AppendShardIdToStringInfo(StringInfo name, uint64 shardId);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* RELAY_UTILITY_H */
|
#endif /* RELAY_UTILITY_H */
|
||||||
|
|
|
@ -0,0 +1,398 @@
|
||||||
|
--
|
||||||
|
-- MULTI_NAME_LENGTHS
|
||||||
|
--
|
||||||
|
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 225000;
|
||||||
|
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 225000;
|
||||||
|
SET citus.multi_shard_commit_protocol = '2pc';
|
||||||
|
-- Verify that a table name > 56 characters gets hashed properly.
|
||||||
|
CREATE TABLE too_long_12345678901234567890123456789012345678901234567890 (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null);
|
||||||
|
SELECT master_create_distributed_table('too_long_12345678901234567890123456789012345678901234567890', 'col1', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards('too_long_12345678901234567890123456789012345678901234567890', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d too_long_*
|
||||||
|
Table "public.too_long_12345678901234567890123456789012345678_e0119164_225000"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
|
||||||
|
Table "public.too_long_12345678901234567890123456789012345678_e0119164_225001"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- Verify that the UDF works and rejects bad arguments.
|
||||||
|
SELECT shard_name(NULL, 666666);
|
||||||
|
ERROR: object_name cannot be null
|
||||||
|
SELECT shard_name(0, 666666);
|
||||||
|
ERROR: object_name does not reference a valid relation
|
||||||
|
SELECT shard_name('too_long_12345678901234567890123456789012345678901234567890'::regclass, 666666);
|
||||||
|
shard_name
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
too_long_12345678901234567890123456789012345678_e0119164_666666
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT shard_name('too_long_12345678901234567890123456789012345678901234567890'::regclass, NULL);
|
||||||
|
ERROR: shard_id cannot be null
|
||||||
|
SELECT shard_name('too_long_12345678901234567890123456789012345678901234567890'::regclass, -21);
|
||||||
|
ERROR: shard_id cannot be zero or negative value
|
||||||
|
DROP TABLE too_long_12345678901234567890123456789012345678901234567890 CASCADE;
|
||||||
|
-- Table to use for rename checks.
|
||||||
|
CREATE TABLE name_lengths (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null,
|
||||||
|
constraint constraint_a UNIQUE (col1)
|
||||||
|
);
|
||||||
|
SELECT master_create_distributed_table('name_lengths', 'col1', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards('name_lengths', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Verify that we CAN add columns with "too-long names", because
|
||||||
|
-- the columns' names are not extended in the corresponding shard tables.
|
||||||
|
ALTER TABLE name_lengths ADD COLUMN float_col_12345678901234567890123456789012345678901234567890 FLOAT;
|
||||||
|
NOTICE: using one-phase commit for distributed DDL commands
|
||||||
|
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||||
|
ALTER TABLE name_lengths ADD COLUMN date_col_12345678901234567890123456789012345678901234567890 DATE;
|
||||||
|
ALTER TABLE name_lengths ADD COLUMN int_col_12345678901234567890123456789012345678901234567890 INTEGER DEFAULT 1;
|
||||||
|
-- Placeholders for unsupported ALTER TABLE to add constraints with implicit names that are likely too long
|
||||||
|
ALTER TABLE name_lengths ADD UNIQUE (float_col_12345678901234567890123456789012345678901234567890);
|
||||||
|
ERROR: alter table command is currently supported
|
||||||
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT and TYPE subcommands are supported.
|
||||||
|
ALTER TABLE name_lengths ADD EXCLUDE (int_col_12345678901234567890123456789012345678901234567890 WITH =);
|
||||||
|
ERROR: alter table command is currently supported
|
||||||
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT and TYPE subcommands are supported.
|
||||||
|
ALTER TABLE name_lengths ADD CHECK (date_col_12345678901234567890123456789012345678901234567890 > '2014-01-01'::date);
|
||||||
|
ERROR: alter table command is currently supported
|
||||||
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT and TYPE subcommands are supported.
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d name_lengths_*
|
||||||
|
Table "public.name_lengths_225002"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------------------------------------------------------------+------------------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
float_col_12345678901234567890123456789012345678901234567890 | double precision |
|
||||||
|
date_col_12345678901234567890123456789012345678901234567890 | date |
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 | integer | default 1
|
||||||
|
Indexes:
|
||||||
|
"constraint_a_225002" UNIQUE CONSTRAINT, btree (col1)
|
||||||
|
|
||||||
|
Table "public.name_lengths_225003"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------------------------------------------------------------+------------------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
float_col_12345678901234567890123456789012345678901234567890 | double precision |
|
||||||
|
date_col_12345678901234567890123456789012345678901234567890 | date |
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 | integer | default 1
|
||||||
|
Indexes:
|
||||||
|
"constraint_a_225003" UNIQUE CONSTRAINT, btree (col1)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- Placeholders for unsupported add constraints with EXPLICIT names that are too long
|
||||||
|
ALTER TABLE name_lengths ADD CONSTRAINT nl_unique_12345678901234567890123456789012345678901234567890 UNIQUE (float_col_12345678901234567890123456789012345678901234567890);
|
||||||
|
ERROR: alter table command is currently supported
|
||||||
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT and TYPE subcommands are supported.
|
||||||
|
ALTER TABLE name_lengths ADD CONSTRAINT nl_exclude_12345678901234567890123456789012345678901234567890 EXCLUDE (int_col_12345678901234567890123456789012345678901234567890 WITH =);
|
||||||
|
ERROR: alter table command is currently supported
|
||||||
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT and TYPE subcommands are supported.
|
||||||
|
ALTER TABLE name_lengths ADD CONSTRAINT nl_checky_12345678901234567890123456789012345678901234567890 CHECK (date_col_12345678901234567890123456789012345678901234567890 >= '2014-01-01'::date);
|
||||||
|
ERROR: alter table command is currently supported
|
||||||
|
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT and TYPE subcommands are supported.
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d nl_*
|
||||||
|
\c - - - :master_port
|
||||||
|
-- Placeholders for RENAME operations
|
||||||
|
ALTER TABLE name_lengths RENAME TO name_len_12345678901234567890123456789012345678901234567890;
|
||||||
|
ERROR: renaming distributed tables or their objects is currently unsupported
|
||||||
|
ALTER TABLE name_lengths RENAME CONSTRAINT unique_12345678901234567890123456789012345678901234567890 TO unique2_12345678901234567890123456789012345678901234567890;
|
||||||
|
ERROR: renaming distributed tables or their objects is currently unsupported
|
||||||
|
-- Verify that CREATE INDEX on already distributed table has proper shard names.
|
||||||
|
CREATE INDEX tmp_idx_12345678901234567890123456789012345678901234567890 ON name_lengths(col2);
|
||||||
|
NOTICE: using one-phase commit for distributed DDL commands
|
||||||
|
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d tmp_idx_*
|
||||||
|
Index "public.tmp_idx_123456789012345678901234567890123456789_5e470afa_225002"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col2 | integer | col2
|
||||||
|
btree, for table "public.name_lengths_225002"
|
||||||
|
|
||||||
|
Index "public.tmp_idx_123456789012345678901234567890123456789_5e470afa_225003"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col2 | integer | col2
|
||||||
|
btree, for table "public.name_lengths_225003"
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- Verify that a new index name > 63 characters is auto-truncated
|
||||||
|
-- by the parser/rewriter before further processing, just as in Postgres.
|
||||||
|
CREATE INDEX tmp_idx_123456789012345678901234567890123456789012345678901234567890 ON name_lengths(col2);
|
||||||
|
NOTICE: identifier "tmp_idx_123456789012345678901234567890123456789012345678901234567890" will be truncated to "tmp_idx_1234567890123456789012345678901234567890123456789012345"
|
||||||
|
NOTICE: using one-phase commit for distributed DDL commands
|
||||||
|
HINT: You can enable two-phase commit for extra safety with: SET citus.multi_shard_commit_protocol TO '2pc'
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d tmp_idx_*
|
||||||
|
Index "public.tmp_idx_123456789012345678901234567890123456789_599636aa_225002"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col2 | integer | col2
|
||||||
|
btree, for table "public.name_lengths_225002"
|
||||||
|
|
||||||
|
Index "public.tmp_idx_123456789012345678901234567890123456789_599636aa_225003"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col2 | integer | col2
|
||||||
|
btree, for table "public.name_lengths_225003"
|
||||||
|
|
||||||
|
Index "public.tmp_idx_123456789012345678901234567890123456789_5e470afa_225002"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col2 | integer | col2
|
||||||
|
btree, for table "public.name_lengths_225002"
|
||||||
|
|
||||||
|
Index "public.tmp_idx_123456789012345678901234567890123456789_5e470afa_225003"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col2 | integer | col2
|
||||||
|
btree, for table "public.name_lengths_225003"
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- Verify that distributed tables with too-long names
|
||||||
|
-- for CHECK constraints are no trouble.
|
||||||
|
CREATE TABLE sneaky_name_lengths (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null,
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 integer not null,
|
||||||
|
CHECK (int_col_12345678901234567890123456789012345678901234567890 > 100)
|
||||||
|
);
|
||||||
|
SELECT master_create_distributed_table('sneaky_name_lengths', 'col1', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP TABLE sneaky_name_lengths CASCADE;
|
||||||
|
CREATE TABLE sneaky_name_lengths (
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 integer UNIQUE not null,
|
||||||
|
col2 integer not null,
|
||||||
|
CONSTRAINT checky_12345678901234567890123456789012345678901234567890 CHECK (int_col_123456789012345678901234567890123456789012345678901234 > 100)
|
||||||
|
);
|
||||||
|
\d sneaky_name_lengths*
|
||||||
|
Table "public.sneaky_name_lengths"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
----------------------------------------------------------------+---------+-----------
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"sneaky_name_lengths_int_col_1234567890123456789012345678901_key" UNIQUE CONSTRAINT, btree (int_col_123456789012345678901234567890123456789012345678901234)
|
||||||
|
Check constraints:
|
||||||
|
"checky_12345678901234567890123456789012345678901234567890" CHECK (int_col_123456789012345678901234567890123456789012345678901234 > 100)
|
||||||
|
|
||||||
|
Index "public.sneaky_name_lengths_int_col_1234567890123456789012345678901_key"
|
||||||
|
Column | Type | Definition
|
||||||
|
----------------------------------------------------------------+---------+----------------------------------------------------------------
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 | integer | int_col_123456789012345678901234567890123456789012345678901234
|
||||||
|
unique, btree, for table "public.sneaky_name_lengths"
|
||||||
|
|
||||||
|
SELECT master_create_distributed_table('sneaky_name_lengths', 'int_col_123456789012345678901234567890123456789012345678901234', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d sneaky_name_lengths*
|
||||||
|
Table "public.sneaky_name_lengths_225006"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
----------------------------------------------------------------+---------+-----------
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"sneaky_name_lengths_int_col_1234567890123456789_6402d2cd_225006" UNIQUE CONSTRAINT, btree (int_col_123456789012345678901234567890123456789012345678901234)
|
||||||
|
Check constraints:
|
||||||
|
"checky_12345678901234567890123456789012345678901234567890" CHECK (int_col_123456789012345678901234567890123456789012345678901234 > 100)
|
||||||
|
|
||||||
|
Table "public.sneaky_name_lengths_225007"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
----------------------------------------------------------------+---------+-----------
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"sneaky_name_lengths_int_col_1234567890123456789_6402d2cd_225007" UNIQUE CONSTRAINT, btree (int_col_123456789012345678901234567890123456789012345678901234)
|
||||||
|
Check constraints:
|
||||||
|
"checky_12345678901234567890123456789012345678901234567890" CHECK (int_col_123456789012345678901234567890123456789012345678901234 > 100)
|
||||||
|
|
||||||
|
Index "public.sneaky_name_lengths_int_col_1234567890123456789_6402d2cd_225006"
|
||||||
|
Column | Type | Definition
|
||||||
|
----------------------------------------------------------------+---------+----------------------------------------------------------------
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 | integer | int_col_123456789012345678901234567890123456789012345678901234
|
||||||
|
unique, btree, for table "public.sneaky_name_lengths_225006"
|
||||||
|
|
||||||
|
Index "public.sneaky_name_lengths_int_col_1234567890123456789_6402d2cd_225007"
|
||||||
|
Column | Type | Definition
|
||||||
|
----------------------------------------------------------------+---------+----------------------------------------------------------------
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 | integer | int_col_123456789012345678901234567890123456789012345678901234
|
||||||
|
unique, btree, for table "public.sneaky_name_lengths_225007"
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
DROP TABLE sneaky_name_lengths CASCADE;
|
||||||
|
-- verify that named constraint with too-long name gets hashed properly
|
||||||
|
CREATE TABLE sneaky_name_lengths (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null,
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 integer not null,
|
||||||
|
constraint unique_12345678901234567890123456789012345678901234567890 UNIQUE (col1)
|
||||||
|
);
|
||||||
|
SELECT master_create_distributed_table('sneaky_name_lengths', 'col1', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d sneaky_name_lengths*
|
||||||
|
Table "public.sneaky_name_lengths_225008"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
------------------------------------------------------------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"unique_1234567890123456789012345678901234567890_a5986f27_225008" UNIQUE CONSTRAINT, btree (col1)
|
||||||
|
|
||||||
|
Table "public.sneaky_name_lengths_225009"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
------------------------------------------------------------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"unique_1234567890123456789012345678901234567890_a5986f27_225009" UNIQUE CONSTRAINT, btree (col1)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
DROP TABLE sneaky_name_lengths CASCADE;
|
||||||
|
-- Verify that much larger shardIds are handled properly
|
||||||
|
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 2250000000000;
|
||||||
|
CREATE TABLE too_long_12345678901234567890123456789012345678901234567890 (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null);
|
||||||
|
SELECT master_create_distributed_table('too_long_12345678901234567890123456789012345678901234567890', 'col1', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards('too_long_12345678901234567890123456789012345678901234567890', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d too_long_*
|
||||||
|
Table "public.too_long_1234567890123456789012345678901_e0119164_2250000000000"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
|
||||||
|
Table "public.too_long_1234567890123456789012345678901_e0119164_2250000000001"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
DROP TABLE too_long_12345678901234567890123456789012345678901234567890 CASCADE;
|
||||||
|
-- Verify that multi-byte boundaries are respected for databases with UTF8 encoding.
|
||||||
|
CREATE TABLE U&"elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D" UESCAPE '!' (
|
||||||
|
col1 integer not null PRIMARY KEY,
|
||||||
|
col2 integer not null);
|
||||||
|
SELECT master_create_distributed_table(U&'elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D' UESCAPE '!', 'col1', 'hash');
|
||||||
|
master_create_distributed_table
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT master_create_worker_shards(U&'elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D' UESCAPE '!', '2', '2');
|
||||||
|
master_create_worker_shards
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d elephant_*
|
||||||
|
Index "public.elephant_слонслонслонсло_14d34928_2250000000002"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col1 | integer | col1
|
||||||
|
primary key, btree, for table "public.elephant_слонслонслонсло_c8b737c2_2250000000002"
|
||||||
|
|
||||||
|
Index "public.elephant_слонслонслонсло_14d34928_2250000000003"
|
||||||
|
Column | Type | Definition
|
||||||
|
--------+---------+------------
|
||||||
|
col1 | integer | col1
|
||||||
|
primary key, btree, for table "public.elephant_слонслонслонсло_c8b737c2_2250000000003"
|
||||||
|
|
||||||
|
Table "public.elephant_слонслонслонсло_c8b737c2_2250000000002"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"elephant_слонслонслонсло_14d34928_2250000000002" PRIMARY KEY, btree (col1)
|
||||||
|
|
||||||
|
Table "public.elephant_слонслонслонсло_c8b737c2_2250000000003"
|
||||||
|
Column | Type | Modifiers
|
||||||
|
--------+---------+-----------
|
||||||
|
col1 | integer | not null
|
||||||
|
col2 | integer | not null
|
||||||
|
Indexes:
|
||||||
|
"elephant_слонслонслонсло_14d34928_2250000000003" PRIMARY KEY, btree (col1)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
-- Clean up.
|
||||||
|
DROP TABLE name_lengths CASCADE;
|
||||||
|
DROP TABLE U&"elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D" UESCAPE '!' CASCADE;
|
|
@ -17,6 +17,7 @@
|
||||||
# ---
|
# ---
|
||||||
test: multi_extension
|
test: multi_extension
|
||||||
test: multi_table_ddl
|
test: multi_table_ddl
|
||||||
|
test: multi_name_lengths
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
# The following distributed tests depend on creating a partitioned table and
|
# The following distributed tests depend on creating a partitioned table and
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
--
|
||||||
|
-- MULTI_NAME_LENGTHS
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 225000;
|
||||||
|
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 225000;
|
||||||
|
|
||||||
|
SET citus.multi_shard_commit_protocol = '2pc';
|
||||||
|
|
||||||
|
-- Verify that a table name > 56 characters gets hashed properly.
|
||||||
|
CREATE TABLE too_long_12345678901234567890123456789012345678901234567890 (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null);
|
||||||
|
SELECT master_create_distributed_table('too_long_12345678901234567890123456789012345678901234567890', 'col1', 'hash');
|
||||||
|
SELECT master_create_worker_shards('too_long_12345678901234567890123456789012345678901234567890', '2', '2');
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d too_long_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Verify that the UDF works and rejects bad arguments.
|
||||||
|
SELECT shard_name(NULL, 666666);
|
||||||
|
SELECT shard_name(0, 666666);
|
||||||
|
SELECT shard_name('too_long_12345678901234567890123456789012345678901234567890'::regclass, 666666);
|
||||||
|
SELECT shard_name('too_long_12345678901234567890123456789012345678901234567890'::regclass, NULL);
|
||||||
|
SELECT shard_name('too_long_12345678901234567890123456789012345678901234567890'::regclass, -21);
|
||||||
|
|
||||||
|
DROP TABLE too_long_12345678901234567890123456789012345678901234567890 CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
-- Table to use for rename checks.
|
||||||
|
CREATE TABLE name_lengths (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null,
|
||||||
|
constraint constraint_a UNIQUE (col1)
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT master_create_distributed_table('name_lengths', 'col1', 'hash');
|
||||||
|
SELECT master_create_worker_shards('name_lengths', '2', '2');
|
||||||
|
|
||||||
|
-- Verify that we CAN add columns with "too-long names", because
|
||||||
|
-- the columns' names are not extended in the corresponding shard tables.
|
||||||
|
|
||||||
|
ALTER TABLE name_lengths ADD COLUMN float_col_12345678901234567890123456789012345678901234567890 FLOAT;
|
||||||
|
ALTER TABLE name_lengths ADD COLUMN date_col_12345678901234567890123456789012345678901234567890 DATE;
|
||||||
|
ALTER TABLE name_lengths ADD COLUMN int_col_12345678901234567890123456789012345678901234567890 INTEGER DEFAULT 1;
|
||||||
|
|
||||||
|
-- Placeholders for unsupported ALTER TABLE to add constraints with implicit names that are likely too long
|
||||||
|
ALTER TABLE name_lengths ADD UNIQUE (float_col_12345678901234567890123456789012345678901234567890);
|
||||||
|
ALTER TABLE name_lengths ADD EXCLUDE (int_col_12345678901234567890123456789012345678901234567890 WITH =);
|
||||||
|
ALTER TABLE name_lengths ADD CHECK (date_col_12345678901234567890123456789012345678901234567890 > '2014-01-01'::date);
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d name_lengths_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Placeholders for unsupported add constraints with EXPLICIT names that are too long
|
||||||
|
ALTER TABLE name_lengths ADD CONSTRAINT nl_unique_12345678901234567890123456789012345678901234567890 UNIQUE (float_col_12345678901234567890123456789012345678901234567890);
|
||||||
|
ALTER TABLE name_lengths ADD CONSTRAINT nl_exclude_12345678901234567890123456789012345678901234567890 EXCLUDE (int_col_12345678901234567890123456789012345678901234567890 WITH =);
|
||||||
|
ALTER TABLE name_lengths ADD CONSTRAINT nl_checky_12345678901234567890123456789012345678901234567890 CHECK (date_col_12345678901234567890123456789012345678901234567890 >= '2014-01-01'::date);
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d nl_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Placeholders for RENAME operations
|
||||||
|
ALTER TABLE name_lengths RENAME TO name_len_12345678901234567890123456789012345678901234567890;
|
||||||
|
ALTER TABLE name_lengths RENAME CONSTRAINT unique_12345678901234567890123456789012345678901234567890 TO unique2_12345678901234567890123456789012345678901234567890;
|
||||||
|
|
||||||
|
-- Verify that CREATE INDEX on already distributed table has proper shard names.
|
||||||
|
|
||||||
|
CREATE INDEX tmp_idx_12345678901234567890123456789012345678901234567890 ON name_lengths(col2);
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d tmp_idx_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Verify that a new index name > 63 characters is auto-truncated
|
||||||
|
-- by the parser/rewriter before further processing, just as in Postgres.
|
||||||
|
CREATE INDEX tmp_idx_123456789012345678901234567890123456789012345678901234567890 ON name_lengths(col2);
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d tmp_idx_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Verify that distributed tables with too-long names
|
||||||
|
-- for CHECK constraints are no trouble.
|
||||||
|
CREATE TABLE sneaky_name_lengths (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null,
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 integer not null,
|
||||||
|
CHECK (int_col_12345678901234567890123456789012345678901234567890 > 100)
|
||||||
|
);
|
||||||
|
SELECT master_create_distributed_table('sneaky_name_lengths', 'col1', 'hash');
|
||||||
|
SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2');
|
||||||
|
DROP TABLE sneaky_name_lengths CASCADE;
|
||||||
|
|
||||||
|
CREATE TABLE sneaky_name_lengths (
|
||||||
|
int_col_123456789012345678901234567890123456789012345678901234 integer UNIQUE not null,
|
||||||
|
col2 integer not null,
|
||||||
|
CONSTRAINT checky_12345678901234567890123456789012345678901234567890 CHECK (int_col_123456789012345678901234567890123456789012345678901234 > 100)
|
||||||
|
);
|
||||||
|
\d sneaky_name_lengths*
|
||||||
|
|
||||||
|
SELECT master_create_distributed_table('sneaky_name_lengths', 'int_col_123456789012345678901234567890123456789012345678901234', 'hash');
|
||||||
|
SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2');
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d sneaky_name_lengths*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
DROP TABLE sneaky_name_lengths CASCADE;
|
||||||
|
|
||||||
|
-- verify that named constraint with too-long name gets hashed properly
|
||||||
|
CREATE TABLE sneaky_name_lengths (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null,
|
||||||
|
int_col_12345678901234567890123456789012345678901234567890 integer not null,
|
||||||
|
constraint unique_12345678901234567890123456789012345678901234567890 UNIQUE (col1)
|
||||||
|
);
|
||||||
|
SELECT master_create_distributed_table('sneaky_name_lengths', 'col1', 'hash');
|
||||||
|
SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2');
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d sneaky_name_lengths*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
DROP TABLE sneaky_name_lengths CASCADE;
|
||||||
|
|
||||||
|
-- Verify that much larger shardIds are handled properly
|
||||||
|
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 2250000000000;
|
||||||
|
CREATE TABLE too_long_12345678901234567890123456789012345678901234567890 (
|
||||||
|
col1 integer not null,
|
||||||
|
col2 integer not null);
|
||||||
|
SELECT master_create_distributed_table('too_long_12345678901234567890123456789012345678901234567890', 'col1', 'hash');
|
||||||
|
SELECT master_create_worker_shards('too_long_12345678901234567890123456789012345678901234567890', '2', '2');
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d too_long_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
DROP TABLE too_long_12345678901234567890123456789012345678901234567890 CASCADE;
|
||||||
|
|
||||||
|
-- Verify that multi-byte boundaries are respected for databases with UTF8 encoding.
|
||||||
|
CREATE TABLE U&"elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D" UESCAPE '!' (
|
||||||
|
col1 integer not null PRIMARY KEY,
|
||||||
|
col2 integer not null);
|
||||||
|
SELECT master_create_distributed_table(U&'elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D' UESCAPE '!', 'col1', 'hash');
|
||||||
|
SELECT master_create_worker_shards(U&'elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D' UESCAPE '!', '2', '2');
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
\d elephant_*
|
||||||
|
\c - - - :master_port
|
||||||
|
|
||||||
|
-- Clean up.
|
||||||
|
DROP TABLE name_lengths CASCADE;
|
||||||
|
DROP TABLE U&"elephant_!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D!0441!043B!043E!043D" UESCAPE '!' CASCADE;
|
Loading…
Reference in New Issue