56 Commits

Author SHA1 Message Date
Erik Nordström
09d37fa4f7 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.
2020-07-29 10:40:12 +02:00
Erik Nordström
a311f3735d Adopt table scan methods for Scanner
This change makes the Scanner code agnostic to the underlying storage
implementation of the tables it scans. This also fixes a bug that made
it impossible to use non-heap table access methods on a
hypertable. The bug existed because a check is made for existing data
before a table is made into a hypertable. And, since this check reads
data from the table using the Scanner, it must be able to read the
data irrespective of the underlying storage.

As a result of the more generic scan interface, resource management is
also improved by delivering tuples in reference-counted tuple table
slots. A backwards-compatibility layer is used for PG11, which maps
all table access functions to the heap equivalents.
2020-07-29 10:40:12 +02:00
Sven Klemm
c90397fd6a Remove support for PG9.6 and PG10
This patch removes code support for PG9.6 and PG10. In addition to
removing PG96 and PG10 macros the following changes are done:

remove HAVE_INT64_TIMESTAMP since this is always true on PG10+
remove PG_VERSION_SUPPORTS_MULTINODE
2020-06-02 23:48:35 +02:00
Erik Nordström
6ba70029e3 Cleanup chunk servers when dropping dependencies
Chunk server mappings are now cleaned up when dropping chunk tables
and foreign servers. In particular, this works even when such objects
are removed as a result of cascading deletions of other objects.

Some refactoring has been done to the event trigger handling code in
addition to adding support for new event objects.
2020-05-27 17:31:09 +02:00
niksa
4368fcff3c Add function to reconstruct the creating command for a table
Deparse a table into a set of SQL commands that can be used to
reconstruct it. Together with column definiton it deparses
constraints, indexes, triggers and rules as well. There are some table
types that are not supported: temporary, partitioned, foreign,
inherited and a table that uses options.  Row security is also not
supported.
2020-05-27 17:31:09 +02:00
Erik Nordström
33f1601e6f Handle constraints, triggers, and indexes on distributed hypertables
In distributed hypertables, chunks are foreign tables and such tables
do not support (or should not support) indexes, certain constraints,
and triggers. Therefore, such objects should not recurse to foreign
table chunks nor add a mappings in the `chunk_constraint` or
`chunk_index` tables.

This change ensures that we properly filter out the indexes, triggers,
and constraints that should not recurse to chunks on distributed
hypertables.
2020-05-27 17:31:09 +02:00
Erik Nordström
28e9a443b3 Improve handling of "dropped" chunks
The internal chunk API is updated to avoid returning `Chunk` objects
that are marked `dropped=true` along with some refactoring, hardening,
and cleanup of the internal chunk APIs. In particular, apart from
being returned in a dropped state, chunks could also be returned in a
partial state (without all fields set, partial constraints,
etc.). None of this is allowed as of this change. Further, lock
handling was unclear when joining chunk metadata from different
catalog tables. This is made clear by having chunks built within
nested scan loops so that proper locks are held when joining in
additional metadata (such as constraints).

This change also fixes issues with dropped chunks that caused chunk
metadata to be processed many times instead of just once, leading to
potential bugs or bad performance.

In particular, since the introduction of the “dropped” flag, chunk
metadata can exist in two states: 1. `dropped=false`
2. `dropped=true`. When dropping chunks (e.g., via `drop_chunks`,
`DROP TABLE <chunk>`, or `DROP TABLE <hypertable>`) there are also two
modes of dropping: 1. DELETE row and 2. UPDATE row and SET
dropped=true.

The deletion mode and the current state of chunk lead to a
cross-product resulting in 4 cases when dropping/deleting a chunk:

1. DELETE row when dropped=false
2. DELETE row when dropped=true
3. UPDATE row when dropped=false
4. UPDATE row when dropped=true

