mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-23 22:41:34 +08:00
This change is part of an effort to create a consistent way of dealing with metadata catalog updates, which is currently a mix of C API and INSERT/UPDATE/DELETE statements from SQL code. This mix makes catalog handling unnecessarily complex as there are multiple ways to update metadata, increasing the risk of security issues with publically exposed SQL functions. It also complicates things like cache invalidation, requiring different mechanisms for C and SQL code. Catalog updates from SQL code require triggers on metadata tables for cache invalidation that do not work with native catalog updates. The creation of chunks has been particularly messy in this regard, making the code hard to follow. Especially the handling of a chunk's constraints, where dimensional and other constraints were handled differently. With this change, constraint handling is now consistent across constraint types with a single API for updating metadata. Reduce memory usage for out-of-order inserts The chunk_result_relation_info should be put on the chunk memory context. This will cause the rri constraint expr to also go onto that context and be correctly freed when the chunk insert state is destroyed.
41 lines
1.6 KiB
PL/PgSQL
41 lines
1.6 KiB
PL/PgSQL
-- Creates a constraint on a chunk.
|
|
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_constraint_add_table_constraint(
|
|
chunk_constraint_row _timescaledb_catalog.chunk_constraint
|
|
)
|
|
RETURNS VOID LANGUAGE PLPGSQL AS
|
|
$BODY$
|
|
DECLARE
|
|
chunk_row _timescaledb_catalog.chunk;
|
|
hypertable_row _timescaledb_catalog.hypertable;
|
|
constraint_oid OID;
|
|
check_sql TEXT;
|
|
def TEXT;
|
|
BEGIN
|
|
SELECT * INTO STRICT chunk_row FROM _timescaledb_catalog.chunk c WHERE c.id = chunk_constraint_row.chunk_id;
|
|
SELECT * INTO STRICT hypertable_row FROM _timescaledb_catalog.hypertable h WHERE h.id = chunk_row.hypertable_id;
|
|
|
|
IF chunk_constraint_row.dimension_slice_id IS NOT NULL THEN
|
|
check_sql = _timescaledb_internal.dimension_slice_get_constraint_sql(chunk_constraint_row.dimension_slice_id);
|
|
IF check_sql IS NOT NULL THEN
|
|
def := format('CHECK (%s)', check_sql);
|
|
ELSE
|
|
def := NULL;
|
|
END IF;
|
|
ELSIF chunk_constraint_row.hypertable_constraint_name IS NOT NULL THEN
|
|
SELECT oid INTO STRICT constraint_oid FROM pg_constraint
|
|
WHERE conname=chunk_constraint_row.hypertable_constraint_name AND
|
|
conrelid = format('%I.%I', hypertable_row.schema_name, hypertable_row.table_name)::regclass::oid;
|
|
def := pg_get_constraintdef(constraint_oid);
|
|
ELSE
|
|
RAISE 'Unknown constraint type';
|
|
END IF;
|
|
|
|
IF def IS NOT NULL THEN
|
|
EXECUTE format(
|
|
$$ ALTER TABLE %I.%I ADD CONSTRAINT %I %s $$,
|
|
chunk_row.schema_name, chunk_row.table_name, chunk_constraint_row.constraint_name, def
|
|
);
|
|
END IF;
|
|
END
|
|
$BODY$;
|