PostgreSQL Source Code: src/backend/utils/adt/arraysubs.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
25#include "utils/fmgrprotos.h"
27
28
29
31{
32
36 bool refelembyval;
38
39
40
41
42
43
47
48
49
50
51
52
53
54
55static void
57 List *indirection,
59 bool isSlice,
60 bool isAssignment)
61{
65
66
67
68
69
70
71
72
73
74 foreach(idx, indirection)
75 {
77 Node *subexpr;
78
79 if (isSlice)
80 {
82 {
84
87 INT4OID, -1,
90 -1);
91 if (subexpr == NULL)
93 (errcode(ERRCODE_DATATYPE_MISMATCH),
94 errmsg("array subscript must have type integer"),
96 }
98 {
99
101 -1,
105 false,
106 true);
107 }
108 else
109 {
110
111 subexpr = NULL;
112 }
113 lowerIndexpr = lappend(lowerIndexpr, subexpr);
114 }
115 else
117
118 if (ai->uidx)
119 {
121
124 INT4OID, -1,
127 -1);
128 if (subexpr == NULL)
130 (errcode(ERRCODE_DATATYPE_MISMATCH),
131 errmsg("array subscript must have type integer"),
133 }
134 else
135 {
136
138 subexpr = NULL;
139 }
140 upperIndexpr = lappend(upperIndexpr, subexpr);
141 }
142
143
146
147
150 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
151 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
153
154
155
156
157
158
159
160
161 if (isSlice)
162 sbsref->refrestype = sbsref->refcontainertype;
163 else
164 sbsref->refrestype = sbsref->refelemtype;
165}
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180static bool
184{
187
188
190 {
192 {
193
195 {
198 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
199 errmsg("array subscript in assignment must not be null")));
201 return false;
202 }
204 }
205 }
206
207
208 for (int i = 0; i < sbsrefstate->numlower; i++)
209 {
211 {
212
214 {
217 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
218 errmsg("array subscript in assignment must not be null")));
220 return false;
221 }
223 }
224 }
225
226 return true;
227}
228
229
230
231
232
233
234
235
236static void
240{
243
244
246
255}
256
257
258
259
260
261
262
263
264static void
268{
271
272
274
285
286}
287
288
289
290
291
292
293
294static void
298{
302
303
304
305
306
307
309 {
311 return;
312 }
313
314
315
316
317
318
319
321 {
324 }
325
335
336}
337
338
339
340
341
342
343
344static void
348{
352
353
354
355
356
357
359 {
361 return;
362 }
363
364
365
366
367
368
369
371 {
374 }
375
388
389}
390
391
392
393
394
395
396
397
398
399static void
403{
406
408 {
409
411 sbsrefstate->prevnull = true;
412 }
413 else
422}
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439static void
443{
446
448 {
449
451 sbsrefstate->prevnull = true;
452 }
453 else
454 {
465
466 sbsrefstate->prevnull = false;
467 }
468}
469
470
471
472
473static void
477{
478 bool is_slice = (sbsrefstate->numlower != 0);
480
481
482
483
484
485
488 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
489 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
491
492
493 if (sbsrefstate->numlower != 0 &&
495 elog(ERROR, "upper and lower index lists are not same length");
496
497
498
499
501 sbsrefstate->workspace = workspace;
502
503
504
505
506 workspace->refelemtype = sbsref->refelemtype;
512
513
514
515
517 if (is_slice)
518 {
522 }
523 else
524 {
528 }
529}
530
531
532
533
534
535
536
537
538
541{
545 .fetch_strict = true,
546 .fetch_leakproof = true,
547 .store_leakproof = false
548 };
549
551}
552
553
554
555
556
557
558
559
560
561
562
563
564
565
568{
572 .fetch_strict = true,
573 .fetch_leakproof = true,
574 .store_leakproof = false
575 };
576
578}
579
580
581
582
583
584
587{
589 Node *ret = NULL;
590
592 {
593
594
595
596
597
598
599
602
603 if (refexpr && IsA(refexpr, Param) &&
607 ret = (Node *) refexpr;
608 }
609
611}
Datum idx(PG_FUNCTION_ARGS)
ArrayType * construct_empty_array(Oid elmtype)
Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Datum array_set_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
static void array_subscript_assign_slice(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
static void array_subscript_fetch_old(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
static void array_subscript_assign(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
static void array_exec_setup(const SubscriptingRef *sbsref, SubscriptingRefState *sbsrefstate, SubscriptExecSteps *methods)
static void array_subscript_fetch(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
Datum array_subscript_handler_support(PG_FUNCTION_ARGS)
static void array_subscript_fetch_old_slice(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
static void array_subscript_fetch_slice(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
Datum array_subscript_handler(PG_FUNCTION_ARGS)
static void array_subscript_transform(SubscriptingRef *sbsref, List *indirection, ParseState *pstate, bool isSlice, bool isAssignment)
Datum raw_array_subscript_handler(PG_FUNCTION_ARGS)
static bool array_subscript_check_subscripts(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
struct ArraySubWorkspace ArraySubWorkspace
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_POINTER(x)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
int16 get_typlen(Oid typid)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Oid exprType(const Node *expr)
int exprLocation(const Node *expr)
#define IsA(nodeptr, _type_)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
int parser_errposition(ParseState *pstate, int location)
#define lfirst_node(type, lc)
static int list_length(const List *l)
static Datum PointerGetDatum(const void *X)
static Datum Int32GetDatum(int32 X)
static int32 DatumGetInt32(Datum X)
struct SubscriptingRefState * state
struct ExprEvalStep::@55::@83 sbsref_subscript
struct ExprEvalStep::@55::@84 sbsref
union ExprEvalStep::@55 d
ParseExprKind p_expr_kind
ExecEvalSubroutine sbs_fetch_old
ExecEvalBoolSubroutine sbs_check_subscripts
ExecEvalSubroutine sbs_assign
ExecEvalSubroutine sbs_fetch
SubscriptTransform transform