Unfortunately, the code didn't distinguish between these cases. In
particular, case (4) should not be able to happen, but since it did it
lead to a recursing loop where an UPDATE created a new tuple that then
is recursed to in the same loop, and so on.

To fix this recursing loop and make the code for dropping chunks less
error prone, a number of assertions have been added, including some
new light-weight scan functions to access chunk information without
building a full-blown chunk.

This change also removes the need to provide the number of constraints
when scanning for chunks. This was really just a hint anyway, but this
is no longer needed since all constraints are joined in anyway.
2020-04-28 13:49:14 +02:00
Ruslan Fomkin
ed32d093dc Use table_open/close and PG aggregated directive
Fixing more places to use table_open and table_close introduced in
PG12. Unifies PG version directives to use aggregated macro.
2020-04-14 23:12:15 +02:00
Joshua Lockerman
949b88ef2e Initial support for PostgreSQL 12
This change includes a major refactoring to support PostgreSQL
12. Note that many tests aren't passing at this point. Changes
include, but are not limited to:

- Handle changes related to table access methods
- New way to expand hypertables since expansion has changed in
  PostgreSQL 12 (more on this below).
- Handle changes related to table expansion for UPDATE/DELETE
- Fixes for various TimescaleDB optimizations that were affected by
  planner changes in PostgreSQL (gapfill, first/last, etc.)

Before PostgreSQL 12, planning was organized something like as
follows:

 1. construct add `RelOptInfo` for base and appendrels
 2. add restrict info, joins, etc.
 3. perform the actual planning with `make_one_rel`

For our optimizations we would expand hypertables in the middle of
step 1; since nothing in the query planner before `make_one_rel` cared
about the inheritance children, we didn’t have to be too precises
about where we were doing it.

However, with PG12, and the optimizations around declarative
partitioning, PostgreSQL now does care about when the children are
expanded, since it wants as much information as possible to perform
partition-pruning. Now planning is organized like:

 1. construct add RelOptInfo for base rels only
 2. add restrict info, joins, etc.
 3. expand appendrels, removing irrelevant declarative partitions
 4. perform the actual planning with make_one_rel

Step 3 always expands appendrels, so when we also expand them during
step 1, the hypertable gets expanded twice, and things in the planner
break.

The changes to support PostgreSQL 12 attempts to solve this problem by
keeping the hypertable root marked as a non-inheritance table until
`make_one_rel` is called, and only then revealing to PostgreSQL that
it does in fact have inheritance children. While this strategy entails
the least code change on our end, the fact that the first hook we can
use to re-enable inheritance is `set_rel_pathlist_hook` it does entail
a number of annoyances:

 1. this hook is called after the sizes of tables are calculated, so we
    must recalculate the sizes of all hypertables, as they will not
    have taken the chunk sizes into account
 2. the table upon which the hook is called will have its paths planned
    under the assumption it has no inheritance children, so if it's a
    hypertable we have to replan it's paths

Unfortunately, the code for doing these is static, so we need to copy
them into our own codebase, instead of just using PostgreSQL's.

In PostgreSQL 12, UPDATE/DELETE on inheritance relations have also
changed and are now planned in two stages:

- In stage 1, the statement is planned as if it was a `SELECT` and all
  leaf tables are discovered.
- In stage 2, the original query is planned against each leaf table,
  discovered in stage 1, directly, not part of an Append.

Unfortunately, this means we cannot look in the appendrelinfo during
UPDATE/DELETE planning, in particular to determine if a table is a
chunk, as the appendrelinfo is not at the point we wish to do so
initialized. This has consequences for how we identify operations on
chunks (sometimes for blocking and something for enabling
functionality).
2020-04-14 23:12:15 +02:00
Ruslan Fomkin
d88be2772b Fix returning error on chunk get and exporting
Fixes to return error in ts_chunk_get_by_relid if fail_if_not_found is
true. Removes TSDLLEXPORT macro from definitions in few C files, which
helps VS Code to work properly and find function definitions.
2020-03-13 09:14:17 +01:00
Matvey Arye
2c594ec6f9 Keep catalog rows for some dropped chunks
If a chunk is dropped but it has a continuous aggregate that is
not dropped we want to preserve the chunk catalog row instead of
deleting the row. This is to prevent dangling identifiers in the
materialization hypertable. It also preserves the dimension slice
and chunk constraints rows for the chunk since those will be necessary
when enabling this with multinode and is necessary to recreate the
chunk too. The postgres objects associated with the chunk are all
dropped (table, constraints, indexes).

