PostgreSQL Source Code
git master
subscripting.h
Go to the documentation of this file.
1
/*-------------------------------------------------------------------------
2
*
3
* subscripting.h
4
* API for generic type subscripting
5
*
6
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
8
*
9
* src/include/nodes/subscripting.h
10
*
11
*-------------------------------------------------------------------------
12
*/
13
#ifndef SUBSCRIPTING_H
14
#define SUBSCRIPTING_H
15
16
#include "
nodes/primnodes.h
"
17
18
/* Forward declarations, to avoid including other headers */
19
struct
ParseState
;
20
struct
SubscriptingRefState
;
21
struct
SubscriptExecSteps
;
22
23
/*
24
* The SQL-visible function that defines a subscripting method is declared
25
* subscripting_function(internal) returns internal
26
* but it actually is not passed any parameter. It must return a pointer
27
* to a "struct SubscriptRoutines" that provides pointers to the individual
28
* subscript parsing and execution methods. Typically the pointer will point
29
* to a "static const" variable, but at need it can point to palloc'd space.
30
* The type (after domain-flattening) of the head variable or expression
31
* of a subscripting construct determines which subscripting function is
32
* called for that construct.
33
*
34
* In addition to the method pointers, struct SubscriptRoutines includes
35
* several bool flags that specify properties of the subscripting actions
36
* this data type can perform:
37
*
38
* fetch_strict indicates that a fetch SubscriptRef is strict, i.e., returns
39
* NULL if any input (either the container or any subscript) is NULL.
40
*
41
* fetch_leakproof indicates that a fetch SubscriptRef is leakproof, i.e.,
42
* will not throw any data-value-dependent errors. Typically this requires
43
* silently returning NULL for invalid subscripts.
44
*
45
* store_leakproof similarly indicates whether an assignment SubscriptRef is
46
* leakproof. (It is common to prefer throwing errors for invalid subscripts
47
* in assignments; that's fine, but it makes the operation not leakproof.
48
* In current usage there is no advantage in making assignments leakproof.)
49
*
50
* There is no store_strict flag. Such behavior would generally be
51
* undesirable, since for example a null subscript in an assignment would
52
* cause the entire container to become NULL.
53
*
54
* Regardless of these flags, all SubscriptRefs are expected to be immutable,
55
* that is they must always give the same results for the same inputs.
56
* They are expected to always be parallel-safe, as well.
57
*/
58
59
/*
60
* The transform method is called during parse analysis of a subscripting
61
* construct. The SubscriptingRef node has been constructed, but some of
62
* its fields still need to be filled in, and the subscript expression(s)
63
* are still in raw form. The transform method is responsible for doing
64
* parse analysis of each subscript expression (using transformExpr),
65
* coercing the subscripts to whatever type it needs, and building the
66
* refupperindexpr and reflowerindexpr lists from those results. The
67
* reflowerindexpr list must be empty for an element operation, or the
68
* same length as refupperindexpr for a slice operation. Insert NULLs
69
* (that is, an empty parse tree, not a null Const node) for any omitted
70
* subscripts in a slice operation. (Of course, if the transform method
71
* does not care to support slicing, it can just throw an error if isSlice.)
72
* See array_subscript_transform() for sample code.
73
*
74
* The transform method is also responsible for identifying the result type
75
* of the subscripting operation. At call, refcontainertype and reftypmod
76
* describe the container type (this will be a base type not a domain), and
77
* refelemtype is set to the container type's pg_type.typelem value. The
78
* transform method must set refrestype and reftypmod to describe the result
79
* of subscripting. For arrays, refrestype is set to refelemtype for an
80
* element operation or refcontainertype for a slice, while reftypmod stays
81
* the same in either case; but other types might use other rules. The
82
* transform method should ignore refcollid, as that's determined later on
83
* during parsing.
84
*
85
* At call, refassgnexpr has not been filled in, so the SubscriptingRef node
86
* always looks like a fetch; refrestype should be set as though for a
87
* fetch, too. (The isAssignment parameter is typically only useful if the
88
* transform method wishes to throw an error for not supporting assignment.)
89
* To complete processing of an assignment, the core parser will coerce the
90
* element/slice source expression to the returned refrestype and reftypmod
91
* before putting it into refassgnexpr. It will then set refrestype and
92
* reftypmod to again describe the container type, since that's what an
93
* assignment must return.
94
*/
95
typedef
void (*
SubscriptTransform
) (
SubscriptingRef
*sbsref,
96
List
*indirection,
97
struct
ParseState
*pstate,
98
bool
isSlice,
99
bool
isAssignment);
100
101
/*
102
* The exec_setup method is called during executor-startup compilation of a
103
* SubscriptingRef node in an expression. It must fill *methods with pointers
104
* to functions that can be called for execution of the node. Optionally,
105
* exec_setup can initialize sbsrefstate->workspace to point to some palloc'd
106
* workspace for execution. (Typically, such workspace is used to hold
107
* looked-up catalog data and/or provide space for the check_subscripts step
108
* to pass data forward to the other step functions.) See executor/execExpr.h
109
* for the definitions of these structs and other ones used in expression
110
* execution.
111
*
112
* The methods to be provided are:
113
*
114
* sbs_check_subscripts: examine the just-computed subscript values available
115
* in sbsrefstate's arrays, and possibly convert them into another form
116
* (stored in sbsrefstate->workspace). Return TRUE to continue with
117
* evaluation of the subscripting construct, or FALSE to skip it and return an
118
* overall NULL result. If this is a fetch and the data type's fetch_strict
119
* flag is true, then sbs_check_subscripts must return FALSE if there are any
120
* NULL subscripts. Otherwise it can choose to throw an error, or return
121
* FALSE, or let sbs_fetch or sbs_assign deal with the null subscripts.
122
*
123
* sbs_fetch: perform a subscripting fetch, using the container value in
124
* *op->resvalue and the subscripts from sbs_check_subscripts. If
125
* fetch_strict is true then all these inputs can be assumed non-NULL,
126
* otherwise sbs_fetch must check for null inputs. Place the result in
127
* *op->resvalue / *op->resnull.
128
*
129
* sbs_assign: perform a subscripting assignment, using the original
130
* container value in *op->resvalue / *op->resnull, the subscripts from
131
* sbs_check_subscripts, and the new element/slice value in
132
* sbsrefstate->replacevalue/replacenull. Any of these inputs might be NULL
133
* (unless sbs_check_subscripts rejected null subscripts). Place the result
134
* (an entire new container value) in *op->resvalue / *op->resnull.
135
*
136
* sbs_fetch_old: this is only used in cases where an element or slice
137
* assignment involves an assignment to a sub-field or sub-element
138
* (i.e., nested containers are involved). It must fetch the existing
139
* value of the target element or slice. This is exactly the same as
140
* sbs_fetch except that (a) it must cope with a NULL container, and
141
* with NULL subscripts if sbs_check_subscripts allows them (typically,
142
* returning NULL is good enough); and (b) the result must be placed in
143
* sbsrefstate->prevvalue/prevnull, without overwriting *op->resvalue.
144
*
145
* Subscripting implementations that do not support assignment need not
146
* provide sbs_assign or sbs_fetch_old methods. It might be reasonable
147
* to also omit sbs_check_subscripts, in which case the sbs_fetch method must
148
* combine the functionality of sbs_check_subscripts and sbs_fetch. (The
149
* main reason to have a separate sbs_check_subscripts method is so that
150
* sbs_fetch_old and sbs_assign need not duplicate subscript processing.)
151
* Set the relevant pointers to NULL for any omitted methods.
152
*/
153
typedef
void (*
SubscriptExecSetup
) (
const
SubscriptingRef
*sbsref,
154
struct
SubscriptingRefState
*sbsrefstate,
155
struct
SubscriptExecSteps
*methods);
156
157
/* Struct returned by the SQL-visible subscript handler function */
158
typedef
struct
SubscriptRoutines
159
{
160
SubscriptTransform
transform
;
/* parse analysis function */
161
SubscriptExecSetup
exec_setup
;
/* expression compilation function */
162
bool
fetch_strict
;
/* is fetch SubscriptRef strict? */
163
bool
fetch_leakproof
;
/* is fetch SubscriptRef leakproof? */
164
bool
store_leakproof
;
/* is assignment SubscriptRef leakproof? */
165
}
SubscriptRoutines
;
166
167
#endif
/* SUBSCRIPTING_H */
primnodes.h
List
Definition:
pg_list.h:54
ParseState
Definition:
parse_node.h:193
SubscriptExecSteps
Definition:
execExpr.h:784
SubscriptRoutines
Definition:
subscripting.h:159
SubscriptRoutines::fetch_leakproof
bool fetch_leakproof
Definition:
subscripting.h:163
SubscriptRoutines::exec_setup
SubscriptExecSetup exec_setup
Definition:
subscripting.h:161
SubscriptRoutines::store_leakproof
bool store_leakproof
Definition:
subscripting.h:164
SubscriptRoutines::fetch_strict
bool fetch_strict
Definition:
subscripting.h:162
SubscriptRoutines::transform
SubscriptTransform transform
Definition:
subscripting.h:160
SubscriptingRefState
Definition:
execExpr.h:754
SubscriptingRef
Definition:
primnodes.h:680
SubscriptExecSetup
void(* SubscriptExecSetup)(const SubscriptingRef *sbsref, struct SubscriptingRefState *sbsrefstate, struct SubscriptExecSteps *methods)
Definition:
subscripting.h:153
SubscriptRoutines
struct SubscriptRoutines SubscriptRoutines
SubscriptTransform
void(* SubscriptTransform)(SubscriptingRef *sbsref, List *indirection, struct ParseState *pstate, bool isSlice, bool isAssignment)
Definition:
subscripting.h:95
src
include
nodes
subscripting.h
Generated on Tue Sep 17 2024 00:13:25 for PostgreSQL Source Code by
1.9.1