From 09763239a233a216d8b91277129eb8d79edf71db Mon Sep 17 00:00:00 2001 From: Sumit Jaiswal Date: Mon, 3 Mar 2025 09:25:08 +0000 Subject: [PATCH] Test fix Signed-off-by: Sumit Jaiswal --- contrib/babelfishpg_tsql/antlr/TSqlParser.g4 | 2 +- contrib/babelfishpg_tsql/runtime/functions.c | 18 +- .../sql/babelfish_partitions.sql | 1 + .../babelfishpg_tsql--5.1.0--5.2.0.sql | 19 + contrib/babelfishpg_tsql/src/catalog.c | 11 +- contrib/babelfishpg_tsql/src/catalog.h | 5 +- contrib/babelfishpg_tsql/src/pl_exec-2.c | 45 +- contrib/babelfishpg_tsql/src/pltsql.h | 1 + .../babelfishpg_tsql/src/pltsql_partition.c | 21 +- contrib/babelfishpg_tsql/src/tsqlIface.cpp | 8 +- test/JDBC/expected/PARTITION-collations.out | 743 ++++++++++++++++++ test/JDBC/expected/PARTITION-vu-prepare.out | 51 +- test/JDBC/expected/PARTITION-vu-verify.out | 90 ++- .../db_collation/PARTITION-vu-verify.out | 90 ++- .../parallel_query/PARTITION-vu-verify.out | 90 ++- test/JDBC/input/PARTITION-collations.sql | 529 +++++++++++++ test/JDBC/input/PARTITION-vu-prepare.mix | 51 +- test/JDBC/input/PARTITION-vu-verify.mix | 66 +- 18 files changed, 1819 insertions(+), 22 deletions(-) create mode 100644 test/JDBC/expected/PARTITION-collations.out create mode 100644 test/JDBC/input/PARTITION-collations.sql diff --git a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 index c429fae2d00..e400ba0064d 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 @@ -1163,7 +1163,7 @@ alter_partition_function ; create_partition_function - : CREATE PARTITION FUNCTION partition_function_name=id LR_BRACKET data_type RR_BRACKET AS RANGE (LEFT | RIGHT)? FOR VALUES LR_BRACKET expression_list? RR_BRACKET + : CREATE PARTITION FUNCTION partition_function_name=id LR_BRACKET data_type collation? RR_BRACKET AS RANGE (LEFT | RIGHT)? FOR VALUES LR_BRACKET expression_list? RR_BRACKET ; // https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-partition-scheme-transact-sql diff --git a/contrib/babelfishpg_tsql/runtime/functions.c b/contrib/babelfishpg_tsql/runtime/functions.c index 1189a498937..f98b6b1b9a8 100644 --- a/contrib/babelfishpg_tsql/runtime/functions.c +++ b/contrib/babelfishpg_tsql/runtime/functions.c @@ -1987,6 +1987,8 @@ search_partition(PG_FUNCTION_ARGS) Datum arg; Oid argtypeid; char *func_param_typname = NULL; + char *func_param_collation; + Oid collation_oid = InvalidOid; Oid func_param_typoid; Oid sqlvariant_typoid; Datum *range_values; @@ -1999,6 +2001,13 @@ search_partition(PG_FUNCTION_ARGS) if (!PG_ARGISNULL(2)) /* Database is specified. */ { char *db_name = text_to_cstring(PG_GETARG_TEXT_P(2)); + /* Lowercase the db_name, if needed. */ + if (pltsql_case_insensitive_identifiers) + { + char *tmp = db_name; + db_name = downcase_identifier(tmp, strlen(tmp), false, false); + pfree(tmp); + } dbid = get_db_id(db_name); if (!DbidIsValid(dbid)) ereport(ERROR, @@ -2037,6 +2046,7 @@ search_partition(PG_FUNCTION_ARGS) if (HeapTupleIsValid(tuple)) { func_param_typname = TextDatumGetCString(heap_getattr(tuple, Anum_bbf_partition_function_input_parameter_type, RelationGetDescr(rel), &isnull)); + func_param_collation = NameStr(*DatumGetName(heap_getattr(tuple, Anum_bbf_partition_function_input_parameter_collation, RelationGetDescr(rel), &isnull))); values = DatumGetArrayTypeP(heap_getattr(tuple, Anum_bbf_partition_function_range_values, RelationGetDescr(rel), &isnull)); deconstruct_array(values, sqlvariant_typoid, -1, false, 'i', &range_values, &nulls, &nelems); @@ -2069,6 +2079,12 @@ search_partition(PG_FUNCTION_ARGS) /* Get OID of partition function parameter type. */ func_param_typoid = (*common_utility_plugin_ptr->get_tsql_datatype_oid) (func_param_typname); + + /* Get collation oid from partition function collation. */ + if (func_param_collation) + { + collation_oid = get_collation_oid(list_make1(makeString(func_param_collation)), false); + } /* * Implicitly convert input value to parameter type of @@ -2096,7 +2112,7 @@ search_partition(PG_FUNCTION_ARGS) ObjectIdGetDatum(get_namespace_oid("sys", false))); cxt.function_oid = cmpfunction_oid; - cxt.colloid = tsql_get_database_or_server_collation_oid_internal(false); + cxt.colloid = collation_oid; /* Perform binary search on sorted range values. */ result = tsql_bsearch_arg(&arg, range_values, nelems, sizeof(Datum), tsql_compare_values, &cxt); diff --git a/contrib/babelfishpg_tsql/sql/babelfish_partitions.sql b/contrib/babelfishpg_tsql/sql/babelfish_partitions.sql index fecd4d28cec..314a9071829 100644 --- a/contrib/babelfishpg_tsql/sql/babelfish_partitions.sql +++ b/contrib/babelfishpg_tsql/sql/babelfish_partitions.sql @@ -10,6 +10,7 @@ CREATE TABLE sys.babelfish_partition_function range_values sys.sql_variant[] CHECK (array_length(range_values, 1) < 15000), -- boundary values create_date SYS.DATETIME NOT NULL, modify_date SYS.DATETIME NOT NULL, + input_parameter_collation NAME, -- collation of the input parameter PRIMARY KEY(dbid, partition_function_name) ); diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--5.1.0--5.2.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--5.1.0--5.2.0.sql index fb578636653..9bfbd58c669 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--5.1.0--5.2.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--5.1.0--5.2.0.sql @@ -450,6 +450,25 @@ BEGIN END; $$; +DO $$ +BEGIN +IF NOT EXISTS(SELECT 1 FROM information_schema.columns WHERE table_name = 'babelfish_partition_function' AND table_schema = 'sys' AND column_name = 'input_parameter_collation') +THEN + -- Add input_parameter_collation column in sys.babelfish_partition_function. + SET allow_system_table_mods = on; + ALTER TABLE sys.babelfish_partition_function ADD COLUMN input_parameter_collation NAME; + RESET allow_system_table_mods; + + -- Update the input_parameter_collation column in sys.babelfish_partition_function + -- catalog for collatable datatypes with default database collation. + UPDATE sys.babelfish_partition_function pf + SET input_parameter_collation = db.default_collation + FROM sys.babelfish_sysdatabases db + WHERE pf.dbid = db.dbid + AND pf.input_parameter_type IN ('CHAR', 'VARCHAR', 'NCHAR', 'NVARCHAR'); +END IF; +END $$; + -- After upgrade, always run analyze for all babelfish catalogs. CALL sys.analyze_babelfish_catalogs(); -- Reset search_path to not affect any subsequent scripts diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 03e48a85e71..d71547d8cc9 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -5314,7 +5314,7 @@ is_partition_function_used(int16 dbid, const char *partition_function_name) */ void add_entry_to_bbf_partition_function(int16 dbid, const char *partition_function_name, char *typname, - bool partition_option, ArrayType *values) + bool partition_option, ArrayType *values, char *collation) { Relation rel; TupleDesc dsc; @@ -5339,6 +5339,15 @@ add_entry_to_bbf_partition_function(int16 dbid, const char *partition_function_n new_record[Anum_bbf_partition_function_range_values - 1] = PointerGetDatum(values); new_record[6] = new_record[7] = TimestampGetDatum(GetSQLLocalTimestamp(3)); + if (collation) + { + NameData input_parameter_collation; + namestrcpy(&input_parameter_collation, collation); + new_record[Anum_bbf_partition_function_input_parameter_collation - 1] = NameGetDatum(&input_parameter_collation); + } + else + new_record_nulls[Anum_bbf_partition_function_input_parameter_collation - 1] = true; + tuple = heap_form_tuple(dsc, new_record, new_record_nulls); /* insert new record in the bbf_partition_function table */ diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 2dd49e7fd35..697f0d1a338 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -432,8 +432,9 @@ extern Oid get_bbf_extended_properties_idx_oid(void); #define Anum_bbf_partition_function_input_parameter_type 4 #define Anum_bbf_partition_function_partition_option 5 #define Anum_bbf_partition_function_range_values 6 +#define Anum_bbf_partition_function_input_parameter_collation 9 -#define BBF_PARTITION_FUNCTION_NUM_COLS 8 +#define BBF_PARTITION_FUNCTION_NUM_COLS 9 extern Oid bbf_partition_function_oid; extern Oid bbf_partition_function_pk_idx_oid; @@ -446,7 +447,7 @@ extern Oid get_bbf_partition_function_id_idx_oid(void); extern Oid get_bbf_partition_function_seq_oid(void); extern int32 get_available_partition_function_id(void); extern void add_entry_to_bbf_partition_function(int16 dbid, const char *partition_function_name, - char *typname, bool partition_option, ArrayType *values); + char *typname, bool partition_option, ArrayType *values, char *collation); extern void remove_entry_from_bbf_partition_function(int16 dbid, const char *partition_function_name); extern bool partition_function_exists(int16 dbid, const char *partition_function_name); extern int get_partition_count(int16 dbid, const char *partition_function_name); diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index 629df3ac6fc..876e5789a97 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -4298,6 +4298,9 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun int32 valtypmod; Datum tsql_type_datum; char *tsql_typename = NULL; + char *collation = NULL; + Oid collation_oid = InvalidOid; + bool type_is_collatable; Datum *input_values; Datum *sql_variant_values; ArrayType *arr_value = NULL; @@ -4337,6 +4340,20 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun errmsg("The identifier that starts with '%.128s' is too long. Maximum length is 128.", partition_function_name))); } + /* + * Get collation oid if collation is specified. + */ + if (stmt->collation) + { + collation_oid = tsql_get_oid_from_collidx(tsql_find_collation_internal(tsql_translate_tsql_collation_to_bbf_collation(stmt->collation))); + + /* raise an error if specified collation is invalid */ + if (!OidIsValid(collation_oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Invalid collation '%s'.", stmt->collation))); + } + /* check if there is existing partition function with the given name in the current database */ if (partition_function_exists(dbid, partition_function_name)) { @@ -4405,6 +4422,28 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("The type '%s' is not yet supported for partition function in Babelfish.", tsql_typename))); + type_is_collatable = OidIsValid(typ->collation); + + /* + * Raise an error if collate clause is specified and datatype is not collatable. + */ + if (stmt->collation && !type_is_collatable) + { + + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Expression type '%s' is invalid for COLLATE clause.", tsql_typename))); + } + /* + * Use default database collation if collate clause is not specified and datatype is collatable. + */ + else if (stmt->collation == NULL && type_is_collatable) + collation_oid = tsql_get_database_or_server_collation_oid_internal(false); + + /* get collation name from collation oid when type is collatable */ + if (type_is_collatable) + collation = get_collation_name(collation_oid); + /* check if the given number of boundaries are exceeding allowed limit */ nargs = list_length(arg); if (nargs >= MAX_PARTITIONS_LIMIT) @@ -4464,7 +4503,7 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun /* set the function oid of operator in tsql comparator context */ cxt.function_oid = cmpfunction_oid; - cxt.colloid = tsql_get_database_or_server_collation_oid_internal(false); + cxt.colloid = collation_oid; cxt.contains_duplicate = false; /* @@ -4498,12 +4537,14 @@ exec_stmt_partition_function(PLtsql_execstate *estate, PLtsql_stmt_partition_fun -1, false, 'i'); /* add entry in the sys.babelfish_partition_function catalog */ - add_entry_to_bbf_partition_function(dbid, partition_function_name, tsql_typename, stmt->is_right, arr_value); + add_entry_to_bbf_partition_function(dbid, partition_function_name, tsql_typename, stmt->is_right, arr_value, collation); pfree(tsql_typename); pfree(input_values); pfree(sql_variant_values); pfree(arr_value); + if (collation) + pfree(collation); /* cleanup estate */ exec_eval_cleanup(estate); diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index d781c37dea1..57e53d7a70c 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1110,6 +1110,7 @@ typedef struct PLtsql_stmt_partition_function bool is_right; PLtsql_type *datatype; List *args; /* the arguments (list of exprs) */ + char *collation; } PLtsql_stmt_partition_function; /* diff --git a/contrib/babelfishpg_tsql/src/pltsql_partition.c b/contrib/babelfishpg_tsql/src/pltsql_partition.c index db5cd4d208e..d9421027731 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_partition.c +++ b/contrib/babelfishpg_tsql/src/pltsql_partition.c @@ -65,15 +65,18 @@ bbf_create_partition_tables(CreateStmt *stmt) SysScanDesc scan; ScanKeyData scanKey[2]; char *input_parameter_type; + char *input_parameter_collation; char *partition_function_name; Datum *range_values; Datum *datum_values; bool *nulls; + bool type_is_collatable = InvalidOid; int nelems; Oid sql_variant_type_oid; Oid input_type_oid; ListCell *elements; Oid partition_column_typoid = InvalidOid; + Oid partition_column_colloid = InvalidOid; Oid partition_column_basetypoid = InvalidOid; char *partition_column_typname = NULL; bool is_binary_datatype = false; @@ -130,6 +133,11 @@ bbf_create_partition_tables(CreateStmt *stmt) partition_column_typoid = pg_type->oid; partition_column_basetypoid = pg_type->typbasetype; partition_column_typname = pstrdup(NameStr(pg_type->typname)); + type_is_collatable = OidIsValid(pg_type->typcollation); + if (coldef->collClause) + partition_column_colloid = get_collation_oid(coldef->collClause->collname, false); + else + partition_column_colloid = tsql_get_database_or_server_collation_oid_internal(false);; ReleaseSysCache(ctype); break; } @@ -170,9 +178,10 @@ bbf_create_partition_tables(CreateStmt *stmt) } input_parameter_type = TextDatumGetCString(heap_getattr(tuple, Anum_bbf_partition_function_input_parameter_type, RelationGetDescr(rel), &isnull)); + input_parameter_collation = NameStr(*DatumGetName(heap_getattr(tuple, Anum_bbf_partition_function_input_parameter_collation, RelationGetDescr(rel), &isnull))); values = DatumGetArrayTypeP(heap_getattr(tuple, Anum_bbf_partition_function_range_values, RelationGetDescr(rel), &isnull)); deconstruct_array(values, sql_variant_type_oid, -1, false, 'i', &datum_values, &nulls, &nelems); - + /* * If the partition columns type is UDT type, then we need * to use the base type of that type while comparing with @@ -210,6 +219,16 @@ bbf_create_partition_tables(CreateStmt *stmt) if ((*common_utility_plugin_ptr->is_tsql_binary_datatype) (input_type_oid) || (*common_utility_plugin_ptr->is_tsql_varbinary_datatype) (input_type_oid)) is_binary_datatype = true; + + if (type_is_collatable) + { + Assert(input_parameter_collation != NULL); + if (partition_column_colloid != tsql_get_oid_from_collidx(tsql_find_collation_internal(input_parameter_collation))) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Collation of partition column '%s' does not match collation of corresponding parameter in partition function '%s'.", + partition_colname, partition_function_name))); + } /* Convert each sql_variant values to CString. */ range_values = palloc(nelems * sizeof(Datum)); diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index 69b55ea7021..3c8ba026eae 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -7845,14 +7845,18 @@ makeCreatePartitionFunction(TSqlParser::Create_partition_functionContext *ctx) std::string typeStr = ::getFullText(ctx->data_type()); PLtsql_type *type = parse_datatype(typeStr.c_str(), 0); + if (ctx->collation()) + stmt->collation = pstrdup(getFullText(ctx->collation()->id()).c_str()); + else + stmt->collation = NULL; stmt->function_name = pstrdup(stripQuoteFromId(ctx->id()).c_str()); stmt->datatype = type; stmt->lineno = getLineNo(ctx); stmt->cmd_type = PLTSQL_STMT_PARTITION_FUNCTION; stmt->is_create = true; /* TODO: Support LEFT boundary option with partition function */ - stmt->is_right = true; - + stmt->is_right = true; + List *arg_list = NIL; if (ctx->expression_list()) { diff --git a/test/JDBC/expected/PARTITION-collations.out b/test/JDBC/expected/PARTITION-collations.out new file mode 100644 index 00000000000..ee73616fd1c --- /dev/null +++ b/test/JDBC/expected/PARTITION-collations.out @@ -0,0 +1,743 @@ + +-------------------------------------------------- +--- CREATE PARTITION FUNCTION with Collate clause +-------------------------------------------------- +-------------------------------------------------------------------- +--- Case 1. Usage of invalid collation with collatable datatype +-------------------------------------------------------------------- +-- Try to create a partition function with an invalid collation for a collatable datatype (NVARCHAR) +-- Expected result: Throws an error indicating that collation is invalid +CREATE PARTITION FUNCTION PF_InvalidCollation (NVARCHAR(10) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +------------------------------------------------------------------------------------------ +--- Case 2. Usage of invalid collation with unsupported datatype for partition function +------------------------------------------------------------------------------------------ +-- Try to create a partition function with an invalid collation with unsupported datatype +-- Expected result: Throws an error indicating that collation is invalid +CREATE PARTITION FUNCTION VarcharMaxPartitionFunction (VARCHAR(MAX) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES ('A', 'B', 'C', 'D'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +CREATE PARTITION FUNCTION NVarcharMaxPartitionFunction (NVARCHAR(MAX) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (N'A', N'B', N'C', N'D'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +CREATE PARTITION FUNCTION VarbinaryMaxPartitionFunction (VARBINARY(MAX) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +CREATE PARTITION FUNCTION TextPartitionFunction (text COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES ('a', 'b', 'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +CREATE PARTITION FUNCTION NTextPartitionFunction (ntext COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +CREATE PARTITION FUNCTION ImagePartitionFunction (image COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (0x123456, 0x789ABC, 0xDEF012); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +CREATE PARTITION FUNCTION XmlPartitionFunction (xml COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES ('1', '2', '3'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + +------------------------------------------------------------------------------------------ +--- Case 3. Usage of valid collation with unsupported datatype for partition function +------------------------------------------------------------------------------------------ +-- Try to create a partition function with an valid collation with unsupported datatype +-- Expected result: Throws an error indicating that datatype is not supported +CREATE PARTITION FUNCTION VarcharMaxPartitionFunction (VARCHAR(MAX) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('A', 'B', 'C', 'D'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'varchar(max)' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION NVarcharMaxPartitionFunction (NVARCHAR(MAX) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (N'A', N'B', N'C', N'D'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'nvarchar(max)' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION VarbinaryMaxPartitionFunction (VARBINARY(MAX) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'varbinary(max)' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION TextPartitionFunction (text COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('a', 'b', 'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'text' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION NTextPartitionFunction (ntext COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'ntext' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION ImagePartitionFunction (image COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (0x123456, 0x789ABC, 0xDEF012); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'image' is not valid for this operation.)~~ + + +CREATE PARTITION FUNCTION XmlPartitionFunction (xml COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('1', '2', '3'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The type 'xml' is not valid for this operation.)~~ + + +-------------------------------------------------------------------- +--- Case 5. Usage of invalid collation with non-collatable datatype +-------------------------------------------------------------------- +-- Try to create a partition function with an invalid collation for a non-collatable datatype +-- Expected result: Throws an error indicating the collation is invalid +CREATE PARTITION FUNCTION PF_InvalidCollationNonCollatable (INT COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid collation 'invalid_collation'.)~~ + + + +-------------------------------------------------------------------- +--- Case 6. Usage of valid collation with non-collatable datatype +-------------------------------------------------------------------- +-- Try to create a partition function with a valid collation for a non-collatable datatype +-- Expected result: Throws an error indicating that datatype cannot have a collation +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableBIGINT (BIGINT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'bigint' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableTINYINT (TINYINT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'tinyint' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableSMALLINT (SMALLINT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'smallint' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableBIT (BIT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (0, 1); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'bit' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableREAL (REAL COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.0, 10.0, 100.0); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'real' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableFLOAT (FLOAT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.0, 10.0, 100.0); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'float' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDECIMAL (DECIMAL(10,2) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'decimal' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableNUMERIC (NUMERIC(10,2) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'numeric' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableMONEY (MONEY COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'money' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableSMALLMONEY (SMALLMONEY COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'smallmoney' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDATEDATE (DATE COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01', '2023-02-01', '2023-03-01'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'date' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatateTIME (TIME COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('00:00:00', '12:00:00', '23:59:59'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'time' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDATETIME (DATETIME COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01 00:00:00', '2023-02-01 12:00:00', '2023-03-01 23:59:59'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'datetime' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDATETIME2 (DATETIME2 COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01 00:00:00.000', '2023-02-01 12:00:00.000', '2023-03-01 23:59:59.999'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'datetime2' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableSMALLDATETIME (SMALLDATETIME COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01 00:00:00', '2023-02-01 12:00:00', '2023-03-01 23:59:59'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'smalldatetime' is invalid for COLLATE clause.)~~ + + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatatableUNIQUEIDENTIFIER (UNIQUEIDENTIFIER COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('11111111-1111-1111-1111-111111111111', '22222222-2222-2222-2222-222222222222', '33333333-3333-3333-3333-333333333333'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Expression type 'uniqueidentifier' is invalid for COLLATE clause.)~~ + + +-------------------------------------------------------------------- +--- Case 7. Partition function with duplicate values under CI_AI collation +-------------------------------------------------------------------- +-- Try to create a partition function with values that are considered duplicates +-- under case-insensitive, accent-insensitive collation +-- Expected result: Should fail with error about duplicate values +CREATE PARTITION FUNCTION PF_DuplicateValues (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'E', N'é', N'e'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +-- Test variation with different characters that would be considered duplicates +CREATE PARTITION FUNCTION PF_DuplicateValues2 (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'a', N'A', N'á', N'Á'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +-- Test with mix of normal and special characters +CREATE PARTITION FUNCTION PF_DuplicateValues3 (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'o', N'ö', N'O', N'Ö'); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Duplicate values are not allowed in partition function boundary values list.)~~ + + +---------------------------------------------------------------------------------------- +-- Case 8: Verify $PARTITION uses correct collation to find the partition number +---------------------------------------------------------------------------------------- +CREATE PARTITION FUNCTION PF_CaseSensitiveAccentSensitive (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'A', N'á', N'c', N'd'); +GO + +-- select query to verify collation-sensitive partition mapping +SELECT + input_value COLLATE Latin1_General_CS_AS, -- used collate with order by verify the ouptut of partition number + $PARTITION.PF_CaseSensitiveAccentSensitive(input_value) as partition_number +FROM ( + VALUES + ('A'), -- Tests case sensitivity + ('a'), -- Tests case sensitivity + (N'á'), -- Tests accent sensitivity + ('b'), -- Tests value between partition boundaries + ('c'), -- Tests exact boundary match + ('C'), -- Tests case sensitivity at boundary + ('d'), -- Tests last boundary + ('e') -- Tests beyond last boundary +) AS test_cases(input_value) +order by input_value; +GO +~~START~~ +nvarchar#!#int +a#!#1 +A#!#2 +á#!#3 +b#!#3 +c#!#4 +C#!#4 +d#!#5 +e#!#5 +~~END~~ + + + +DROP PARTITION FUNCTION PF_CaseSensitiveAccentSensitive; +GO + +-------------------------------------------------------------------- +-- Case 9: Cross database $PARTITION collation verification +-------------------------------------------------------------------- +-- Create a test database with CI_AS collation +CREATE DATABASE PartitionCollateTestDB +COLLATE Latin1_General_CI_AS; +GO + +USE PartitionCollateTestDB; +GO + +-- Part 1: Partition function with explicit collation (CS_AS) +CREATE PARTITION FUNCTION PF_ExplicitCollate (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'A', N'á', N'c', N'd'); +GO + +-- Part 2: Partition function without collation (uses database default CI_AS) +CREATE PARTITION FUNCTION PF_ImplicitCollate (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'A', N'á', N'c', N'd'); +GO + +-- Switch to different database to test cross-database access +USE master; +GO + +-- Test cross-database $PARTITION with explicit collation (CS_AS) +SELECT + input_value COLLATE Latin1_General_CS_AS, -- used collate with order by verify the ouptut of partition number + PartitionCollateTestDB.$PARTITION.PF_ExplicitCollate(input_value) as partition_number +FROM ( + VALUES + ('A'), -- Tests case sensitivity + ('a'), -- Should map different from 'A' + (N'á'), -- Tests accent sensitivity + ('b'), -- Tests value between boundaries + ('c'), -- Tests boundary value + ('C'), -- Should map different from 'c' + ('d'), -- Tests last boundary + ('e') -- Tests beyond last boundary +) AS test_cases(input_value) +ORDER BY + input_value; +GO +~~START~~ +nvarchar#!#int +a#!#1 +A#!#2 +á#!#3 +b#!#3 +c#!#4 +C#!#4 +d#!#5 +e#!#5 +~~END~~ + + +-- Test cross-database $PARTITION with implicit collation (database default CI_AS) +SELECT + input_value COLLATE Latin1_General_CI_AS, -- used collate with order by verify the ouptut of partition number + PartitionCollateTestDB.$PARTITION.PF_ImplicitCollate(input_value) as partition_number +FROM ( + VALUES + ('A'), -- Tests case insensitivity + ('a'), -- Should map same as 'A' + (N'á'), -- Tests accent sensitivity + ('b'), -- Tests value between boundaries + ('c'), -- Tests boundary value + ('C'), -- Should map same as 'c' + ('d'), -- Tests last boundary + ('e') -- Tests beyond last boundary +) AS test_cases(input_value) +ORDER BY + input_value; +GO +~~START~~ +nvarchar#!#int +A#!#2 +a#!#2 +á#!#3 +b#!#3 +c#!#4 +C#!#4 +d#!#5 +e#!#5 +~~END~~ + + +-- Cleanup +USE master; +GO + +DROP DATABASE PartitionCollateTestDB; +GO + + + +-------------------------------------------------- +--- CREATE PARTITIONED TABLE with Collate clause +-------------------------------------------------- +-- Create a database with a specific collation +CREATE DATABASE CaseInsensitiveAccentSensitive +COLLATE Latin1_General_CI_AS; +GO + +USE CaseInsensitiveAccentSensitive; +GO + +------------------------------------------------------------------------------------------- +--- Case 1. Partition function and partition key with explicit collation with collation match. +------------------------------------------------------------------------------------------- +-- Create a partition function with a specific collation +CREATE PARTITION FUNCTION PF_AccentSensitive (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_AccentSensitive +AS PARTITION PF_AccentSensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a different collation +-- Expected result: Table creation should fail with an error indicating the collation mismatch +CREATE TABLE PartitionedTable1 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, -- collation doesn't match partition function + Value NVARCHAR(100) +) ON PS_AccentSensitive(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_AccentSensitive'.)~~ + + + +DROP PARTITION SCHEME PS_AccentSensitive; +GO + +DROP PARTITION FUNCTION PF_AccentSensitive; +GO +-------------------------------------------------------------------------- +--- Case 2. Partition function with explicit collation different than +--- database default doesn't match partition key default collation. +-------------------------------------------------------------------------- +-- Create a partition function with a collation different than the database default +CREATE PARTITION FUNCTION PF_AccentSensitive (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_AccentSensitive +AS PARTITION PF_AccentSensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using the database default collation +-- Expected result: Table creation should fail with an error indicating the collation mismatch +CREATE TABLE PartitionedTable2 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10), -- using database default collation + Value NVARCHAR(100) +) ON PS_AccentSensitive(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_AccentSensitive'.)~~ + + +DROP PARTITION SCHEME PS_AccentSensitive; +GO + +DROP PARTITION FUNCTION PF_AccentSensitive; +GO + +----------------------------------------------------------------------------------------- +--- Case 3. Partition function with default collation doesn't match explicit collation of partition key +-------------------------------------------------------------------- +-- Create a partition function without specifying a collation +CREATE PARTITION FUNCTION PF_CaseInsensitive (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_CaseInsensitive +AS PARTITION PF_CaseInsensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a specific collation +-- Expected result: Table creation should fail with an error indicating the collation mismatch +CREATE TABLE PartitionedTable3 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CS_AS, -- collation doesn't match default partition function collation + Value NVARCHAR(100) +) ON PS_CaseInsensitive(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CaseInsensitive'.)~~ + + +DROP PARTITION SCHEME PS_CaseInsensitive; +GO + +DROP PARTITION FUNCTION PF_CaseInsensitive; +GO + +--------------------------------------------------------------------------------- +--- Case 4. Both partition function and table are with default database collation +--------------------------------------------------------------------------------- +-- Create a partition function without specifying a collation +CREATE PARTITION FUNCTION PF_DefaultCollation (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using the database default collation +-- Expected result: Table creation should succeed, with the partition key column using the database default collation +CREATE TABLE PartitionedTable4 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10), -- using database default collation + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO + +-- check partition key column collation +SELECT name, collation_name FROM sys.all_columns where object_id = object_id('PartitionedTable4') order by name; +GO +~~START~~ +varchar#!#varchar +id#!# +partitionkey#!#bbf_unicode_cp1_ci_as +value#!#bbf_unicode_cp1_ci_as +~~END~~ + + +DROP TABLE PartitionedTable4; +GO + +DROP PARTITION SCHEME PS_DefaultCollation; +GO + +DROP PARTITION FUNCTION PF_DefaultCollation; +Go + +-------------------------------------------------------------------- +--- Case 5. Partition function and table with explicit collation matches +-------------------------------------------------------------------- +-- Create a partition function with a specific collation +CREATE PARTITION FUNCTION PF_AccentInsensitive (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_AccentInsensitive +AS PARTITION PF_AccentInsensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using the same collation as the partition function +-- Expected result: Table creation should succeed +CREATE TABLE PartitionedTable5 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_AccentInsensitive(PartitionKey); +GO + +-- check partition key column collation +SELECT name, collation_name FROM sys.all_columns where object_id = object_id('PartitionedTable5') order by name; +GO +~~START~~ +varchar#!#varchar +id#!# +partitionkey#!#bbf_unicode_cp1_ci_ai +value#!#bbf_unicode_cp1_ci_as +~~END~~ + + +DROP TABLE PartitionedTable5; +GO + +DROP PARTITION SCHEME PS_AccentInsensitive; +GO + +DROP PARTITION FUNCTION PF_AccentInsensitive; +GO + +-------------------------------------------------------------------- +--- Case 6: Usage of invalid collation with non-collatable partition key column +-------------------------------------------------------------------- +-- Create a partition function without specifying a collation +CREATE PARTITION FUNCTION PF_DefaultCollation (INT) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Try to create a partitioned table with a partition key column using an invalid collation +-- Expected result: Throws an error indicating the collation is invalid +CREATE TABLE PartitionedTable6 ( + ID INT IDENTITY(1,1), + PartitionKey INT COLLATE invalid_collation, -- using invalid collation + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: collation "invalid_collation" for encoding "UTF8" does not exist)~~ + + +DROP PARTITION SCHEME PS_DefaultCollation +DROP PARTITION FUNCTION PF_DefaultCollation +GO + +-------------------------------------------------------------------- +--- Case 7: Usage of valid collation with non-collatable partition key column +-------------------------------------------------------------------- +-- Create a partition function with non-collatable datatype +CREATE PARTITION FUNCTION PF_DefaultCollation (INT) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a valid collation +-- Expected result: Throws an error indicating the datatype is not collatable +CREATE TABLE PartitionedTable7 ( + ID INT IDENTITY(1,1), + PartitionKey INT COLLATE Latin1_GENERAL_CI_AS, -- using valid collation with non-collatable datatype + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: collations are not supported by type integer)~~ + + +DROP PARTITION SCHEME PS_DefaultCollation +DROP PARTITION FUNCTION PF_DefaultCollation +GO + + +----------------------------------------------------------------------------------------------- +--- Case 8: Usage of collatable partition key column with non-collatable partition function datatype +------------------------------------------------------------------------------------------------ +-- Create a partition function with non-collatable datatype +CREATE PARTITION FUNCTION PF_DefaultCollation (INT) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a valid collation +-- Expected result: Throws an error indicating the datatype is different +CREATE TABLE PartitionedTable7 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_GENERAL_CI_AS, -- using valid collation with collatable datatype + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Partition column 'partitionkey' has data type 'nvarchar' which is different from the partition function 'PF_DefaultCollation' parameter data type 'int'.)~~ + + +DROP PARTITION SCHEME PS_DefaultCollation +DROP PARTITION FUNCTION PF_DefaultCollation +GO + +USE master +Go + +DROP DATABASE CaseInsensitiveAccentSensitive +GO diff --git a/test/JDBC/expected/PARTITION-vu-prepare.out b/test/JDBC/expected/PARTITION-vu-prepare.out index 451e292f1a9..73774caf113 100644 --- a/test/JDBC/expected/PARTITION-vu-prepare.out +++ b/test/JDBC/expected/PARTITION-vu-prepare.out @@ -575,10 +575,12 @@ SET QUOTED_IDENTIFIER OFF; Go --------------------------------------------------- ---- TO test Permission --------------------------------------------------- -CREATE DATABASE PartitionDb; +-------------------------------------------------------------------------- +--- Test database to test Permission and Collation of Partition Functions +-------------------------------------------------------------------------- +-- Create a test database with a specific collation +CREATE DATABASE PartitionDb +COLLATE Latin1_General_CI_AI;; GO USE PartitionDb; @@ -1341,3 +1343,44 @@ CREATE VIEW SysSearchPartitionNULLDepView AS SELECT sys.search_partition('IntPartitionFunction', 10, NULL) GO + + +-------------------------------------------------- +--- To test Collation of Partition Functions +-------------------------------------------------- +USE PartitionDb; +GO + +-- Create partition functions without explicit collation (will use database default) +CREATE PARTITION FUNCTION PF_CollationTest_Char (CHAR(10)) +AS RANGE RIGHT FOR VALUES ('A', 'M', 'Z'); +GO + +CREATE PARTITION FUNCTION PF_CollationTest_VarChar (VARCHAR(10)) +AS RANGE RIGHT FOR VALUES ('Apple', 'Mango', 'Zebra'); +GO + +CREATE PARTITION FUNCTION PF_CollationTest_NChar (NCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'A', N'M', N'Z'); +GO + +CREATE PARTITION FUNCTION PF_CollationTest_NVarChar (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'Apple', N'Mango', N'Zebra'); +GO + +-- Create corresponding partition schemes +CREATE PARTITION SCHEME PS_CollationTest_Char +AS PARTITION PF_CollationTest_Char ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME PS_CollationTest_VarChar +AS PARTITION PF_CollationTest_VarChar ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME PS_CollationTest_NChar +AS PARTITION PF_CollationTest_NChar ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME PS_CollationTest_NVarChar +AS PARTITION PF_CollationTest_NVarChar ALL TO ([PRIMARY]); +GO diff --git a/test/JDBC/expected/PARTITION-vu-verify.out b/test/JDBC/expected/PARTITION-vu-verify.out index f815f61bd6e..5405bc05ba9 100644 --- a/test/JDBC/expected/PARTITION-vu-verify.out +++ b/test/JDBC/expected/PARTITION-vu-verify.out @@ -1230,6 +1230,10 @@ go ~~START~~ nvarchar#!#char#!#nvarchar#!#int#!#bit#!#bit PartitionDb_PartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_Char#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_VarChar#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_NChar#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_NVarChar#!#R #!#RANGE#!#4#!#1#!#0 ~~END~~ @@ -1243,6 +1247,10 @@ go ~~START~~ nvarchar#!#nvarchar#!#char#!#nvarchar#!#bit#!#bit PartitionDb_PartitionScheme#!#PartitionDb_PartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_Char#!#PF_CollationTest_Char#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_VarChar#!#PF_CollationTest_VarChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_NChar#!#PF_CollationTest_NChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_NVarChar#!#PF_CollationTest_NVarChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 ~~END~~ @@ -3380,7 +3388,7 @@ GO int ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Invalid database name 'NonExistentDatabase'.)~~ +~~ERROR (Message: Invalid database name 'nonexistentdatabase'.)~~ -- error during implicit Conversion of values to partition function parameter type @@ -3804,3 +3812,83 @@ GO DROP USER partition_u2 GO + +--------------------------------------------------------------- +--- Test Collation of Partition Functions after upgrade +--------------------------------------------------------------- +USE PartitionDb +Go + +-- Test 1: Create tables with the compatible collation i.e. database default (should work) +CREATE TABLE PT_SameCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go + +-- Test 2: Create tables with incompatible collation i.e. other than database default (should fail) +CREATE TABLE PT_DifferentCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_Char'.)~~ + + +CREATE TABLE PT_DifferentCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_VarChar'.)~~ + + +CREATE TABLE PT_DifferentCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_NChar'.)~~ + + +CREATE TABLE PT_DifferentCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_NVarChar'.)~~ + diff --git a/test/JDBC/expected/db_collation/PARTITION-vu-verify.out b/test/JDBC/expected/db_collation/PARTITION-vu-verify.out index a874ea01c8a..399b81d5662 100644 --- a/test/JDBC/expected/db_collation/PARTITION-vu-verify.out +++ b/test/JDBC/expected/db_collation/PARTITION-vu-verify.out @@ -1230,6 +1230,10 @@ go ~~START~~ nvarchar#!#char#!#nvarchar#!#int#!#bit#!#bit PartitionDb_PartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_Char#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_VarChar#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_NChar#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_NVarChar#!#R #!#RANGE#!#4#!#1#!#0 ~~END~~ @@ -1243,6 +1247,10 @@ go ~~START~~ nvarchar#!#nvarchar#!#char#!#nvarchar#!#bit#!#bit PartitionDb_PartitionScheme#!#PartitionDb_PartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_Char#!#PF_CollationTest_Char#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_VarChar#!#PF_CollationTest_VarChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_NChar#!#PF_CollationTest_NChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_NVarChar#!#PF_CollationTest_NVarChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 ~~END~~ @@ -3380,7 +3388,7 @@ GO int ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Invalid database name 'NonExistentDatabase'.)~~ +~~ERROR (Message: Invalid database name 'nonexistentdatabase'.)~~ -- error during implicit Conversion of values to partition function parameter type @@ -3804,3 +3812,83 @@ GO DROP USER partition_u2 GO + +--------------------------------------------------------------- +--- Test Collation of Partition Functions after upgrade +--------------------------------------------------------------- +USE PartitionDb +Go + +-- Test 1: Create tables with the compatible collation i.e. database default (should work) +CREATE TABLE PT_SameCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go + +-- Test 2: Create tables with incompatible collation i.e. other than database default (should fail) +CREATE TABLE PT_DifferentCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_Char'.)~~ + + +CREATE TABLE PT_DifferentCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_VarChar'.)~~ + + +CREATE TABLE PT_DifferentCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_NChar'.)~~ + + +CREATE TABLE PT_DifferentCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_NVarChar'.)~~ + diff --git a/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out b/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out index 27858ce98ad..422fe330186 100644 --- a/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out +++ b/test/JDBC/expected/parallel_query/PARTITION-vu-verify.out @@ -1230,6 +1230,10 @@ go ~~START~~ nvarchar#!#char#!#nvarchar#!#int#!#bit#!#bit PartitionDb_PartitionFunction#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_Char#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_VarChar#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_NChar#!#R #!#RANGE#!#4#!#1#!#0 +PF_CollationTest_NVarChar#!#R #!#RANGE#!#4#!#1#!#0 ~~END~~ @@ -1243,6 +1247,10 @@ go ~~START~~ nvarchar#!#nvarchar#!#char#!#nvarchar#!#bit#!#bit PartitionDb_PartitionScheme#!#PartitionDb_PartitionFunction#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_Char#!#PF_CollationTest_Char#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_VarChar#!#PF_CollationTest_VarChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_NChar#!#PF_CollationTest_NChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 +PS_CollationTest_NVarChar#!#PF_CollationTest_NVarChar#!#PS#!#PARTITION_SCHEME#!#0#!#0 ~~END~~ @@ -3489,7 +3497,7 @@ GO int ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Invalid database name 'NonExistentDatabase'.)~~ +~~ERROR (Message: Invalid database name 'nonexistentdatabase'.)~~ -- error during implicit Conversion of values to partition function parameter type @@ -3913,3 +3921,83 @@ GO DROP USER partition_u2 GO + +--------------------------------------------------------------- +--- Test Collation of Partition Functions after upgrade +--------------------------------------------------------------- +USE PartitionDb +Go + +-- Test 1: Create tables with the compatible collation i.e. database default (should work) +CREATE TABLE PT_SameCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go + +-- Test 2: Create tables with incompatible collation i.e. other than database default (should fail) +CREATE TABLE PT_DifferentCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_Char'.)~~ + + +CREATE TABLE PT_DifferentCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_VarChar'.)~~ + + +CREATE TABLE PT_DifferentCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_NChar'.)~~ + + +CREATE TABLE PT_DifferentCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Collation of partition column 'partitionkey' does not match collation of corresponding parameter in partition function 'PF_CollationTest_NVarChar'.)~~ + diff --git a/test/JDBC/input/PARTITION-collations.sql b/test/JDBC/input/PARTITION-collations.sql new file mode 100644 index 00000000000..3a67df85e36 --- /dev/null +++ b/test/JDBC/input/PARTITION-collations.sql @@ -0,0 +1,529 @@ +-------------------------------------------------- +--- CREATE PARTITION FUNCTION with Collate clause +-------------------------------------------------- + +-------------------------------------------------------------------- +--- Case 1. Usage of invalid collation with collatable datatype +-------------------------------------------------------------------- +-- Try to create a partition function with an invalid collation for a collatable datatype (NVARCHAR) +-- Expected result: Throws an error indicating that collation is invalid +CREATE PARTITION FUNCTION PF_InvalidCollation (NVARCHAR(10) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO + +------------------------------------------------------------------------------------------ +--- Case 2. Usage of invalid collation with unsupported datatype for partition function +------------------------------------------------------------------------------------------ +-- Try to create a partition function with an invalid collation with unsupported datatype +-- Expected result: Throws an error indicating that collation is invalid +CREATE PARTITION FUNCTION VarcharMaxPartitionFunction (VARCHAR(MAX) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES ('A', 'B', 'C', 'D'); +GO + +CREATE PARTITION FUNCTION NVarcharMaxPartitionFunction (NVARCHAR(MAX) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (N'A', N'B', N'C', N'D'); +GO + +CREATE PARTITION FUNCTION VarbinaryMaxPartitionFunction (VARBINARY(MAX) COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000); +GO + +CREATE PARTITION FUNCTION TextPartitionFunction (text COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES ('a', 'b', 'c'); +GO + +CREATE PARTITION FUNCTION NTextPartitionFunction (ntext COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO + +CREATE PARTITION FUNCTION ImagePartitionFunction (image COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (0x123456, 0x789ABC, 0xDEF012); +GO + +CREATE PARTITION FUNCTION XmlPartitionFunction (xml COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES ('1', '2', '3'); +GO + +------------------------------------------------------------------------------------------ +--- Case 3. Usage of valid collation with unsupported datatype for partition function +------------------------------------------------------------------------------------------ +-- Try to create a partition function with an valid collation with unsupported datatype +-- Expected result: Throws an error indicating that datatype is not supported +CREATE PARTITION FUNCTION VarcharMaxPartitionFunction (VARCHAR(MAX) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('A', 'B', 'C', 'D'); +GO + +CREATE PARTITION FUNCTION NVarcharMaxPartitionFunction (NVARCHAR(MAX) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (N'A', N'B', N'C', N'D'); +GO + +CREATE PARTITION FUNCTION VarbinaryMaxPartitionFunction (VARBINARY(MAX) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (0x000, 0x800, 0x400, 0xC000); +GO + +CREATE PARTITION FUNCTION TextPartitionFunction (text COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('a', 'b', 'c'); +GO + +CREATE PARTITION FUNCTION NTextPartitionFunction (ntext COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c'); +GO + +CREATE PARTITION FUNCTION ImagePartitionFunction (image COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (0x123456, 0x789ABC, 0xDEF012); +GO + +CREATE PARTITION FUNCTION XmlPartitionFunction (xml COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('1', '2', '3'); +GO + +-------------------------------------------------------------------- +--- Case 5. Usage of invalid collation with non-collatable datatype +-------------------------------------------------------------------- +-- Try to create a partition function with an invalid collation for a non-collatable datatype +-- Expected result: Throws an error indicating the collation is invalid +CREATE PARTITION FUNCTION PF_InvalidCollationNonCollatable (INT COLLATE invalid_collation) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +Go + +-------------------------------------------------------------------- +--- Case 6. Usage of valid collation with non-collatable datatype +-------------------------------------------------------------------- +-- Try to create a partition function with a valid collation for a non-collatable datatype +-- Expected result: Throws an error indicating that datatype cannot have a collation + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableBIGINT (BIGINT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableTINYINT (TINYINT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableSMALLINT (SMALLINT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableBIT (BIT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (0, 1); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableREAL (REAL COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.0, 10.0, 100.0); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableFLOAT (FLOAT COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.0, 10.0, 100.0); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDECIMAL (DECIMAL(10,2) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableNUMERIC (NUMERIC(10,2) COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableMONEY (MONEY COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableSMALLMONEY (SMALLMONEY COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES (1.00, 10.00, 100.00); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDATEDATE (DATE COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01', '2023-02-01', '2023-03-01'); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatateTIME (TIME COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('00:00:00', '12:00:00', '23:59:59'); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDATETIME (DATETIME COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01 00:00:00', '2023-02-01 12:00:00', '2023-03-01 23:59:59'); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableDATETIME2 (DATETIME2 COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01 00:00:00.000', '2023-02-01 12:00:00.000', '2023-03-01 23:59:59.999'); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatableSMALLDATETIME (SMALLDATETIME COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('2023-01-01 00:00:00', '2023-02-01 12:00:00', '2023-03-01 23:59:59'); +GO + +CREATE PARTITION FUNCTION PF_ValidCollationNonCollatatableUNIQUEIDENTIFIER (UNIQUEIDENTIFIER COLLATE Latin1_General_CI_AS) +AS RANGE RIGHT FOR VALUES ('11111111-1111-1111-1111-111111111111', '22222222-2222-2222-2222-222222222222', '33333333-3333-3333-3333-333333333333'); +GO + +-------------------------------------------------------------------- +--- Case 7. Partition function with duplicate values under CI_AI collation +-------------------------------------------------------------------- +-- Try to create a partition function with values that are considered duplicates +-- under case-insensitive, accent-insensitive collation +-- Expected result: Should fail with error about duplicate values +CREATE PARTITION FUNCTION PF_DuplicateValues (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'E', N'é', N'e'); +GO + +-- Test variation with different characters that would be considered duplicates +CREATE PARTITION FUNCTION PF_DuplicateValues2 (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'a', N'A', N'á', N'Á'); +GO + +-- Test with mix of normal and special characters +CREATE PARTITION FUNCTION PF_DuplicateValues3 (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'o', N'ö', N'O', N'Ö'); +GO + +---------------------------------------------------------------------------------------- +-- Case 8: Verify $PARTITION uses correct collation to find the partition number +---------------------------------------------------------------------------------------- +CREATE PARTITION FUNCTION PF_CaseSensitiveAccentSensitive (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'A', N'á', N'c', N'd'); +GO + +-- select query to verify collation-sensitive partition mapping +SELECT + input_value COLLATE Latin1_General_CS_AS, -- used collate with order by verify the ouptut of partition number + $PARTITION.PF_CaseSensitiveAccentSensitive(input_value) as partition_number +FROM ( + VALUES + ('A'), -- Tests case sensitivity + ('a'), -- Tests case sensitivity + (N'á'), -- Tests accent sensitivity + ('b'), -- Tests value between partition boundaries + ('c'), -- Tests exact boundary match + ('C'), -- Tests case sensitivity at boundary + ('d'), -- Tests last boundary + ('e') -- Tests beyond last boundary +) AS test_cases(input_value) +order by input_value; +GO + + +DROP PARTITION FUNCTION PF_CaseSensitiveAccentSensitive; +GO + +-------------------------------------------------------------------- +-- Case 9: Cross database $PARTITION collation verification +-------------------------------------------------------------------- +-- Create a test database with CI_AS collation +CREATE DATABASE PartitionCollateTestDB +COLLATE Latin1_General_CI_AS; +GO + +USE PartitionCollateTestDB; +GO + +-- Part 1: Partition function with explicit collation (CS_AS) +CREATE PARTITION FUNCTION PF_ExplicitCollate (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'A', N'á', N'c', N'd'); +GO + +-- Part 2: Partition function without collation (uses database default CI_AS) +CREATE PARTITION FUNCTION PF_ImplicitCollate (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'A', N'á', N'c', N'd'); +GO + +-- Switch to different database to test cross-database access +USE master; +GO + +-- Test cross-database $PARTITION with explicit collation (CS_AS) +SELECT + input_value COLLATE Latin1_General_CS_AS, -- used collate with order by verify the ouptut of partition number + PartitionCollateTestDB.$PARTITION.PF_ExplicitCollate(input_value) as partition_number +FROM ( + VALUES + ('A'), -- Tests case sensitivity + ('a'), -- Should map different from 'A' + (N'á'), -- Tests accent sensitivity + ('b'), -- Tests value between boundaries + ('c'), -- Tests boundary value + ('C'), -- Should map different from 'c' + ('d'), -- Tests last boundary + ('e') -- Tests beyond last boundary +) AS test_cases(input_value) +ORDER BY + input_value; +GO + +-- Test cross-database $PARTITION with implicit collation (database default CI_AS) +SELECT + input_value COLLATE Latin1_General_CI_AS, -- used collate with order by verify the ouptut of partition number + PartitionCollateTestDB.$PARTITION.PF_ImplicitCollate(input_value) as partition_number +FROM ( + VALUES + ('A'), -- Tests case insensitivity + ('a'), -- Should map same as 'A' + (N'á'), -- Tests accent sensitivity + ('b'), -- Tests value between boundaries + ('c'), -- Tests boundary value + ('C'), -- Should map same as 'c' + ('d'), -- Tests last boundary + ('e') -- Tests beyond last boundary +) AS test_cases(input_value) +ORDER BY + input_value; +GO + +-- Cleanup +USE master; +GO + +DROP DATABASE PartitionCollateTestDB; +GO + + + +-------------------------------------------------- +--- CREATE PARTITIONED TABLE with Collate clause +-------------------------------------------------- +-- Create a database with a specific collation +CREATE DATABASE CaseInsensitiveAccentSensitive +COLLATE Latin1_General_CI_AS; +GO + +USE CaseInsensitiveAccentSensitive; +GO + +------------------------------------------------------------------------------------------- +--- Case 1. Partition function and partition key with explicit collation with collation match. +------------------------------------------------------------------------------------------- +-- Create a partition function with a specific collation +CREATE PARTITION FUNCTION PF_AccentSensitive (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_AccentSensitive +AS PARTITION PF_AccentSensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a different collation +-- Expected result: Table creation should fail with an error indicating the collation mismatch +CREATE TABLE PartitionedTable1 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, -- collation doesn't match partition function + Value NVARCHAR(100) +) ON PS_AccentSensitive(PartitionKey); +GO + + +DROP PARTITION SCHEME PS_AccentSensitive; +GO + +DROP PARTITION FUNCTION PF_AccentSensitive; +GO +-------------------------------------------------------------------------- +--- Case 2. Partition function with explicit collation different than +--- database default doesn't match partition key default collation. +-------------------------------------------------------------------------- +-- Create a partition function with a collation different than the database default +CREATE PARTITION FUNCTION PF_AccentSensitive (NVARCHAR(10) COLLATE Latin1_General_CS_AS) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_AccentSensitive +AS PARTITION PF_AccentSensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using the database default collation +-- Expected result: Table creation should fail with an error indicating the collation mismatch +CREATE TABLE PartitionedTable2 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10), -- using database default collation + Value NVARCHAR(100) +) ON PS_AccentSensitive(PartitionKey); +GO + +DROP PARTITION SCHEME PS_AccentSensitive; +GO + +DROP PARTITION FUNCTION PF_AccentSensitive; +GO + +----------------------------------------------------------------------------------------- +--- Case 3. Partition function with default collation doesn't match explicit collation of partition key +-------------------------------------------------------------------- +-- Create a partition function without specifying a collation +CREATE PARTITION FUNCTION PF_CaseInsensitive (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_CaseInsensitive +AS PARTITION PF_CaseInsensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a specific collation +-- Expected result: Table creation should fail with an error indicating the collation mismatch +CREATE TABLE PartitionedTable3 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CS_AS, -- collation doesn't match default partition function collation + Value NVARCHAR(100) +) ON PS_CaseInsensitive(PartitionKey); +GO + +DROP PARTITION SCHEME PS_CaseInsensitive; +GO + +DROP PARTITION FUNCTION PF_CaseInsensitive; +GO + +--------------------------------------------------------------------------------- +--- Case 4. Both partition function and table are with default database collation +--------------------------------------------------------------------------------- +-- Create a partition function without specifying a collation +CREATE PARTITION FUNCTION PF_DefaultCollation (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using the database default collation +-- Expected result: Table creation should succeed, with the partition key column using the database default collation +CREATE TABLE PartitionedTable4 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10), -- using database default collation + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO + +-- check partition key column collation +SELECT name, collation_name FROM sys.all_columns where object_id = object_id('PartitionedTable4') order by name; +GO + +DROP TABLE PartitionedTable4; +GO + +DROP PARTITION SCHEME PS_DefaultCollation; +GO + +DROP PARTITION FUNCTION PF_DefaultCollation; +Go + +-------------------------------------------------------------------- +--- Case 5. Partition function and table with explicit collation matches +-------------------------------------------------------------------- +-- Create a partition function with a specific collation +CREATE PARTITION FUNCTION PF_AccentInsensitive (NVARCHAR(10) COLLATE Latin1_General_CI_AI) +AS RANGE RIGHT FOR VALUES (N'a', N'b', N'c', N'd'); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_AccentInsensitive +AS PARTITION PF_AccentInsensitive ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using the same collation as the partition function +-- Expected result: Table creation should succeed +CREATE TABLE PartitionedTable5 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_AccentInsensitive(PartitionKey); +GO + +-- check partition key column collation +SELECT name, collation_name FROM sys.all_columns where object_id = object_id('PartitionedTable5') order by name; +GO + +DROP TABLE PartitionedTable5; +GO + +DROP PARTITION SCHEME PS_AccentInsensitive; +GO + +DROP PARTITION FUNCTION PF_AccentInsensitive; +GO + +-------------------------------------------------------------------- +--- Case 6: Usage of invalid collation with non-collatable partition key column +-------------------------------------------------------------------- +-- Create a partition function without specifying a collation +CREATE PARTITION FUNCTION PF_DefaultCollation (INT) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Try to create a partitioned table with a partition key column using an invalid collation +-- Expected result: Throws an error indicating the collation is invalid +CREATE TABLE PartitionedTable6 ( + ID INT IDENTITY(1,1), + PartitionKey INT COLLATE invalid_collation, -- using invalid collation + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO + +DROP PARTITION SCHEME PS_DefaultCollation +DROP PARTITION FUNCTION PF_DefaultCollation +GO + +-------------------------------------------------------------------- +--- Case 7: Usage of valid collation with non-collatable partition key column +-------------------------------------------------------------------- +-- Create a partition function with non-collatable datatype +CREATE PARTITION FUNCTION PF_DefaultCollation (INT) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a valid collation +-- Expected result: Throws an error indicating the datatype is not collatable +CREATE TABLE PartitionedTable7 ( + ID INT IDENTITY(1,1), + PartitionKey INT COLLATE Latin1_GENERAL_CI_AS, -- using valid collation with non-collatable datatype + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO + +DROP PARTITION SCHEME PS_DefaultCollation +DROP PARTITION FUNCTION PF_DefaultCollation +GO + + +----------------------------------------------------------------------------------------------- +--- Case 8: Usage of collatable partition key column with non-collatable partition function datatype +------------------------------------------------------------------------------------------------ +-- Create a partition function with non-collatable datatype +CREATE PARTITION FUNCTION PF_DefaultCollation (INT) +AS RANGE RIGHT FOR VALUES (1, 10, 100); +GO + +-- Create a partition scheme using the above partition function +CREATE PARTITION SCHEME PS_DefaultCollation +AS PARTITION PF_DefaultCollation ALL TO ([PRIMARY]); +GO + +-- Create a partitioned table with a partition key column using a valid collation +-- Expected result: Throws an error indicating the datatype is different +CREATE TABLE PartitionedTable7 ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_GENERAL_CI_AS, -- using valid collation with collatable datatype + Value NVARCHAR(100) +) ON PS_DefaultCollation(PartitionKey); +GO + +DROP PARTITION SCHEME PS_DefaultCollation +DROP PARTITION FUNCTION PF_DefaultCollation +GO + +USE master +Go + +DROP DATABASE CaseInsensitiveAccentSensitive +GO \ No newline at end of file diff --git a/test/JDBC/input/PARTITION-vu-prepare.mix b/test/JDBC/input/PARTITION-vu-prepare.mix index 844eb9faa7e..7ef82ff3720 100644 --- a/test/JDBC/input/PARTITION-vu-prepare.mix +++ b/test/JDBC/input/PARTITION-vu-prepare.mix @@ -575,10 +575,12 @@ SET QUOTED_IDENTIFIER OFF; Go --------------------------------------------------- ---- TO test Permission --------------------------------------------------- -CREATE DATABASE PartitionDb; +-------------------------------------------------------------------------- +--- Test database to test Permission and Collation of Partition Functions +-------------------------------------------------------------------------- +-- Create a test database with a specific collation +CREATE DATABASE PartitionDb +COLLATE Latin1_General_CI_AI;; GO USE PartitionDb; @@ -1161,4 +1163,45 @@ GO CREATE VIEW SysSearchPartitionNULLDepView AS SELECT sys.search_partition('IntPartitionFunction', 10, NULL) +GO + +-------------------------------------------------- +--- To test Collation of Partition Functions +-------------------------------------------------- + +USE PartitionDb; +GO + +-- Create partition functions without explicit collation (will use database default) +CREATE PARTITION FUNCTION PF_CollationTest_Char (CHAR(10)) +AS RANGE RIGHT FOR VALUES ('A', 'M', 'Z'); +GO + +CREATE PARTITION FUNCTION PF_CollationTest_VarChar (VARCHAR(10)) +AS RANGE RIGHT FOR VALUES ('Apple', 'Mango', 'Zebra'); +GO + +CREATE PARTITION FUNCTION PF_CollationTest_NChar (NCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'A', N'M', N'Z'); +GO + +CREATE PARTITION FUNCTION PF_CollationTest_NVarChar (NVARCHAR(10)) +AS RANGE RIGHT FOR VALUES (N'Apple', N'Mango', N'Zebra'); +GO + +-- Create corresponding partition schemes +CREATE PARTITION SCHEME PS_CollationTest_Char +AS PARTITION PF_CollationTest_Char ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME PS_CollationTest_VarChar +AS PARTITION PF_CollationTest_VarChar ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME PS_CollationTest_NChar +AS PARTITION PF_CollationTest_NChar ALL TO ([PRIMARY]); +GO + +CREATE PARTITION SCHEME PS_CollationTest_NVarChar +AS PARTITION PF_CollationTest_NVarChar ALL TO ([PRIMARY]); GO \ No newline at end of file diff --git a/test/JDBC/input/PARTITION-vu-verify.mix b/test/JDBC/input/PARTITION-vu-verify.mix index 54041ed2abf..9c727b5cd45 100644 --- a/test/JDBC/input/PARTITION-vu-verify.mix +++ b/test/JDBC/input/PARTITION-vu-verify.mix @@ -1739,4 +1739,68 @@ USE PartitionDb; GO DROP USER partition_u2 -GO \ No newline at end of file +GO + +--------------------------------------------------------------- +--- Test Collation of Partition Functions after upgrade +--------------------------------------------------------------- +USE PartitionDb +Go + +-- Test 1: Create tables with the compatible collation i.e. database default (should work) +CREATE TABLE PT_SameCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO + +CREATE TABLE PT_SameCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AI, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go + +-- Test 2: Create tables with incompatible collation i.e. other than database default (should fail) +CREATE TABLE PT_DifferentCollation_Char ( + ID INT IDENTITY(1,1), + PartitionKey CHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_Char(PartitionKey); +Go + +CREATE TABLE PT_DifferentCollation_VarChar ( + ID INT IDENTITY(1,1), + PartitionKey VARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_VarChar(PartitionKey); +GO + +CREATE TABLE PT_DifferentCollation_NChar ( + ID INT IDENTITY(1,1), + PartitionKey NCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NChar(PartitionKey); +GO + +CREATE TABLE PT_DifferentCollation_NVarChar ( + ID INT IDENTITY(1,1), + PartitionKey NVARCHAR(10) COLLATE Latin1_General_CI_AS, + Value NVARCHAR(100) +) ON PS_CollationTest_NVarChar(PartitionKey); +Go