If data is ever reinserted to the same data region, the chunk is
recreated with the same dimension definitions as before. The postgres
objects are simply recreated.
2019-12-30 09:10:44 -05:00
Matvey Arye
d9d1a44d2e Refactor chunk handling to separate out stub
Previously, the Chunk struct was used to represent both a full
chunk and the stub used for joins. The stub used for joins
only contained valid values for some chunk fields and not others.
After the join determined that a Chunk was complete, it filled
in the rest of the chunk field. The fact that a chunk could have
only some fields filled out and not others at different times,
made the code hard to follow and error prone.

So we separate out the stub state of the chunk into a separate
struct that doesn't contain the not-filled-out fields inside
of it.  This leverages the type system to prevent errors that
try to access invalid fields during the join phase and makes
the code easier to follow.
2019-12-06 15:04:51 -05:00
gayyappan
72588a2382 Restrict constraints on compressed hypertables.
Primary and unqiue constraints are limited to segment_by and order_by
columns and foreign key constraints are limited to segment_by columns
when creating a compressed hypertable. There are no restrictions on
check constraints.
2019-10-29 19:02:58 -04:00
Erik Nordström
4e08f14075 Fix chunk exclusion with ordered append
With ordered append, chunk exclusion occur only along the primary open
"time" dimension, failing to exclude chunks along additional
partitioning dimensions. For instance, a query on a two-dimensional
table "hyper" (time, device), such as

```
SELECT * FROM hyper
WHERE time > '2019-06-11 12:30'
AND device = 1
ORDER BY time;
```

would only exclude chunks based on the "time" column restriction, but
not the "device" column restriction. This causes an unnecessary number
of chunks to be included in the query plan.

The reason this happens is because chunk exclusion during ordered
append is based on pre-sorting the set of slices in the primary
dimension to determine ordering. This is followed by a scan for
chunks slice-by-slice in the order of the sorted slices. Since those
scans do not include the restrictions in other dimensions, chunks that
would otherwise not match are included in the result.

This change fixes this issue by using the "regular" chunk scan that
account for multi-dimensional restrictions. This is followed by a sort
of the resulting chunks along the primary "time" dimension.

While this, sometimes, means sorting a larger set than the initial
slices in the primary "time" dimension, the resulting chunk set is
smaller instead. Sorting chunks also allows doing secondary ordering
on chunk ID for those chunks that belong to the same "time"
slice. While this additional ordering is not required for correct
tuple ordering, it gives slightly nicer EXPLAIN output since chunks
are also ordered by ID.
2019-07-03 16:31:15 +02:00
Matvey Arye
202da119d7 Refactor chunk_constraint code to use the foreach scanner
This PR changes the chunk_constraint code to use the foreach style
scanner interface. The purpose of this PR is both to reduce the
complexity and verbosity of the chunk_constraint code and to serve
as an example of best practices for using the foreach scanner interface.
2019-03-29 15:51:03 -04:00
Matvey Arye
34edba16a9 Run clang-format on code 2019-02-05 16:55:16 -05:00
Joshua Lockerman
acc41a7712 Update license header
Only have the copyright in the NOTICE. Hopefully
only having to update one place each year will
keep it consistent.
2019-01-03 11:57:51 -05:00
Amy Tai
2e4bb5de2a Recluster and drop chunks scheduling code
For both recluster and drop_chunks policies, adds the scheduler code to run the appropriate function after reading the policy arguments from the appropriate internal policy table. For the recluster jobs, also picks chunks that are eligible for recluster, based on the current selection: 1) chunks at least 3rd newest chunk, 2) have not been reclustered before. The logic will try to pick the oldest such chunk.
2019-01-02 15:43:48 -05:00
Joshua Lockerman
4ff6ac7b91 Initial Timescale-Licensed-Module and License-Key Implementation
This commit adds support for dynamically loaded submodules to timescaledb
as well an initial license-key implementation in the tsl subdirectory.
Dynamically loaded modules allow our users to determine which licenses they
wish to use for their version of timescaledb; if they wish to only use
Apache-Licensed code, they do not load the Timescale-Licensed submodule. Calls
from the Apache-Licensed code into the Timescale-Licensed submodule are
handled via dynamicaly-set function pointers; see tsl/src/Readme.module.md for
more details.

