mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-24 06:53:59 +08:00
Fix memory issues when scanning chunk constraints
A function to lookup the name of a chunk constraint returned a pointer to string without first copying the string into a safe memory context. This probably worked by chance because everything in the scan function ran in the current memory context, including the deforming of the tuple. However, returning pointers to data in deformed tuples can easily cause memory corruption with the introduction of other changes (such as improved memory management). This memory issue is fixed by explicitly reallocating the string in the memory context that should be used for any returned data. Changes are also made to avoid unnecessarily deforming tuples multiple times in the same scan function.
This commit is contained in:
parent
a311f3735d
commit
09d37fa4f7
@ -647,28 +647,10 @@ ts_chunk_constraint_create_on_chunk(Chunk *chunk, Oid constraint_oid)
|
|||||||
static bool
|
static bool
|
||||||
hypertable_constraint_matches_tuple(TupleInfo *ti, const char *hypertable_constraint_name)
|
hypertable_constraint_matches_tuple(TupleInfo *ti, const char *hypertable_constraint_name)
|
||||||
{
|
{
|
||||||
bool nulls[Natts_chunk_constraint];
|
bool isnull;
|
||||||
Datum values[Natts_chunk_constraint];
|
Datum name = slot_getattr(ti->slot, Anum_chunk_constraint_hypertable_constraint_name, &isnull);
|
||||||
bool should_free;
|
|
||||||
HeapTuple tuple = ts_scanner_fetch_heap_tuple(ti, false, &should_free);
|
|
||||||
const char *constrname;
|
|
||||||
bool matches = false;
|
|
||||||
|
|
||||||
heap_deform_tuple(tuple, ti->slot->tts_tupleDescriptor, values, nulls);
|
return !isnull && namestrcmp(DatumGetName(name), hypertable_constraint_name) == 0;
|
||||||
|
|
||||||
if (!nulls[AttrNumberGetAttrOffset(Anum_chunk_constraint_hypertable_constraint_name)])
|
|
||||||
{
|
|
||||||
constrname = NameStr(*DatumGetName(
|
|
||||||
values[AttrNumberGetAttrOffset(Anum_chunk_constraint_hypertable_constraint_name)]));
|
|
||||||
|
|
||||||
if (strcmp(hypertable_constraint_name, constrname) == 0)
|
|
||||||
matches = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (should_free)
|
|
||||||
heap_freetuple(tuple);
|
|
||||||
|
|
||||||
return matches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -910,20 +892,24 @@ ts_chunk_constraint_get_name_from_hypertable_constraint(Oid chunk_relid,
|
|||||||
init_scan_by_chunk_id(&iterator, DatumGetInt32(chunk_id));
|
init_scan_by_chunk_id(&iterator, DatumGetInt32(chunk_id));
|
||||||
ts_scanner_foreach(&iterator)
|
ts_scanner_foreach(&iterator)
|
||||||
{
|
{
|
||||||
bool nulls[Natts_chunk_constraint];
|
TupleInfo *ti = ts_scan_iterator_tuple_info(&iterator);
|
||||||
Datum values[Natts_chunk_constraint];
|
MemoryContext oldmctx;
|
||||||
bool should_free;
|
bool isnull;
|
||||||
HeapTuple tuple = ts_scan_iterator_fetch_heap_tuple(&iterator, false, &should_free);
|
Datum datum;
|
||||||
|
char *name;
|
||||||
|
|
||||||
if (!hypertable_constraint_matches_tuple(ts_scan_iterator_tuple_info(&iterator),
|
if (!hypertable_constraint_matches_tuple(ti, hypertable_constraint_name))
|
||||||
hypertable_constraint_name))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
heap_deform_tuple(tuple, ts_scan_iterator_tupledesc(&iterator), values, nulls);
|
datum = slot_getattr(ti->slot, Anum_chunk_constraint_constraint_name, &isnull);
|
||||||
|
Assert(!isnull);
|
||||||
|
|
||||||
|
oldmctx = MemoryContextSwitchTo(ti->mctx);
|
||||||
|
name = pstrdup(NameStr(*DatumGetName(datum)));
|
||||||
|
MemoryContextSwitchTo(oldmctx);
|
||||||
ts_scan_iterator_close(&iterator);
|
ts_scan_iterator_close(&iterator);
|
||||||
return NameStr(
|
|
||||||
*DatumGetName(values[AttrNumberGetAttrOffset(Anum_chunk_constraint_constraint_name)]));
|
return name;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user