PostgreSQL Source Code: src/backend/executor/nodeSubplan.c Source File (original) (raw)
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
28
29#include <math.h>
30
41
44 bool *isNull);
47 bool *isNull);
53
54
55
56
57
58
59
60
64 bool *isNull)
65{
70
72
73
74 *isNull = false;
75
76
78 elog(ERROR, "CTE subplans should not be executed via ExecSubPlan");
80 elog(ERROR, "cannot set parent params from subquery");
81
82
84
85
88 else
90
91
93
94 return retval;
95}
96
97
98
99
103 bool *isNull)
104{
108
109
111 elog(ERROR, "hashed subplan with direct correlation not supported");
112
113
114
115
116
119
120
121
122
123
124 *isNull = false;
127
128
129
130
131
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
158 {
161 slot,
164 {
167 }
170 {
172 *isNull = true;
174 }
177 }
178
179
180
181
182
183
184
185
186
187
188
190 {
193 }
195 {
197 *isNull = true;
199 }
200
203 {
205 *isNull = true;
207 }
210 {
212 *isNull = true;
214 }
217}
218
219
220
221
225 bool *isNull)
226{
233 bool found = false;
236
237
241
242
243
244
245
246
248
249
250
251
252
253
254
255 foreach(l, subplan->parParam)
256 {
258
260 }
261
262
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
292 *isNull = false;
293
297 {
300 bool rownull;
301 int col;
303
305 {
306 found = true;
308 break;
309 }
310
312 {
313
314 if (found)
316 (errcode(ERRCODE_CARDINALITY_VIOLATION),
317 errmsg("more than one row returned by a subquery used as an expression")));
318 found = true;
319
320
321
322
323
324
325
326
327
331
333
334 continue;
335 }
336
338 {
339
340 if (found)
342 (errcode(ERRCODE_CARDINALITY_VIOLATION),
343 errmsg("more than one row returned by a subquery used as an expression")));
344 found = true;
345
346
347
348
349
350
351
352
353
357
358
359
360
361 col = 1;
362 foreach(plst, subplan->setParam)
363 {
366
371 col++;
372 }
373
374
375 continue;
376 }
377
379 {
381 bool disnull;
382
383 found = true;
384
389
390 continue;
391 }
392
393
396 (errcode(ERRCODE_CARDINALITY_VIOLATION),
397 errmsg("more than one row returned by a subquery used as an expression")));
398
399 found = true;
400
401
402
403
404
405
406 col = 1;
407 foreach(plst, subplan->paramIds)
408 {
411
415 col++;
416 }
417
419 &rownull);
420
422 {
423
424 if (rownull)
425 *isNull = true;
427 {
429 *isNull = false;
430 break;
431 }
432 }
434 {
435
436 if (rownull)
437 *isNull = true;
439 {
441 *isNull = false;
442 break;
443 }
444 }
445 else
446 {
447
448 result = rowresult;
449 *isNull = rownull;
450 }
451 }
452
454
456 {
457
459 }
460 else if (!found)
461 {
462
463
464
465
466
469 {
470 result = (Datum) 0;
471 *isNull = true;
472 }
474 {
475
476 foreach(l, subplan->setParam)
477 {
480
484 prmdata->isnull = true;
485 }
486 }
487 }
488
489 return result;
490}
491
492
493
494
495static void
497{
500 int ncols = node->numCols;
503 long nbuckets;
505
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
531
533 if (nbuckets < 1)
534 nbuckets = 1;
535
538 else
542 ncols,
547 nbuckets,
548 0,
552 false);
553
555 {
556 if (ncols == 1)
557 nbuckets = 1;
558 else
559 {
560 nbuckets /= 16;
561 if (nbuckets < 1)
562 nbuckets = 1;
563 }
564
567 else
571 ncols,
576 nbuckets,
577 0,
581 false);
582 }
583 else
585
586
587
588
589
591
592
593
594
596
597
598
599
600
604 {
605 int col = 1;
607 bool isnew;
608
609
610
611
612
613 foreach(plst, subplan->paramIds)
614 {
617
622 col++;
623 }
625
626
627
628
630 {
633 }
635 {
638 }
639
640
641
642
643
645 }
646
647
648
649
650
651
652
653
655
657}
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673static bool
676 int numCols,
679 const Oid *collations,
681{
683 bool result;
684 int i;
685
686
689
690
691
692
693
694
695
696 result = false;
697
698 for (i = numCols; --i >= 0;)
699 {
702 attr2;
703 bool isNull1,
704 isNull2;
705
707
708 if (isNull1)
709 continue;
710
712
713 if (isNull2)
714 continue;
715
716
718 collations[i],
719 attr1, attr2)))
720 {
721 result = true;
722 break;
723 }
724 }
725
727
728 return result;
729}
730
731
732
733
734
735
736
737
738
739
740
741
742static bool
745{
746 int numCols = hashtable->numCols;
750
753 {
755
758 numCols, keyColIdx,
759 eqfunctions,
762 {
764 return true;
765 }
766 }
767
768 return false;
769}
770
771
772
773
774
775
776
777static bool
779{
781 int i;
782
783 for (i = 1; i <= ncols; i++)
784 {
786 return false;
787 }
788 return true;
789}
790
791
792
793
794
795
796
797static bool
799{
801 int i;
802
803 for (i = 1; i <= ncols; i++)
804 {
806 return false;
807 }
808 return true;
809}
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
827{
830
831 sstate->subplan = subplan;
832
833
836
837
838
839
840
842 elog(ERROR, "subplan \"%s\" was not initialized",
844
845
846 sstate->parent = parent;
847
848
850
851
852
853
868
869
870
871
872
873
874
875
876
877
878
879
882 {
884
885 foreach(lst, subplan->setParam)
886 {
889
891 }
892 }
893
894
895
896
897
899 {
900 int ncols,
901 i;
904 Oid *cross_eq_funcoids;
907 List *oplist,
908 *lefttlist,
909 *righttlist;
911
912
915 "Subplan HashTable Context",
917
920 "Subplan HashTable Temp Context",
922
924
925
926
927
928
929
930
931
932
933
934
935
936
937
939 {
940
942 }
944 {
945
947 }
948 else
949 {
950
951 elog(ERROR, "unrecognized testexpr type: %d",
953 oplist = NIL;
954 }
956
957 lefttlist = righttlist = NIL;
965
966 cross_eq_funcoids = (Oid *) palloc(ncols * sizeof(Oid));
967
968 i = 1;
969 foreach(l, oplist)
970 {
974 Oid rhs_eq_oper;
975 Oid left_hashfn;
976 Oid right_hashfn;
977
979
980
983 i,
984 NULL,
985 false);
986 lefttlist = lappend(lefttlist, tle);
987
988
991 i,
992 NULL,
993 false);
994 righttlist = lappend(righttlist, tle);
995
996
997 cross_eq_funcoids[i - 1] = opexpr->opfuncid;
1000
1001
1003 NULL, &rhs_eq_oper))
1004 elog(ERROR, "could not find compatible hash operator for operator %u",
1005 opexpr->opno);
1007
1008
1010 &left_hashfn, &right_hashfn))
1011 elog(ERROR, "could not find hash function for hash operator %u",
1012 opexpr->opno);
1013 fmgr_info(left_hashfn, &lhs_hash_funcs[i - 1]);
1015
1016
1018
1019
1021
1022 i++;
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032
1036 NULL,
1037 slot,
1038 parent,
1039 NULL);
1040
1045 slot,
1047 NULL);
1048
1049
1052 lhs_hash_funcs,
1056 parent,
1057 0);
1058
1059
1060
1061
1062
1065 ncols,
1067 cross_eq_funcoids,
1069 parent);
1070 }
1071
1072 return sstate;
1073}
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099void
1101{
1110 bool found = false;
1112
1115 elog(ERROR, "ANY/ALL subselect unsupported as initplan");
1117 elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan");
1119 elog(ERROR, "correlated subplans should not be executed via ExecSetParamPlan");
1120
1121
1122
1123
1124
1126
1127
1131
1132
1133
1134
1136
1137
1138
1139
1140
1144 {
1146 int i = 1;
1147
1149 {
1150
1153
1156 prm->isnull = false;
1157 found = true;
1158 break;
1159 }
1160
1162 {
1164 bool disnull;
1165
1166 found = true;
1167
1172
1173 continue;
1174 }
1175
1176 if (found &&
1181 (errcode(ERRCODE_CARDINALITY_VIOLATION),
1182 errmsg("more than one row returned by a subquery used as an expression")));
1183
1184 found = true;
1185
1186
1187
1188
1189
1190
1191
1195
1196
1197
1198
1199 foreach(l, subplan->setParam)
1200 {
1203
1207 i++;
1208 }
1209 }
1210
1212 {
1213
1216
1217
1218
1219
1220
1221
1226 true);
1229 prm->isnull = false;
1230 }
1231 else if (!found)
1232 {
1234 {
1235
1238
1241 prm->isnull = false;
1242 }
1243 else
1244 {
1245
1246 foreach(l, subplan->setParam)
1247 {
1250
1254 }
1255 }
1256 }
1257
1259
1260
1262}
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275void
1277{
1278 int paramid;
1279
1280 paramid = -1;
1281 while ((paramid = bms_next_member(params, paramid)) >= 0)
1282 {
1284
1286 {
1287
1289
1291 }
1292 }
1293}
1294
1295
1296
1297
1298void
1300{
1305
1306
1308 elog(ERROR, "direct correlated subquery unsupported as initplan");
1310 elog(ERROR, "setParam list of initplan is empty");
1312 elog(ERROR, "extParam set of initplan is empty");
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326 foreach(l, subplan->setParam)
1327 {
1330
1333
1335 }
1336}
ArrayBuildStateAny * initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)
ArrayBuildStateAny * accumArrayResultAny(ArrayBuildStateAny *astate, Datum dvalue, bool disnull, Oid input_type, MemoryContext rcontext)
Datum makeArrayResultAny(ArrayBuildStateAny *astate, MemoryContext rcontext, bool release)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_add_member(Bitmapset *a, int x)
long clamp_cardinality_to_long(Cardinality x)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ExecReScan(PlanState *node)
ExprState * ExecBuildHash32FromAttrs(TupleDesc desc, const TupleTableSlotOps *ops, FmgrInfo *hashfunctions, Oid *collations, int numCols, AttrNumber *keyColIdx, PlanState *parent, uint32 init_value)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
ExprState * ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx, const Oid *eqfunctions, const Oid *collations, PlanState *parent)
TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew, uint32 *hash)
TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot, ExprState *eqcomp, ExprState *hashexpr)
TupleHashTable BuildTupleHashTable(PlanState *parent, TupleDesc inputDesc, const TupleTableSlotOps *inputOps, int numCols, AttrNumber *keyColIdx, const Oid *eqfuncoids, FmgrInfo *hashfunctions, Oid *collations, long nbuckets, Size additionalsize, MemoryContext metacxt, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)
void ResetTupleHashTable(TupleHashTable hashtable)
const TupleTableSlotOps TTSOpsVirtual
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
TupleDesc ExecTypeFromTL(List *targetList)
ExprContext * CreateExprContext(EState *estate)
#define ScanTupleHashTable(htable, iter)
#define TermTupleHashIterator(iter)
#define InitTupleHashIterator(htable, iter)
tuplehash_iterator TupleHashIterator
static MinimalTuple TupleHashEntryGetTuple(TupleHashEntry entry)
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
#define ResetExprContext(econtext)
static TupleTableSlot * ExecProcNode(PlanState *node)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define fmgr_info_set_expr(expr, finfo)
Assert(PointerIsAligned(start, uint64))
void heap_freetuple(HeapTuple htup)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
List * lappend(List *list, void *datum)
bool get_compatible_hash_operators(Oid opno, Oid *lhs_opno, Oid *rhs_opno)
RegProcedure get_opcode(Oid opno)
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SMALL_SIZES
#define CHECK_FOR_INTERRUPTS()
static bool is_andclause(const void *clause)
static Datum ExecHashSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull)
SubPlanState * ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
static void buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
static bool execTuplesUnequal(TupleTableSlot *slot1, TupleTableSlot *slot2, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, const Oid *collations, MemoryContext evalContext)
void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
static bool slotNoNulls(TupleTableSlot *slot)
static Datum ExecScanSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull)
void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
static bool slotAllNulls(TupleTableSlot *slot)
Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull)
static bool findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot, FmgrInfo *eqfunctions)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define lfirst_node(type, lc)
static int list_length(const List *l)
static void * list_nth(const List *list, int n)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Datum BoolGetDatum(bool X)
static Pointer DatumGetPointer(Datum X)
ParamExecData * es_param_exec_vals
MemoryContext es_query_cxt
ScanDirection es_direction
ParamExecData * ecxt_param_exec_vals
MemoryContext ecxt_per_query_memory
TupleTableSlot * resultslot
ExprContext * pi_exprContext
ExprState * lhs_hash_expr
MemoryContext hashtablecxt
ExprContext * innerecontext
FmgrInfo * tab_hash_funcs
MemoryContext hashtempcxt
struct PlanState * planstate
ProjectionInfo * projLeft
ProjectionInfo * projRight
struct PlanState * parent
TupleTableSlot * tableslot
TupleDesc tts_tupleDescriptor
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static HeapTuple ExecCopySlotHeapTuple(TupleTableSlot *slot)
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static bool slot_attisnull(TupleTableSlot *slot, int attnum)