This commit also adds code for license keys for the ApacheOnly, Community, and
Enterprise editions. The license key determines which features are enabled,
and controls loading the submodule: when a license key that requires the
sub-module is installed, the module is automatically loaded.
Currently the ApacheOnly and Community license-keys are hardcoded to be
"ApacheOnly" and "Community" respectively. The first version of the enterprise
license-key is described in tsl/src/Readme.module.md
2019-01-02 15:43:48 -05:00
David Kohn
5aa1edac15 Refactor compatibility functions and code to support PG11
Introduce PG11 support by introducing compatibility functions for
any whose signatures have changed in PG11. Additionally, refactor
the structure of the compatibility functions found in compat.h by
breaking them out by function (or small set of similar functions)
so that it is easier to see what changed between versions and maintain
changes as more versions are supported.

In general, the philosophy has been to try for forward compatibility
wherever possible, so that we use the latest versions of function interfaces
where we can or where reasonably convenient and mimic the behavior
in older versions as much as possible.
2018-12-12 11:42:33 -05:00
Joshua Lockerman
9de504f958 Add ts_ prefix to everything in headers
Future proofing: if we ever want to make our functions available  to
others they’d need to be prefixed to prevent name collisions. In
order to avoid having some functions with the ts_ prefix and
others without, we’re adding the prefix to all non-static
functions now.
2018-12-05 14:43:22 -05:00
Amy Tai
0267f46b56 Clean up catalog code
Organize catalog.c so that functions that access the Catalog struct are physically separate from the functions that modify the actual catalog tables on disk. Also added macros and made static some functions that aren't used outside the catalog files. Also refactored out the CatalogDatabaseInfo struct, which is independent of the Catalog struct and will be reused in the future.
2018-11-27 17:10:50 -05:00
Erik Nordström
28e2e6a2f7 Refactor scanner callback interface
This change adds proper result types for the scanner's filter and
tuple handling callbacks. Previously, these callbacks were supposed to
return bool, which was hard to interpret. For instance, for the tuple
handler callback, true meant continue processing the next tuple while
false meant finish the scan. However, this wasn't always clear. Having
proper return types also makes it easier to see from a function's
signature that it is a scanner callback handler, rather than some
other function that can be called directly.
2018-11-08 17:33:26 +01:00
Joshua Lockerman
d8e41ddaba Add Apache License header to all C files 2018-10-29 13:28:19 -04:00
didier
41d984696c Enclose macro replacement list and arguments in parentheses 2018-09-26 20:55:14 -04:00
Joshua Lockerman
8571e41297 Use AttrNumberGetAttrOffset instead of Anum_name - 1 for array indexing
Use the postgres macro instead of manual subtraction everywhere to be more readable,
and gain the Assert.

Done with
`find ./src -type f -exec sed -i -e 's/Anum_\(.*\) - 1/AttrNumberGetAttrOffset(Anum_\1)/' {} \;`
2018-08-30 17:13:32 +02:00
Erik Nordström
9c9cdca6d3 Add support for adaptive chunk sizing
Users can now (optionally) set a target chunk size and TimescaleDB
will try to adapt the interval length of the first open ("time")
dimension in order to reach that target chunk size. If a hypertable
has more than one open dimension, only the first one will have a
dynamically adapting interval.

