-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathplanner.h
More file actions
159 lines (140 loc) · 5.53 KB
/
Copy pathplanner.h
File metadata and controls
159 lines (140 loc) · 5.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* This file and its contents are licensed under the Apache License 2.0.
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#pragma once
#include <postgres.h>
#include <nodes/parsenodes.h>
#include <nodes/pathnodes.h>
#include <nodes/pg_list.h>
#include <parser/parsetree.h>
#include "chunk.h"
#include "export.h"
#include "guc.h"
#include "hypertable.h"
#include <storage/lockdefs.h>
/*
* Constraints created during planning to improve chunk exclusion
* will be marked with this value as location so they can be easily
* identified and removed when they are no longer needed.
* Removal happens in timescaledb_set_rel_pathlist hook.
*/
#define PLANNER_LOCATION_MAGIC -29811
typedef struct Chunk Chunk;
typedef struct Hypertable Hypertable;
typedef struct TimescaleDBPrivate
{
bool appends_ordered;
/* attno of the time dimension in the parent table if appends are ordered */
int order_attno;
List *nested_oids;
List *chunk_oids;
/* Cached chunk data for the chunk relinfo. */
Chunk *cached_chunk_struct;
/* Cached equivalence members for compressed chunks. List of (EC, EM) Lists. */
List *compressed_ec_em_pairs;
/* Cached transformed pathkeys */
List *transformed_sort_pathkeys;
bool transformed_sort_pathkeys_valid;
} TimescaleDBPrivate;
extern TSDLLEXPORT bool ts_rte_is_hypertable(const RangeTblEntry *rte);
extern TSDLLEXPORT bool ts_rte_is_marked_for_expansion(const RangeTblEntry *rte);
extern TSDLLEXPORT void ts_rte_mark_compressed_relation(RangeTblEntry *rte);
extern TSDLLEXPORT bool ts_contains_external_param(Node *node);
extern TSDLLEXPORT bool ts_contains_join_param(Node *node);
static inline TimescaleDBPrivate *
ts_create_private_reloptinfo(RelOptInfo *rel)
{
Assert(rel->fdw_private == NULL);
rel->fdw_private = palloc0(sizeof(TimescaleDBPrivate));
return rel->fdw_private;
}
static inline TimescaleDBPrivate *
ts_get_private_reloptinfo(RelOptInfo *rel)
{
/* If rel->fdw_private is not set up here it means the rel got missclassified
* and did not get expanded by our code but by postgres native code.
* This is not a problem by itself, but probably an oversight on our part.
*/
Assert(rel->fdw_private);
return rel->fdw_private ? rel->fdw_private : ts_create_private_reloptinfo(rel);
}
/*
* TsRelType provides consistent classification of planned relations across
* planner hooks.
*/
typedef enum TsRelType
{
TS_REL_HYPERTABLE, /* A hypertable with no parent */
TS_REL_CHUNK_STANDALONE, /* Chunk with no parent (i.e., it's part of the
* plan as a standalone table. For example,
* querying the chunk directly and not via the
* parent hypertable). */
TS_REL_HYPERTABLE_CHILD, /* Self child. With PostgreSQL's table expansion,
* the root table is expanded as a child of
* itself. This happens when our expansion code
* is turned off. */
TS_REL_CHUNK_CHILD, /* Chunk with parent and the result of table
* expansion. */
TS_REL_OTHER, /* Anything which is none of the above */
} TsRelType;
extern TSDLLEXPORT Hypertable *ts_planner_get_hypertable(const Oid relid, const unsigned int flags);
extern void ts_preprocess_first_last_aggregates(PlannerInfo *root, List *tlist);
extern void ts_plan_expand_hypertable_chunks(Hypertable *ht, PlannerInfo *root, RelOptInfo *rel,
bool include_osm);
extern void ts_plan_expand_timebucket_annotate(PlannerInfo *root, RelOptInfo *rel);
extern Expr *ts_transform_time_bucket_comparison(Expr *);
extern Expr *ts_transform_nested_time_bucket_comparison(Expr *);
extern Node *ts_constify_now(PlannerInfo *root, List *rtable, Node *node);
extern void ts_planner_constraint_cleanup(PlannerInfo *root, RelOptInfo *rel);
extern Node *ts_add_space_constraints(PlannerInfo *root, List *rtable, Node *node);
extern TSDLLEXPORT void ts_add_baserel_cache_entry_for_chunk(Oid chunk_reloid,
Hypertable *hypertable);
TsRelType TSDLLEXPORT ts_classify_relation(const PlannerInfo *root, const RelOptInfo *rel,
Hypertable **ht);
/*
* Chunk-equivalent of planner_rt_fetch(), but returns the corresponding chunk
* instead of range table entry.
*
* Returns NULL if this rel is not a chunk.
*
* This cache should be pre-warmed by hypertable expansion, but it
* doesn't run in the following cases:
*
* 1. if it was a direct query on the chunk;
*
* 2. if it is not a SELECT QUERY.
*/
static inline const Chunk *
ts_planner_chunk_fetch(const PlannerInfo *root, RelOptInfo *rel)
{
TimescaleDBPrivate *rel_private;
/* The rel can only be a chunk if it is part of a hypertable expansion
* (RELOPT_OTHER_MEMBER_REL) or a directly query on the chunk
* (RELOPT_BASEREL) */
if (rel->reloptkind != RELOPT_OTHER_MEMBER_REL && rel->reloptkind != RELOPT_BASEREL)
{
return NULL;
}
/* The rel_private entry should have been created as part of classifying
* the relation in timescaledb_get_relation_info_hook(). Therefore,
* ts_get_private_reloptinfo() asserts that it is already set but falls
* back to creating rel_private in release builds for safety. */
rel_private = ts_get_private_reloptinfo(rel);
if (NULL == rel_private->cached_chunk_struct)
{
RangeTblEntry *rte = planner_rt_fetch(rel->relid, root);
/*
* Get the chunk and cache it. Do not use a slice tuple lock because
* that will assign a transaction ID, which is not necessary for
* queries.
*/
rel_private->cached_chunk_struct =
ts_chunk_get_by_relid_locked(rte->relid,
AccessShareLock,
NULL,
/* fail_if_not_found = */ true);
}
return rel_private->cached_chunk_struct;
}