mirror of https://github.com/citusdata/citus.git
Merge pull request #6297 from citusdata/disallow-numeric-negative-scale
Relevant PG commit: 085f931f52494e1f304e35571924efa6fcdc2b44pull/6288/head
commit
b15cb146a3
|
@ -139,6 +139,14 @@ static Oid DropFKeysAndUndistributeTable(Oid relationId);
|
||||||
static void DropFKeysRelationInvolvedWithTableType(Oid relationId, int tableTypeFlag);
|
static void DropFKeysRelationInvolvedWithTableType(Oid relationId, int tableTypeFlag);
|
||||||
static void CopyLocalDataIntoShards(Oid relationId);
|
static void CopyLocalDataIntoShards(Oid relationId);
|
||||||
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
||||||
|
|
||||||
|
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
||||||
|
static bool DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
||||||
|
Var *distributionColumn);
|
||||||
|
static int numeric_typmod_scale(int32 typmod);
|
||||||
|
static bool is_valid_numeric_typmod(int32 typmod);
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
static bool DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
||||||
Var *distributionColumn);
|
Var *distributionColumn);
|
||||||
static bool CanUseExclusiveConnections(Oid relationId, bool localTableEmpty);
|
static bool CanUseExclusiveConnections(Oid relationId, bool localTableEmpty);
|
||||||
|
@ -1681,6 +1689,20 @@ EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||||
"AS (...) STORED.")));
|
"AS (...) STORED.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
||||||
|
|
||||||
|
/* verify target relation is not distributed by a column of type numeric with negative scale */
|
||||||
|
if (distributionMethod != DISTRIBUTE_BY_NONE &&
|
||||||
|
DistributionColumnUsesNumericColumnNegativeScale(relationDesc,
|
||||||
|
distributionColumn))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("cannot distribute relation: %s", relationName),
|
||||||
|
errdetail("Distribution column must not use numeric type "
|
||||||
|
"with negative scale")));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* check for support function needed by specified partition method */
|
/* check for support function needed by specified partition method */
|
||||||
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
||||||
{
|
{
|
||||||
|
@ -2401,6 +2423,59 @@ RelationUsesIdentityColumns(TupleDesc relationDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (PG_VERSION_NUM >= PG_VERSION_15)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* is_valid_numeric_typmod checks if the typmod value is valid
|
||||||
|
*
|
||||||
|
* Because of the offset, valid numeric typmods are at least VARHDRSZ
|
||||||
|
*
|
||||||
|
* Copied from PG. See numeric.c for understanding how this works.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
is_valid_numeric_typmod(int32 typmod)
|
||||||
|
{
|
||||||
|
return typmod >= (int32) VARHDRSZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* numeric_typmod_scale extracts the scale from a numeric typmod.
|
||||||
|
*
|
||||||
|
* Copied from PG. See numeric.c for understanding how this works.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
numeric_typmod_scale(int32 typmod)
|
||||||
|
{
|
||||||
|
return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DistributionColumnUsesNumericColumnNegativeScale returns whether a given relation uses
|
||||||
|
* numeric data type with negative scale on distribution column
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
DistributionColumnUsesNumericColumnNegativeScale(TupleDesc relationDesc,
|
||||||
|
Var *distributionColumn)
|
||||||
|
{
|
||||||
|
Form_pg_attribute attributeForm = TupleDescAttr(relationDesc,
|
||||||
|
distributionColumn->varattno - 1);
|
||||||
|
|
||||||
|
if (attributeForm->atttypid == NUMERICOID &&
|
||||||
|
is_valid_numeric_typmod(attributeForm->atttypmod) &&
|
||||||
|
numeric_typmod_scale(attributeForm->atttypmod) < 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DistributionColumnUsesGeneratedStoredColumn returns whether a given relation uses
|
* DistributionColumnUsesGeneratedStoredColumn returns whether a given relation uses
|
||||||
* GENERATED ALWAYS AS (...) STORED on distribution column
|
* GENERATED ALWAYS AS (...) STORED on distribution column
|
||||||
|
|
|
@ -392,9 +392,37 @@ ON (true)
|
||||||
WHEN MATCHED THEN
|
WHEN MATCHED THEN
|
||||||
UPDATE SET x = (SELECT count(*) FROM tbl2);
|
UPDATE SET x = (SELECT count(*) FROM tbl2);
|
||||||
ERROR: MERGE command is not supported on Citus tables yet
|
ERROR: MERGE command is not supported on Citus tables yet
|
||||||
|
-- test numeric types with negative scale
|
||||||
|
CREATE TABLE numeric_negative_scale(numeric_column numeric(3,-1), orig_value int);
|
||||||
|
INSERT into numeric_negative_scale SELECT x,x FROM generate_series(111, 115) x;
|
||||||
|
-- verify that we can not distribute by a column that has numeric type with negative scale
|
||||||
|
SELECT create_distributed_table('numeric_negative_scale','numeric_column');
|
||||||
|
ERROR: cannot distribute relation: numeric_negative_scale
|
||||||
|
DETAIL: Distribution column must not use numeric type with negative scale
|
||||||
|
-- However, we can distribute by other columns
|
||||||
|
SELECT create_distributed_table('numeric_negative_scale','orig_value');
|
||||||
|
NOTICE: Copying data from local table...
|
||||||
|
NOTICE: copying the data has completed
|
||||||
|
DETAIL: The local data in the table is no longer visible, but is still on disk.
|
||||||
|
HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$pg15.numeric_negative_scale$$)
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM numeric_negative_scale ORDER BY 1,2;
|
||||||
|
numeric_column | orig_value
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
110 | 111
|
||||||
|
110 | 112
|
||||||
|
110 | 113
|
||||||
|
110 | 114
|
||||||
|
120 | 115
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
-- Clean up
|
-- Clean up
|
||||||
DROP SCHEMA pg15 CASCADE;
|
DROP SCHEMA pg15 CASCADE;
|
||||||
NOTICE: drop cascades to 9 other objects
|
NOTICE: drop cascades to 10 other objects
|
||||||
DETAIL: drop cascades to collation german_phonebook_test
|
DETAIL: drop cascades to collation german_phonebook_test
|
||||||
drop cascades to collation default_provider
|
drop cascades to collation default_provider
|
||||||
drop cascades to table sale
|
drop cascades to table sale
|
||||||
|
@ -404,3 +432,4 @@ drop cascades to view sale_triggers
|
||||||
drop cascades to table generated_stored_ref
|
drop cascades to table generated_stored_ref
|
||||||
drop cascades to table tbl1
|
drop cascades to table tbl1
|
||||||
drop cascades to table tbl2
|
drop cascades to table tbl2
|
||||||
|
drop cascades to table numeric_negative_scale
|
||||||
|
|
|
@ -245,5 +245,15 @@ ON (true)
|
||||||
WHEN MATCHED THEN
|
WHEN MATCHED THEN
|
||||||
UPDATE SET x = (SELECT count(*) FROM tbl2);
|
UPDATE SET x = (SELECT count(*) FROM tbl2);
|
||||||
|
|
||||||
|
-- test numeric types with negative scale
|
||||||
|
CREATE TABLE numeric_negative_scale(numeric_column numeric(3,-1), orig_value int);
|
||||||
|
INSERT into numeric_negative_scale SELECT x,x FROM generate_series(111, 115) x;
|
||||||
|
-- verify that we can not distribute by a column that has numeric type with negative scale
|
||||||
|
SELECT create_distributed_table('numeric_negative_scale','numeric_column');
|
||||||
|
-- However, we can distribute by other columns
|
||||||
|
SELECT create_distributed_table('numeric_negative_scale','orig_value');
|
||||||
|
|
||||||
|
SELECT * FROM numeric_negative_scale ORDER BY 1,2;
|
||||||
|
|
||||||
-- Clean up
|
-- Clean up
|
||||||
DROP SCHEMA pg15 CASCADE;
|
DROP SCHEMA pg15 CASCADE;
|
||||||
|
|
Loading…
Reference in New Issue