Users can optionally specify their own function that calculates the
new dimension interval. They can also set a target size of 0 in order
to estimate a suitable target size for a chunk based on available
memory.
2018-08-08 17:01:31 +02:00
Matvey Arye
7f8d17db24 Handle DEFERRED and VALID options for constraints
Also add tests for deferred constraints in general.
2018-08-07 10:13:29 -04:00
Erik Nordström
cbc5e60abe Block NO INHERIT constraints on hypertables
Constraints with the NO INHERIT option does not make sense on a
hypertable's root table since these will not be enforced.

Previously, NO INHERIT constraints were blocked on chunks, and were
thus not enforced until chunk creation time, allowing creation of NO
INHERIT constraints on empty hypertables, but then causing failure at
chunk-creation time. Instead, NO INHERIT constraints are now properly
blocked at the hypertable level.
2018-07-30 15:34:03 +02:00
Mike Futerko
4f2f1a6eb7 Update the error messages to conform with the style guide; Fix tests
An attempt to unify the error messages to conform with the PostgreSQL error
messages style guide. See the link below:
https://www.postgresql.org/docs/current/static/error-style-guide.html
2018-07-10 12:55:02 -04:00
Erik Nordström
2e1f3b9fd0 Improve memory allocation during cache lookups
Previously, cache lookups were run on the cache's memory
context. While simple, this risked allocating transient (work) data on
that memory context, e.g., when scanning for new cache data during
cache misses.

This change makes scan functions take a memory context, which the
found data should be allocated on. All other data is allocated on the
current memory (typically the transaction's memory context). With this
functionality, a cache can pass its memory context to the scan, thus
avoiding taking on unnecessary memory allocations.
2018-06-22 16:45:07 +02:00
Matvey Arye
26965826f4 Move index and constraints drop handling to event trigger
This Fixes at least two bugs:

1) A drop of a referenced table used to drop the associated
FK constraint but not the metadata associated with the constraint.
Fixes #43.

2) A drop of a column removed any indexes associated with the column
but not the metadata associated with the index.
2018-02-09 10:15:07 -05:00
Erik Nordström
71b11240a7 Delete orphaned dimension slices
When chunks are deleted, dimension slices can be orphaned, i.e., there
are no chunks or chunk constraints that reference such slices. This
change ensures that, when chunks are deleted, orphaned slices are also
deleted.
2018-01-26 21:39:12 +01:00
Erik Nordström
fa19a54a88 Handle deletes on metadata objects via native catalog API
Deletes on metadata in the TimescaleDB catalog has so far been a mix
of native deletes using the C-based catalog API and SQL-based DELETE
statements that CASCADEs.

This mixed environment is confusing, and SQL-based DELETEs do not
consistently clean up objects that are related to the deleted
metadata.

This change moves towards A C-based API for deletes that consistently
deletes also the dependent objects (such as indexes, tables and
constraints).  Ideally, we should prohobit direct manipulation of
catalog tables using SQL statements to avoid ending up in a bad state.

Once all catalog manipulations happend via the native API, we can also
remove the cache invalidation triggers on the catalog tables.
2018-01-26 21:39:12 +01:00
Erik Nordström
b6e2780460 Apply new indentation (pgindent) used in PostgreSQL 10
Source code indentation has been updated in PostgreSQL 10 to fix a
number of issues. This update applies this new indentation to the
entire code base.

The new indentation requires a new version of pg_bsd_indent, which can
be found here:

https://git.postgresql.org/git/pg_bsd_indent.git
2018-01-18 15:19:23 +01:00
Matvey Arye
87f055dd2c Add support for ALTER TABLE RENAME CONSTRAINT.
Renaming constraints on hypertables is now supported. Using the ONLY
option with RENAME CONSTRAINT is blocked for hypertables. Renaming
constraints on chunks is also blocked.

This commit also fixes a possible bug in chunk_constraint code.
Previously, `chunk_constraint_add_from_tuple` used GETSTRUCT on the
tuple to convert the tuple to `FormData_chunk_constraint`. This
was incorrect since some fields can be NULL. Using GETSTRUCT for
tables with NULLABLE fields is unsafe and indeed was incorrect·
in this case.
2018-01-10 13:36:38 -05:00
Erik Nordström
21efcce95c Refactor chunk table creation and unify constraint handling
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.
2017-12-28 11:24:29 +01:00
Matvey Arye
12dff61c20 Fixes insert for 32bit architecture
Fixes problem with insert on 32bit architecture. Fixes #336.
2017-12-07 16:39:15 -05:00
Erik Nordström
2ba1a40a9f Fix issue with creating expression indexes
When creating an index on a chunk based on a index on a hypertable, it
is necessary to adjust the attribute numbers of referenced columns in
case the hypertable and the chunk have different number of attributes
(this can happen, e.g., due to removing columns on the hypertable that
aren't inherited by a newly created chunk). This adjustment was
handled for regular indexes, but not expression indexes, causing an
error to be raised. This change adds the proper handling of expression
indexes.
2017-10-25 10:03:30 +02:00
Matvey Arye
c420c11e44 Create a catalog entry for constraint-backed indexes
This change makes our catalog more in-line with the pg catalog.
It also will simplify a lot of other code.
2017-10-24 11:26:04 -04:00
Matvey Arye
728481ee29 Fix bugs found by valgrind 2017-10-24 11:19:38 -04:00
Erik Nordström
1d95dfbe44 Add limit option to scanner
This adds an option to set a limit on how many tuples to return in a
relation scan using the scanner implemention. This avoids a common
pattern of manually implementing limits in the tuple handling
function.
2017-09-13 12:24:43 +02:00
Matvey Arye
48e0a61131 Remove triggers from chunk and chunk_constraint
Streamline code and remove triggers from chunk and
chunk_constraint. Lots of additional cleanup. Also removes need to CASCADE
hypertable drops (fixes #88).
2017-09-07 11:31:48 -04:00
Matvey Arye
4dcbe6114d Add support for hypertable constraints
This PR add support for primary-key, foreign-key, unique, and exclusion constraints.
Previously supported are CHECK and NOT NULL constraints. Now, foreign key
constraints where a hypertable references a plain table is support
(while vice versa, with a plain table references a hypertable, is still not).
2017-09-07 11:31:48 -04:00
Erik Nordström
c2f686dbba Refactor chunk creation to handle chunk collisions and alignment
When new chunks are created, the calculated chunk hypercube might
collide or not align with existing chunks when partitioning has
changed in one or more dimensions. In such cases, the chunk should be
cut to fit the alignment criteria and any collisions should be
resolved. Unfortunately, alignment and collision detection wasn't
properly handled.

This refactoring adds proper axis-aligned bounding box collision
detection generalized to N dimensions. It also correctly handles
dimension alignment.
2017-09-06 15:07:13 +02:00
Erik Nordström
ad444f8982 Remove unused functions
Remove the following unused functions in order to quench compiler
warnings:

- chunk_constraint_from_form_data()
- chunk_constraint_from_tuple()
- hypercube_free()
2017-06-27 12:43:55 -04:00
Matvey Arye
44da2c0be6 Run pgindent on code 2017-06-26 18:10:59 -04:00
Erik Nordström
a6309dac48 Fix a number of comments and cleanup unused code 2017-06-22 20:15:38 +02:00
Matvey Arye
ce3d630b6d Run pgindent on code 2017-06-22 20:15:38 +02:00
Matvey Arye
9489d06595 Some minor code cleanup 2017-06-22 20:15:38 +02:00