PostgreSQL Source Code git master
Loading...
Searching...
No Matches
llvmjit_expr.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * llvmjit_expr.c
4 * JIT compile expressions.
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/jit/llvm/llvmjit_expr.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include <llvm-c/Core.h>
19#include <llvm-c/Target.h>
20
21#include "access/htup_details.h"
22#include "access/nbtree.h"
24#include "catalog/pg_type.h"
25#include "executor/execExpr.h"
26#include "executor/execdebug.h"
27#include "executor/nodeAgg.h"
29#include "funcapi.h"
30#include "jit/llvmjit.h"
31#include "jit/llvmjit_emit.h"
32#include "miscadmin.h"
33#include "nodes/makefuncs.h"
34#include "nodes/nodeFuncs.h"
35#include "parser/parse_coerce.h"
36#include "parser/parsetree.h"
37#include "pgstat.h"
38#include "utils/acl.h"
39#include "utils/builtins.h"
40#include "utils/date.h"
41#include "utils/fmgrtab.h"
42#include "utils/lsyscache.h"
43#include "utils/memutils.h"
44#include "utils/timestamp.h"
45#include "utils/typcache.h"
46#include "utils/xml.h"
47
53
54
55static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull);
56
61 const char *funcname,
63 ExprEvalStep *op,
64 int natts, LLVMValueRef *v_args);
65#if LLVM_VERSION_MAJOR < 22
67#endif
68
69/* macro making it easier to call ExecEval* functions */
70#define build_EvalXFunc(b, mod, funcname, v_state, op, ...) \
71 build_EvalXFuncInt(b, mod, funcname, v_state, op, \
72 lengthof(((LLVMValueRef[]){__VA_ARGS__})), \
73 ((LLVMValueRef[]){__VA_ARGS__}))
74
75
76/*
77 * JIT compile expression.
78 */
79bool
81{
82 PlanState *parent = state->parent;
83 char *funcname;
84
85 LLVMJitContext *context = NULL;
86
93
94 /* state itself */
98
99 /* returnvalue */
101
102 /* tmp vars in state */
105
106 /* slots */
113
114 /* nulls/values of slots */
127
128 /* stuff in econtext */
131
132 instr_time starttime;
136
138
139 /*
140 * Right now we don't support compiling expressions without a parent, as
141 * we need access to the EState.
142 */
143 Assert(parent);
144
145 /* get or create JIT context */
146 if (parent->state->es_jit)
147 context = (LLVMJitContext *) parent->state->es_jit;
148 else
149 {
150 context = llvm_create_context(parent->state->es_jit_flags);
151 parent->state->es_jit = &context->base;
152 }
153
154 INSTR_TIME_SET_CURRENT(starttime);
155
156 mod = llvm_mutable_module(context);
158
160
161 funcname = llvm_expand_funcname(context, "evalexpr");
162
163 /* create function */
165 llvm_pg_var_func_type("ExecInterpExprStillValid"));
169
170 entry = LLVMAppendBasicBlockInContext(lc, eval_fn, "entry");
171
172 /* build state */
176
178
181 v_state,
183 "v.state.resvalue");
186 v_state,
188 "v.state.resnull");
191 v_state,
193 "v.state.parent");
194
195 /* build global slots */
200 "v_scanslot");
205 "v_innerslot");
210 "v_outerslot");
215 "v_oldslot");
220 "v_newslot");
223 v_state,
225 "v_resultslot");
226
227 /* build global values/isnull pointers */
232 "v_scanvalues");
237 "v_scannulls");
242 "v_innervalues");
247 "v_innernulls");
252 "v_outervalues");
257 "v_outernulls");
260 v_oldslot,
262 "v_oldvalues");
265 v_oldslot,
267 "v_oldnulls");
270 v_newslot,
272 "v_newvalues");
275 v_newslot,
277 "v_newnulls");
282 "v_resultvalues");
287 "v_resultnulls");
288
289 /* aggvalues/aggnulls */
294 "v.econtext.aggvalues");
299 "v.econtext.aggnulls");
300
301 /* allocate blocks for each op upfront, so we can do jumps easily */
303 for (int opno = 0; opno < state->steps_len; opno++)
304 opblocks[opno] = l_bb_append_v(eval_fn, "b.op.%d.start", opno);
305
306 /* jump from entry to first block */
308
309 for (int opno = 0; opno < state->steps_len; opno++)
310 {
311 ExprEvalStep *op;
312 ExprEvalOp opcode;
315
317
318 op = &state->steps[opno];
319 opcode = ExecEvalStepOp(state, op);
320
323
324 switch (opcode)
325 {
326 case EEOP_DONE_RETURN:
327 {
330
333
335
337 break;
338 }
339
342 break;
343
349 {
350 TupleDesc desc = NULL;
355 const TupleTableSlotOps *tts_ops = NULL;
356
357 b_fetch = l_bb_before_v(opblocks[opno + 1],
358 "op.%d.fetch", opno);
359
360 if (op->d.fetch.known_desc)
361 desc = op->d.fetch.known_desc;
362
363 if (op->d.fetch.fixed)
364 tts_ops = op->d.fetch.kind;
365
366 /* step should not have been generated */
367 Assert(tts_ops != &TTSOpsVirtual);
368
369 if (opcode == EEOP_INNER_FETCHSOME)
371 else if (opcode == EEOP_OUTER_FETCHSOME)
373 else if (opcode == EEOP_SCAN_FETCHSOME)
375 else if (opcode == EEOP_OLD_FETCHSOME)
377 else
379
380 /*
381 * Check if all required attributes are available, or
382 * whether deforming is required.
383 */
384 v_nvalid =
387 v_slot,
389 "");
393 ""),
394 opblocks[opno + 1], b_fetch);
395
397
398 /*
399 * If the tupledesc of the to-be-deformed tuple is known,
400 * and JITing of deforming is enabled, build deform
401 * function specific to tupledesc and the exact number of
402 * to-be-extracted attributes.
403 */
404 if (tts_ops && desc && (context->base.flags & PGJIT_DEFORM))
405 {
408 slot_compile_deform(context, desc,
409 tts_ops,
410 op->d.fetch.last_var);
412 INSTR_TIME_ACCUM_DIFF(context->base.instr.deform_counter,
414 }
415
416 if (l_jit_deform)
417 {
418 LLVMValueRef params[1];
419
420 params[0] = v_slot;
421
422 l_call(b,
425 params, lengthof(params), "");
426 }
427 else
428 {
429 LLVMValueRef params[2];
430
431 params[0] = v_slot;
432 params[1] = l_int32_const(lc, op->d.fetch.last_var);
433
434 l_call(b,
435 llvm_pg_var_func_type("slot_getsomeattrs_int"),
436 llvm_pg_func(mod, "slot_getsomeattrs_int"),
437 params, lengthof(params), "");
438 }
439
440 LLVMBuildBr(b, opblocks[opno + 1]);
441 break;
442 }
443
444 case EEOP_INNER_VAR:
445 case EEOP_OUTER_VAR:
446 case EEOP_SCAN_VAR:
447 case EEOP_OLD_VAR:
448 case EEOP_NEW_VAR:
449 {
451 isnull;
455
456 if (opcode == EEOP_INNER_VAR)
457 {
460 }
461 else if (opcode == EEOP_OUTER_VAR)
462 {
465 }
466 else if (opcode == EEOP_SCAN_VAR)
467 {
470 }
471 else if (opcode == EEOP_OLD_VAR)
472 {
475 }
476 else
477 {
480 }
481
486 LLVMBuildStore(b, isnull, v_resnullp);
487
488 LLVMBuildBr(b, opblocks[opno + 1]);
489 break;
490 }
491
494 case EEOP_SCAN_SYSVAR:
495 case EEOP_OLD_SYSVAR:
496 case EEOP_NEW_SYSVAR:
497 {
499
500 if (opcode == EEOP_INNER_SYSVAR)
502 else if (opcode == EEOP_OUTER_SYSVAR)
504 else if (opcode == EEOP_SCAN_SYSVAR)
506 else if (opcode == EEOP_OLD_SYSVAR)
508 else
510
511 build_EvalXFunc(b, mod, "ExecEvalSysVar",
513
514 LLVMBuildBr(b, opblocks[opno + 1]);
515 break;
516 }
517
518 case EEOP_WHOLEROW:
519 build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
520 v_state, op, v_econtext);
521 LLVMBuildBr(b, opblocks[opno + 1]);
522 break;
523
529 {
538
539 if (opcode == EEOP_ASSIGN_INNER_VAR)
540 {
543 }
544 else if (opcode == EEOP_ASSIGN_OUTER_VAR)
545 {
548 }
549 else if (opcode == EEOP_ASSIGN_SCAN_VAR)
550 {
553 }
554 else if (opcode == EEOP_ASSIGN_OLD_VAR)
555 {
558 }
559 else
560 {
563 }
564
565 /* load data */
569
570 /* compute addresses of targets */
572 v_rvaluep = l_gep(b,
573 TypeDatum,
575 &v_resultnum, 1, "");
579 &v_resultnum, 1, "");
580
581 /* and store */
584
585 LLVMBuildBr(b, opblocks[opno + 1]);
586 break;
587 }
588
589 case EEOP_ASSIGN_TMP:
591 {
593 v_isnull;
597 size_t resultnum = op->d.assign_tmp.resultnum;
598
599 /* load data */
602
603 /* compute addresses of targets */
604 v_resultnum = l_int32_const(lc, resultnum);
605 v_rvaluep =
607 v_risnullp =
609
610 /* store nullness */
612
613 /* make value readonly if necessary */
614 if (opcode == EEOP_ASSIGN_TMP_MAKE_RO)
615 {
618
619 b_notnull = l_bb_before_v(opblocks[opno + 1],
620 "op.%d.assign_tmp.notnull", opno);
621
622 /* check if value is NULL */
625 l_sbool_const(0), ""),
626 b_notnull, opblocks[opno + 1]);
627
628 /* if value is not null, convert to RO datum */
630 v_params[0] = v_value;
631 v_value =
632 l_call(b,
633 llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
634 llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
636
637 /*
638 * Falling out of the if () with builder in b_notnull,
639 * which is fine - the null is already stored above.
640 */
641 }
642
643 /* and finally store result */
645
646 LLVMBuildBr(b, opblocks[opno + 1]);
647 break;
648 }
649
650 case EEOP_CONST:
651 {
654
657
660
661 LLVMBuildBr(b, opblocks[opno + 1]);
662 break;
663 }
664
665 case EEOP_FUNCEXPR:
669 {
670 FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
673
674 if (opcode == EEOP_FUNCEXPR_STRICT ||
675 opcode == EEOP_FUNCEXPR_STRICT_1 ||
676 opcode == EEOP_FUNCEXPR_STRICT_2)
677 {
681
682 /*
683 * Block for the actual function call, if args are
684 * non-NULL.
685 */
686 b_nonull = l_bb_before_v(opblocks[opno + 1],
687 "b.%d.no-null-args", opno);
688
689 /* should make sure they're optimized beforehand */
690 if (op->d.func.nargs == 0)
691 elog(ERROR, "argumentless strict functions are pointless");
692
693 v_fcinfo =
695
696 /*
697 * set resnull to true, if the function is actually
698 * called, it'll be reset
699 */
701
702 /* create blocks for checking args, one for each */
704 palloc(sizeof(LLVMBasicBlockRef) * op->d.func.nargs);
705 for (int argno = 0; argno < op->d.func.nargs; argno++)
707 l_bb_before_v(b_nonull, "b.%d.isnull.%d", opno,
708 argno);
709
710 /* jump to check of first argument */
712
713 /* check each arg for NULLness */
714 for (int argno = 0; argno < op->d.func.nargs; argno++)
715 {
718
720
721 /*
722 * Compute block to jump to if argument is not
723 * null.
724 */
725 if (argno + 1 == op->d.func.nargs)
727 else
729
730 /* and finally load & check NULLness of arg */
735 l_sbool_const(1),
736 ""),
737 opblocks[opno + 1],
739 }
740
742 }
743
744 v_retval = BuildV1Call(context, b, mod, fcinfo,
748
749 LLVMBuildBr(b, opblocks[opno + 1]);
750 break;
751 }
752
754 build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
755 v_state, op, v_econtext);
756 LLVMBuildBr(b, opblocks[opno + 1]);
757 break;
758
759
761 build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
762 v_state, op, v_econtext);
763 LLVMBuildBr(b, opblocks[opno + 1]);
764 break;
765
766 /*
767 * Treat them the same for now, optimizer can remove
768 * redundancy. Could be worthwhile to optimize during emission
769 * though.
770 */
774 {
784
786 "b.%d.boolisnull", opno);
788 "b.%d.boolcheckfalse", opno);
790 "b.%d.boolisfalse", opno);
792 "b.%d.boolisanynull", opno);
794 "b.%d.boolcont", opno);
795
798
799 if (opcode == EEOP_BOOL_AND_STEP_FIRST)
801
804
805 /* check if current input is NULL */
808 l_sbool_const(1), ""),
811
812 /* build block that sets anynull */
814 /* set boolanynull to true */
816 /* and jump to next block */
818
819 /* build block checking for false */
823 l_datum_const(0), ""),
825 b_boolcont);
826
827 /*
828 * Build block handling FALSE. Value is false, so short
829 * circuit.
830 */
832 /* result is already set to FALSE, need not change it */
833 /* and jump to the end of the AND expression */
835
836 /* Build block that continues if bool is TRUE. */
838
840
841 /* set value to NULL if any previous values were NULL */
844 l_sbool_const(0), ""),
845 opblocks[opno + 1], b_boolisanynull);
846
848 /* set resnull to true */
850 /* reset resvalue */
852
853 LLVMBuildBr(b, opblocks[opno + 1]);
854 break;
855 }
856
857 /*
858 * Treat them the same for now, optimizer can remove
859 * redundancy. Could be worthwhile to optimize during emission
860 * though.
861 */
865 {
870
876
878 "b.%d.boolisnull", opno);
880 "b.%d.boolchecktrue", opno);
882 "b.%d.boolistrue", opno);
884 "b.%d.boolisanynull", opno);
886 "b.%d.boolcont", opno);
887
890
891 if (opcode == EEOP_BOOL_OR_STEP_FIRST)
895
898 l_sbool_const(1), ""),
901
902 /* build block that sets anynull */
904 /* set boolanynull to true */
906 /* and jump to next block */
908
909 /* build block checking for true */
913 l_datum_const(1), ""),
915 b_boolcont);
916
917 /*
918 * Build block handling True. Value is true, so short
919 * circuit.
920 */
922 /* result is already set to TRUE, need not change it */
923 /* and jump to the end of the OR expression */
925
926 /* build block that continues if bool is FALSE */
928
930
931 /* set value to NULL if any previous values were NULL */
934 l_sbool_const(0), ""),
935 opblocks[opno + 1], b_boolisanynull);
936
938 /* set resnull to true */
940 /* reset resvalue */
942
943 LLVMBuildBr(b, opblocks[opno + 1]);
944 break;
945 }
946
948 {
951
952 /* compute !boolvalue */
957 l_datum_const(0),
958 ""),
959 TypeDatum, "");
960
961 /*
962 * Store it back in resvalue. We can ignore resnull here;
963 * if it was true, it stays true, and the value we store
964 * in resvalue doesn't matter.
965 */
967
968 LLVMBuildBr(b, opblocks[opno + 1]);
969 break;
970 }
971
972 case EEOP_QUAL:
973 {
978
980 "op.%d.qualfail", opno);
981
984
988 l_sbool_const(1), ""),
990 l_datum_const(0), ""),
991 "");
992
996 opblocks[opno + 1]);
997
998 /* build block handling NULL or false */
1000 /* set resnull to false */
1002 /* set resvalue to false */
1004 /* and jump out */
1006 break;
1007 }
1008
1009 case EEOP_JUMP:
1010 {
1012 break;
1013 }
1014
1015 case EEOP_JUMP_IF_NULL:
1016 {
1018
1019 /* Transfer control if current result is null */
1020
1022
1025 l_sbool_const(1), ""),
1026 opblocks[op->d.jump.jumpdone],
1027 opblocks[opno + 1]);
1028 break;
1029 }
1030
1032 {
1034
1035 /* Transfer control if current result is non-null */
1036
1038
1041 l_sbool_const(0), ""),
1042 opblocks[op->d.jump.jumpdone],
1043 opblocks[opno + 1]);
1044 break;
1045 }
1046
1047
1049 {
1053
1054 /* Transfer control if current result is null or false */
1055
1058
1060 LLVMBuildOr(b,
1062 l_sbool_const(1), ""),
1064 l_datum_const(0), ""),
1065 "");
1066
1069 opblocks[op->d.jump.jumpdone],
1070 opblocks[opno + 1]);
1071 break;
1072 }
1073
1075 {
1078
1079 v_resvalue =
1082 l_sbool_const(1), ""),
1083 l_datum_const(1),
1084 l_datum_const(0),
1085 "");
1088
1089 LLVMBuildBr(b, opblocks[opno + 1]);
1090 break;
1091 }
1092
1094 {
1097
1098 v_resvalue =
1101 l_sbool_const(1), ""),
1102 l_datum_const(0),
1103 l_datum_const(1),
1104 "");
1107
1108 LLVMBuildBr(b, opblocks[opno + 1]);
1109 break;
1110 }
1111
1113 build_EvalXFunc(b, mod, "ExecEvalRowNull",
1114 v_state, op, v_econtext);
1115 LLVMBuildBr(b, opblocks[opno + 1]);
1116 break;
1117
1119 build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
1120 v_state, op, v_econtext);
1121 LLVMBuildBr(b, opblocks[opno + 1]);
1122 break;
1123
1128 {
1130 b_notnull;
1132
1133 b_isnull = l_bb_before_v(opblocks[opno + 1],
1134 "op.%d.isnull", opno);
1135 b_notnull = l_bb_before_v(opblocks[opno + 1],
1136 "op.%d.isnotnull", opno);
1137
1138 /* check if value is NULL */
1141 l_sbool_const(1), ""),
1143
1144 /* if value is NULL, return false */
1146
1147 /* result is not null */
1149
1150 if (opcode == EEOP_BOOLTEST_IS_TRUE ||
1151 opcode == EEOP_BOOLTEST_IS_FALSE)
1152 {
1154 }
1155 else
1156 {
1158 }
1159
1160 LLVMBuildBr(b, opblocks[opno + 1]);
1161
1163
1164 if (opcode == EEOP_BOOLTEST_IS_TRUE ||
1166 {
1167 /*
1168 * if value is not null NULL, return value (already
1169 * set)
1170 */
1171 }
1172 else
1173 {
1176
1179 v_value,
1180 l_datum_const(0),
1181 ""),
1182 TypeDatum, "");
1184 }
1185 LLVMBuildBr(b, opblocks[opno + 1]);
1186 break;
1187 }
1188
1189 case EEOP_PARAM_EXEC:
1190 build_EvalXFunc(b, mod, "ExecEvalParamExec",
1191 v_state, op, v_econtext);
1192 LLVMBuildBr(b, opblocks[opno + 1]);
1193 break;
1194
1195 case EEOP_PARAM_EXTERN:
1196 build_EvalXFunc(b, mod, "ExecEvalParamExtern",
1197 v_state, op, v_econtext);
1198 LLVMBuildBr(b, opblocks[opno + 1]);
1199 break;
1200
1202 {
1205
1207 llvm_pg_var_type("TypeExecEvalSubroutine"));
1208
1209 v_params[0] = v_state;
1211 v_params[2] = v_econtext;
1212 l_call(b,
1214 v_func,
1215 v_params, lengthof(v_params), "");
1216
1217 LLVMBuildBr(b, opblocks[opno + 1]);
1218 break;
1219 }
1220
1221 case EEOP_PARAM_SET:
1222 build_EvalXFunc(b, mod, "ExecEvalParamSet",
1223 v_state, op, v_econtext);
1224 LLVMBuildBr(b, opblocks[opno + 1]);
1225 break;
1226
1228 {
1229 int jumpdone = op->d.sbsref_subscript.jumpdone;
1233
1235 llvm_pg_var_type("TypeExecEvalBoolSubroutine"));
1236
1237 v_params[0] = v_state;
1239 v_params[2] = v_econtext;
1240 v_ret = l_call(b,
1242 v_func,
1243 v_params, lengthof(v_params), "");
1245
1248 l_sbool_const(1), ""),
1249 opblocks[opno + 1],
1250 opblocks[jumpdone]);
1251 break;
1252 }
1253
1254 case EEOP_SBSREF_OLD:
1255 case EEOP_SBSREF_ASSIGN:
1256 case EEOP_SBSREF_FETCH:
1257 {
1260
1262 llvm_pg_var_type("TypeExecEvalSubroutine"));
1263
1264 v_params[0] = v_state;
1266 v_params[2] = v_econtext;
1267 l_call(b,
1269 v_func,
1270 v_params, lengthof(v_params), "");
1271
1272 LLVMBuildBr(b, opblocks[opno + 1]);
1273 break;
1274 }
1275
1276 case EEOP_CASE_TESTVAL:
1277 {
1281 v_casenull;
1282
1284 l_ptr(TypeDatum));
1287
1292
1293 LLVMBuildBr(b, opblocks[opno + 1]);
1294 break;
1295 }
1296
1298 {
1301
1302 v_casevalue =
1305 v_econtext,
1307 v_casenull =
1310 v_econtext,
1314
1315 LLVMBuildBr(b, opblocks[opno + 1]);
1316 break;
1317 }
1318
1319 case EEOP_MAKE_READONLY:
1320 {
1328
1329 b_notnull = l_bb_before_v(opblocks[opno + 1],
1330 "op.%d.readonly.notnull", opno);
1331
1334
1336
1337 /* store null isnull value in result */
1339
1340 /* check if value is NULL */
1343 l_sbool_const(1), ""),
1344 opblocks[opno + 1], b_notnull);
1345
1346 /* if value is not null, convert to RO datum */
1348
1350 l_ptr(TypeDatum));
1351
1353
1354 v_params[0] = v_value;
1355 v_ret =
1356 l_call(b,
1357 llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
1358 llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
1359 v_params, lengthof(v_params), "");
1361
1362 LLVMBuildBr(b, opblocks[opno + 1]);
1363 break;
1364 }
1365
1366 case EEOP_IOCOERCE:
1367 {
1369 fcinfo_in;
1371 v_fn_in;
1378
1381
1386
1389
1391 "op.%d.skipoutputnull", opno);
1393 "op.%d.calloutput", opno);
1394 b_input = l_bb_before_v(opblocks[opno + 1],
1395 "op.%d.input", opno);
1397 "op.%d.inputcall", opno);
1398
1403
1409 "v_fcinfo_in_isnull");
1410
1411 /* output functions are not called on nulls */
1415 l_sbool_const(1), ""),
1417 b_calloutput);
1418
1422
1425
1426 /* set arg[0] */
1428 v_resvalue,
1431 l_sbool_const(0),
1433 /* and call output function (can never return NULL) */
1434 v_output = l_call(b,
1437 1, "funccall_coerce_out");
1439
1440 /* build block handling input function call */
1442
1443 /* phi between resnull and output function call branches */
1444 {
1447
1450
1453
1454 v_output = LLVMBuildPhi(b, TypeDatum, "output");
1458 }
1459
1460 /*
1461 * If input function is strict, skip if input string is
1462 * NULL.
1463 */
1464 if (op->d.iocoerce.finfo_in->fn_strict)
1465 {
1468 l_datum_const(0), ""),
1469 opblocks[opno + 1],
1470 b_inputcall);
1471 }
1472 else
1473 {
1475 }
1476
1478 /* set arguments */
1479 /* arg0: output */
1484
1485 /* arg1: ioparam: preset in execExpr.c */
1486 /* arg2: typmod: preset in execExpr.c */
1487
1488 /* reset fcinfo_in->isnull */
1490 /* and call function */
1491 v_retval = l_call(b,
1493 v_fn_in, &v_fcinfo_in, 1,
1494 "funccall_iocoerce_in");
1495
1497
1498 LLVMBuildBr(b, opblocks[opno + 1]);
1499 break;
1500 }
1501
1502 case EEOP_IOCOERCE_SAFE:
1503 build_EvalXFunc(b, mod, "ExecEvalCoerceViaIOSafe",
1504 v_state, op);
1505 LLVMBuildBr(b, opblocks[opno + 1]);
1506 break;
1507
1508 case EEOP_DISTINCT:
1509 case EEOP_NOT_DISTINCT:
1510 {
1511 FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1512
1515
1520
1523
1525
1530
1531 b_noargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.noargnull", opno);
1532 b_checkbothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.checkbothargnull", opno);
1533 b_bothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.bothargnull", opno);
1534 b_anyargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.anyargnull", opno);
1535
1537
1538 /* load args[0|1].isnull for both arguments */
1541 l_sbool_const(1), "");
1544 l_sbool_const(1), "");
1545
1548
1549 /*
1550 * Check function arguments for NULLness: If either is
1551 * NULL, we check if both args are NULL. Otherwise call
1552 * comparator.
1553 */
1555 b_noargnull);
1556
1557 /*
1558 * build block checking if any arg is null
1559 */
1562 b_anyargnull);
1563
1564
1565 /* Both NULL? Then is not distinct... */
1568 if (opcode == EEOP_NOT_DISTINCT)
1570 else
1572
1573 LLVMBuildBr(b, opblocks[opno + 1]);
1574
1575 /* Only one is NULL? Then is distinct... */
1578 if (opcode == EEOP_NOT_DISTINCT)
1580 else
1582 LLVMBuildBr(b, opblocks[opno + 1]);
1583
1584 /* neither argument is null: compare */
1586
1587 v_result = BuildV1Call(context, b, mod, fcinfo,
1589
1590 if (opcode == EEOP_DISTINCT)
1591 {
1592 /* Must invert result of "=" */
1593 v_result =
1596 v_result,
1597 l_datum_const(0), ""),
1598 TypeDatum, "");
1599 }
1600
1603
1604 LLVMBuildBr(b, opblocks[opno + 1]);
1605 break;
1606 }
1607
1608 case EEOP_NULLIF:
1609 {
1610 FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1611
1623
1624 b_hasnull = l_bb_before_v(opblocks[opno + 1],
1625 "b.%d.null-args", opno);
1626 b_nonull = l_bb_before_v(opblocks[opno + 1],
1627 "b.%d.no-null-args", opno);
1629 "b.%d.argsequal", opno);
1630
1632
1633 /* save original arg[0] */
1635
1636 /* if either argument is NULL they can't be equal */
1639
1641 LLVMBuildOr(b,
1643 l_sbool_const(1), ""),
1645 l_sbool_const(1), ""),
1646 "");
1647
1649
1650 /* one (or both) of the arguments are null, return arg[0] */
1654 LLVMBuildBr(b, opblocks[opno + 1]);
1655
1656 /* build block to invoke function and check result */
1658
1659 /*
1660 * If first argument is of varlena type, it might be an
1661 * expanded datum. We need to ensure that the value
1662 * passed to the comparison function is a read-only
1663 * pointer. However, if we end by returning the first
1664 * argument, that will be the original read-write pointer
1665 * if it was read-write.
1666 */
1667 if (op->d.func.make_ro)
1668 {
1671
1672 v_params[0] = v_arg0;
1673 v_arg0_ro =
1674 l_call(b,
1675 llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
1676 llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
1677 v_params, lengthof(v_params), "");
1679 l_funcvaluep(b, v_fcinfo, 0));
1680 }
1681
1682 v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull);
1683
1684 /*
1685 * If result not null and arguments are equal return null,
1686 * else return arg[0] (same result as if there'd been
1687 * NULLs, hence reuse b_hasnull).
1688 */
1692 l_sbool_const(0),
1693 ""),
1695 v_retval,
1696 l_datum_const(1),
1697 ""),
1698 "");
1700
1701 /* build block setting result to NULL, if args are equal */
1705
1706 LLVMBuildBr(b, opblocks[opno + 1]);
1707 break;
1708 }
1709
1711 build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
1712 v_state, op);
1713 LLVMBuildBr(b, opblocks[opno + 1]);
1714 break;
1715
1716 case EEOP_CURRENTOFEXPR:
1717 build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
1718 v_state, op);
1719 LLVMBuildBr(b, opblocks[opno + 1]);
1720 break;
1721
1722 case EEOP_NEXTVALUEEXPR:
1723 build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
1724 v_state, op);
1725 LLVMBuildBr(b, opblocks[opno + 1]);
1726 break;
1727
1728 case EEOP_RETURNINGEXPR:
1729 {
1734
1735 b_isnull = l_bb_before_v(opblocks[opno + 1],
1736 "op.%d.row.isnull", opno);
1737
1738 /*
1739 * The next op actually evaluates the expression. If the
1740 * OLD/NEW row doesn't exist, skip that and return NULL.
1741 */
1744 v_state,
1746 "v.state.flags");
1748
1750
1754 v_nullflag, ""),
1755 l_sbool_const(0), ""),
1756 opblocks[opno + 1], b_isnull);
1757
1759
1762
1764 break;
1765 }
1766
1767 case EEOP_ARRAYEXPR:
1768 build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
1769 v_state, op);
1770 LLVMBuildBr(b, opblocks[opno + 1]);
1771 break;
1772
1773 case EEOP_ARRAYCOERCE:
1774 build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
1775 v_state, op, v_econtext);
1776 LLVMBuildBr(b, opblocks[opno + 1]);
1777 break;
1778
1779 case EEOP_ROW:
1780 build_EvalXFunc(b, mod, "ExecEvalRow",
1781 v_state, op);
1782 LLVMBuildBr(b, opblocks[opno + 1]);
1783 break;
1784
1786 {
1792
1794
1795 b_null = l_bb_before_v(opblocks[opno + 1],
1796 "op.%d.row-null", opno);
1797 b_compare = l_bb_before_v(opblocks[opno + 1],
1798 "op.%d.row-compare", opno);
1800 l_bb_before_v(opblocks[opno + 1],
1801 "op.%d.row-compare-result",
1802 opno);
1803
1804 /*
1805 * If function is strict, and either arg is null, we're
1806 * done.
1807 */
1809 {
1814
1815 v_fcinfo = l_ptr_const(fcinfo,
1817
1820
1822 LLVMBuildOr(b,
1824 LLVMIntEQ,
1825 v_argnull0,
1826 l_sbool_const(1),
1827 ""),
1829 v_argnull1,
1830 l_sbool_const(1), ""),
1831 "");
1832
1834 }
1835 else
1836 {
1838 }
1839
1840 /* build block invoking comparison function */
1842
1843 /* call function */
1844 v_retval = BuildV1Call(context, b, mod, fcinfo,
1847
1848 /* if result of function is NULL, force NULL result */
1851 LLVMIntEQ,
1853 l_sbool_const(0),
1854 ""),
1856 b_null);
1857
1858 /* build block analyzing the !NULL comparator result */
1860
1861 /* if results equal, compare next, otherwise done */
1864 LLVMIntEQ,
1865 v_retval,
1866 l_datum_const(0), ""),
1867 opblocks[opno + 1],
1869
1870 /*
1871 * Build block handling NULL input or NULL comparator
1872 * result.
1873 */
1877
1878 break;
1879 }
1880
1882 {
1883 CompareType cmptype = op->d.rowcompare_final.cmptype;
1884
1888
1889 /*
1890 * Btree comparators return 32 bit results, need to be
1891 * careful about sign (used as a 64 bit value it's
1892 * otherwise wrong).
1893 */
1894 v_cmpresult =
1898
1899 switch (cmptype)
1900 {
1901 case COMPARE_LT:
1903 break;
1904 case COMPARE_LE:
1906 break;
1907 case COMPARE_GT:
1909 break;
1910 case COMPARE_GE:
1912 break;
1913 default:
1914 /* EQ and NE cases aren't allowed here */
1915 Assert(false);
1916 predicate = 0; /* prevent compiler warning */
1917 break;
1918 }
1919
1921 predicate,
1923 l_int32_const(lc, 0),
1924 "");
1926
1929
1930 LLVMBuildBr(b, opblocks[opno + 1]);
1931 break;
1932 }
1933
1934 case EEOP_MINMAX:
1935 build_EvalXFunc(b, mod, "ExecEvalMinMax",
1936 v_state, op);
1937 LLVMBuildBr(b, opblocks[opno + 1]);
1938 break;
1939
1940 case EEOP_FIELDSELECT:
1941 build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
1942 v_state, op, v_econtext);
1943 LLVMBuildBr(b, opblocks[opno + 1]);
1944 break;
1945
1947 build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
1948 v_state, op, v_econtext);
1949 LLVMBuildBr(b, opblocks[opno + 1]);
1950 break;
1951
1953 build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
1954 v_state, op, v_econtext);
1955 LLVMBuildBr(b, opblocks[opno + 1]);
1956 break;
1957
1959 {
1963 v_casenull;
1964
1966 l_ptr(TypeDatum));
1969
1974
1975 LLVMBuildBr(b, opblocks[opno + 1]);
1976 break;
1977 }
1978
1980 {
1983
1984 v_casevalue =
1987 v_econtext,
1989 "");
1990 v_casenull =
1993 v_econtext,
1995 "");
1998
1999 LLVMBuildBr(b, opblocks[opno + 1]);
2000 break;
2001 }
2002
2004 build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
2005 v_state, op);
2006 LLVMBuildBr(b, opblocks[opno + 1]);
2007 break;
2008
2009 case EEOP_DOMAIN_CHECK:
2010 build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
2011 v_state, op);
2012 LLVMBuildBr(b, opblocks[opno + 1]);
2013 break;
2014
2016 {
2018
2020
2023 LLVMBuildBr(b, opblocks[opno + 1]);
2024 break;
2025 }
2026
2031 {
2041
2042 /*
2043 * When performing the next hash and not in strict mode we
2044 * perform a rotation of the previously stored hash value
2045 * before doing the NULL check. We want to do this even
2046 * when we receive a NULL Datum to hash. In strict mode,
2047 * we do this after the NULL check so as not to waste the
2048 * effort of rotating the bits when we're going to throw
2049 * away the hash value and return NULL.
2050 */
2051 if (opcode == EEOP_HASHDATUM_NEXT32)
2052 {
2055 LLVMValueRef tmp;
2056
2057 tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
2058 l_ptr(TypeDatum));
2059
2060 /*
2061 * Fetch the previously hashed value from where the
2062 * previous hash operation stored it.
2063 */
2064 v_prevhash = l_load(b, TypeDatum, tmp, "prevhash");
2065
2066 /*
2067 * Rotate bits left by 1 bit. Be careful not to
2068 * overflow uint32 when working with Datum.
2069 */
2071 "");
2073 l_datum_const(0xffffffff), "");
2075 l_datum_const(31), "");
2077 "rotatedhash");
2078 }
2079
2080 /*
2081 * Block for the actual function call, if args are
2082 * non-NULL.
2083 */
2085 "b.%d.ifnotnull",
2086 opno);
2087
2088 /* we expect the hash function to have 1 argument */
2089 if (fcinfo->nargs != 1)
2090 elog(ERROR, "incorrect number of function arguments");
2091
2092 v_fcinfo = l_ptr_const(fcinfo,
2094
2096 "b.%d.isnull.0", opno);
2097
2099
2100 /*
2101 * Determine what to do if we find the argument to be
2102 * NULL.
2103 */
2104 if (opcode == EEOP_HASHDATUM_FIRST_STRICT ||
2106 {
2108 "b.%d.strictnull",
2109 opno);
2110
2112
2113 /*
2114 * In strict node, NULL inputs result in NULL. Save
2115 * the NULL result and goto jumpdone.
2116 */
2120 }
2121 else
2122 {
2124 "b.%d.null",
2125 opno);
2126
2128
2129
2131
2132 if (opcode == EEOP_HASHDATUM_NEXT32)
2133 {
2135
2136 /*
2137 * Save the rotated hash value and skip to the
2138 * next op.
2139 */
2141 }
2142 else
2143 {
2144 Assert(opcode == EEOP_HASHDATUM_FIRST);
2145
2146 /*
2147 * Store a zero Datum when the Datum to hash is
2148 * NULL
2149 */
2151 }
2152
2153 LLVMBuildBr(b, opblocks[opno + 1]);
2154 }
2155
2157
2158 /* emit code to check if the input parameter is NULL */
2162 LLVMIntEQ,
2164 l_sbool_const(1),
2165 ""),
2167 b_ifnotnull);
2168
2170
2171 /*
2172 * Rotate the previously stored hash value when performing
2173 * NEXT32 in strict mode. In non-strict mode we already
2174 * did this before checking for NULLs.
2175 */
2176 if (opcode == EEOP_HASHDATUM_NEXT32_STRICT)
2177 {
2180 LLVMValueRef tmp;
2181
2182 tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
2183 l_ptr(TypeDatum));
2184
2185 /*
2186 * Fetch the previously hashed value from where the
2187 * previous hash operation stored it.
2188 */
2189 v_prevhash = l_load(b, TypeDatum, tmp, "prevhash");
2190
2191 /*
2192 * Rotate bits left by 1 bit. Be careful not to
2193 * overflow uint32 when working with Datum.
2194 */
2196 "");
2198 l_datum_const(0xffffffff), "");
2200 l_datum_const(31), "");
2202 "rotatedhash");
2203 }
2204
2205 /* call the hash function */
2206 v_retval = BuildV1Call(context, b, mod, fcinfo,
2208
2209 /*
2210 * For NEXT32 ops, XOR (^) the returned hash value with
2211 * the existing hash value.
2212 */
2213 if (opcode == EEOP_HASHDATUM_NEXT32 ||
2216 "xorhash");
2217
2220
2221 LLVMBuildBr(b, opblocks[opno + 1]);
2222 break;
2223 }
2224
2226 build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
2227 v_state, op, v_econtext);
2228 LLVMBuildBr(b, opblocks[opno + 1]);
2229 break;
2230
2231 case EEOP_SCALARARRAYOP:
2232 build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
2233 v_state, op);
2234 LLVMBuildBr(b, opblocks[opno + 1]);
2235 break;
2236
2238 build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp",
2239 v_state, op, v_econtext);
2240 LLVMBuildBr(b, opblocks[opno + 1]);
2241 break;
2242
2243 case EEOP_XMLEXPR:
2244 build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
2245 v_state, op);
2246 LLVMBuildBr(b, opblocks[opno + 1]);
2247 break;
2248
2250 build_EvalXFunc(b, mod, "ExecEvalJsonConstructor",
2251 v_state, op, v_econtext);
2252 LLVMBuildBr(b, opblocks[opno + 1]);
2253 break;
2254
2255 case EEOP_IS_JSON:
2256 build_EvalXFunc(b, mod, "ExecEvalJsonIsPredicate",
2257 v_state, op);
2258 LLVMBuildBr(b, opblocks[opno + 1]);
2259 break;
2260
2261 case EEOP_JSONEXPR_PATH:
2262 {
2263 JsonExprState *jsestate = op->d.jsonexpr.jsestate;
2265
2266 /*
2267 * Call ExecEvalJsonExprPath(). It returns the address of
2268 * the step to perform next.
2269 */
2270 v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExprPath",
2271 v_state, op, v_econtext);
2272
2273 /*
2274 * Build a switch to map the return value (v_ret above),
2275 * which is a runtime value of the step address to perform
2276 * next, to either jump_empty, jump_error,
2277 * jump_eval_coercion, or jump_end.
2278 */
2279 if (jsestate->jump_empty >= 0 ||
2280 jsestate->jump_error >= 0 ||
2281 jsestate->jump_eval_coercion >= 0)
2282 {
2288 b_empty,
2289 b_error,
2290 b_coercion;
2291
2292 b_empty =
2293 l_bb_before_v(opblocks[opno + 1],
2294 "op.%d.jsonexpr_empty", opno);
2295 b_error =
2296 l_bb_before_v(opblocks[opno + 1],
2297 "op.%d.jsonexpr_error", opno);
2298 b_coercion =
2299 l_bb_before_v(opblocks[opno + 1],
2300 "op.%d.jsonexpr_coercion", opno);
2301 b_done =
2302 l_bb_before_v(opblocks[opno + 1],
2303 "op.%d.jsonexpr_done", opno);
2304
2306 v_ret,
2307 b_done,
2308 3);
2309 /* Returned jsestate->jump_empty? */
2310 if (jsestate->jump_empty >= 0)
2311 {
2314 }
2315 /* ON EMPTY code */
2317 if (jsestate->jump_empty >= 0)
2318 LLVMBuildBr(b, opblocks[jsestate->jump_empty]);
2319 else
2321
2322 /* Returned jsestate->jump_error? */
2323 if (jsestate->jump_error >= 0)
2324 {
2327 }
2328 /* ON ERROR code */
2330 if (jsestate->jump_error >= 0)
2331 LLVMBuildBr(b, opblocks[jsestate->jump_error]);
2332 else
2334
2335 /* Returned jsestate->jump_eval_coercion? */
2336 if (jsestate->jump_eval_coercion >= 0)
2337 {
2340 }
2341 /* jump_eval_coercion code */
2343 if (jsestate->jump_eval_coercion >= 0)
2345 else
2347
2349 }
2350
2351 LLVMBuildBr(b, opblocks[jsestate->jump_end]);
2352 break;
2353 }
2354
2356 build_EvalXFunc(b, mod, "ExecEvalJsonCoercion",
2357 v_state, op, v_econtext);
2358
2359 LLVMBuildBr(b, opblocks[opno + 1]);
2360 break;
2361
2363 build_EvalXFunc(b, mod, "ExecEvalJsonCoercionFinish",
2364 v_state, op);
2365
2366 LLVMBuildBr(b, opblocks[opno + 1]);
2367 break;
2368
2369 case EEOP_AGGREF:
2370 {
2373 isnull;
2374
2376
2377 /* load agg value / null */
2378 value = l_load_gep1(b, TypeDatum, v_aggvalues, v_aggno, "aggvalue");
2379 isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
2380
2381 /* and store result */
2383 LLVMBuildStore(b, isnull, v_resnullp);
2384
2385 LLVMBuildBr(b, opblocks[opno + 1]);
2386 break;
2387 }
2388
2389 case EEOP_GROUPING_FUNC:
2390 build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
2391 v_state, op);
2392 LLVMBuildBr(b, opblocks[opno + 1]);
2393 break;
2394
2395 case EEOP_WINDOW_FUNC:
2396 {
2401 isnull;
2402
2403 /*
2404 * At this point aggref->wfuncno is not yet set (it's set
2405 * up in ExecInitWindowAgg() after initializing the
2406 * expression). So load it from memory each time round.
2407 */
2408 v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
2411
2412 /* load window func value / null */
2414 "windowvalue");
2416 "windownull");
2417
2419 LLVMBuildStore(b, isnull, v_resnullp);
2420
2421 LLVMBuildBr(b, opblocks[opno + 1]);
2422 break;
2423 }
2424
2426 build_EvalXFunc(b, mod, "ExecEvalMergeSupportFunc",
2427 v_state, op, v_econtext);
2428 LLVMBuildBr(b, opblocks[opno + 1]);
2429 break;
2430
2431 case EEOP_SUBPLAN:
2432 build_EvalXFunc(b, mod, "ExecEvalSubPlan",
2433 v_state, op, v_econtext);
2434 LLVMBuildBr(b, opblocks[opno + 1]);
2435 break;
2436
2439 {
2442
2447
2448 if (opcode == EEOP_AGG_STRICT_DESERIALIZE)
2449 {
2453
2455 "op.%d.deserialize", opno);
2456
2457 v_fcinfo = l_ptr_const(fcinfo,
2460
2463 LLVMIntEQ,
2464 v_argnull0,
2465 l_sbool_const(1),
2466 ""),
2470 }
2471
2472 aggstate = castNode(AggState, state->parent);
2473 fcinfo = op->d.agg_deserialize.fcinfo_data;
2474
2475 v_tmpcontext =
2476 l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2479 v_retval = BuildV1Call(context, b, mod, fcinfo,
2482
2485
2486 LLVMBuildBr(b, opblocks[opno + 1]);
2487 break;
2488 }
2489
2493 {
2494 int nargs = op->d.agg_strict_input_check.nargs;
2496 bool *nulls = op->d.agg_strict_input_check.nulls;
2497 int jumpnull;
2498
2502
2503 Assert(nargs > 0);
2504
2505 jumpnull = op->d.agg_strict_input_check.jumpnull;
2508
2509 /* create blocks for checking args */
2511 for (int argno = 0; argno < nargs; argno++)
2512 {
2514 l_bb_before_v(opblocks[opno + 1],
2515 "op.%d.check-null.%d",
2516 opno, argno);
2517 }
2518
2520
2521 /* strict function, check for NULL args */
2522 for (int argno = 0; argno < nargs; argno++)
2523 {
2527
2529
2530 if (argno + 1 == nargs)
2531 b_argnotnull = opblocks[opno + 1];
2532 else
2534
2537 else
2538 {
2540
2542 v_argisnull =
2545 "");
2546 }
2547
2550 LLVMIntEQ,
2552 l_sbool_const(1), ""),
2553 opblocks[jumpnull],
2554 b_argnotnull);
2555 }
2556
2557 break;
2558 }
2559
2561 {
2562 int jumpnull;
2567
2569
2570 /*
2571 * pergroup_allaggs = aggstate->all_pergroups
2572 * [op->d.agg_plain_pergroup_nullcheck.setoff];
2573 */
2575 l_ptr(StructAggState), "");
2576
2581 "aggstate.all_pergroups");
2582
2584
2587
2591 l_datum_const(0), ""),
2592 opblocks[jumpnull],
2593 opblocks[opno + 1]);
2594 break;
2595 }
2596
2603 {
2605 AggStatePerTrans pertrans;
2606 FunctionCallInfo fcinfo;
2607
2611
2614
2617
2619
2624
2626
2628
2630
2633
2634 aggstate = castNode(AggState, state->parent);
2635 pertrans = op->d.agg_trans.pertrans;
2636
2637 fcinfo = pertrans->transfn_fcinfo;
2638
2639 v_aggstatep =
2641 v_pertransp = l_ptr_const(pertrans,
2643
2644 /*
2645 * pergroup = &aggstate->all_pergroups
2646 * [op->d.agg_trans.setoff] [op->d.agg_trans.transno];
2647 */
2653 "aggstate.all_pergroups");
2656 v_pergroupp =
2657 l_gep(b,
2661 &v_transno, 1, "");
2662
2663
2666 {
2670
2676 "notransvalue");
2677
2678 b_init = l_bb_before_v(opblocks[opno + 1],
2679 "op.%d.inittrans", opno);
2680 b_no_init = l_bb_before_v(opblocks[opno + 1],
2681 "op.%d.no_inittrans", opno);
2682
2685 l_sbool_const(1), ""),
2686 b_init,
2687 b_no_init);
2688
2689 /* block to init the transition value if necessary */
2690 {
2691 LLVMValueRef params[4];
2692
2694
2697
2698 params[0] = v_aggstatep;
2699 params[1] = v_pertransp;
2700 params[2] = v_pergroupp;
2701 params[3] = v_aggcontext;
2702
2703 l_call(b,
2704 llvm_pg_var_func_type("ExecAggInitGroup"),
2705 llvm_pg_func(mod, "ExecAggInitGroup"),
2706 params, lengthof(params),
2707 "");
2708
2709 LLVMBuildBr(b, opblocks[opno + 1]);
2710 }
2711
2713 }
2714
2719 {
2722
2724 "op.%d.strictpass", opno);
2725 v_transnull =
2730 "transnull");
2731
2734 l_sbool_const(1), ""),
2735 opblocks[opno + 1],
2736 b_strictpass);
2737
2739 }
2740
2741
2742 v_fcinfo = l_ptr_const(fcinfo,
2746
2752 "aggstate.current_set");
2758 "aggstate.curaggcontext");
2764 "aggstate.curpertrans");
2765
2766 /* set aggstate globals */
2771
2772 /* invoke transition function in per-tuple context */
2773 v_tmpcontext =
2774 l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2777
2778 /* store transvalue in fcinfo->args[0] */
2784 "transvalue");
2785 v_transnullp =
2790 "transnullp");
2792 l_load(b,
2793 TypeDatum,
2795 "transvalue"),
2796 l_funcvaluep(b, v_fcinfo, 0));
2798 l_load(b, TypeStorageBool, v_transnullp, "transnull"),
2799 l_funcnullp(b, v_fcinfo, 0));
2800
2801 /* and invoke transition function */
2802 v_retval = BuildV1Call(context, b, mod, fcinfo,
2804
2805 /*
2806 * For pass-by-ref datatype, must copy the new value into
2807 * aggcontext and free the prior transValue. But if
2808 * transfn returned a pointer to its first input, we don't
2809 * need to do anything. Also, if transfn returned a
2810 * pointer to a R/W expanded object that is already a
2811 * child of the aggcontext, assume we can adopt that value
2812 * without copying it.
2813 */
2817 {
2824 LLVMValueRef params[6];
2825
2826 b_call = l_bb_before_v(opblocks[opno + 1],
2827 "op.%d.transcall", opno);
2828 b_nocall = l_bb_before_v(opblocks[opno + 1],
2829 "op.%d.transnocall", opno);
2830
2833
2834 /*
2835 * DatumGetPointer(newVal) !=
2836 * DatumGetPointer(pergroup->transValue))
2837 */
2841 v_retval, ""),
2842 b_nocall, b_call);
2843
2844 /* returned datum not passed datum, reparent */
2846
2847 params[0] = v_aggstatep;
2848 params[1] = v_pertransp;
2849 params[2] = v_retval;
2850 params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
2851 TypeParamBool, "");
2852 params[4] = v_transvalue;
2853 params[5] = LLVMBuildTrunc(b, v_transnull,
2854 TypeParamBool, "");
2855
2856 v_fn = llvm_pg_func(mod, "ExecAggCopyTransValue");
2857 v_newval =
2858 l_call(b,
2860 v_fn,
2861 params, lengthof(params),
2862 "");
2863
2864 /* store trans value */
2867
2869 LLVMBuildBr(b, opblocks[opno + 1]);
2870
2871 /* returned datum passed datum, no need to reparent */
2873 }
2874
2875 /* store trans value */
2878
2880
2881 LLVMBuildBr(b, opblocks[opno + 1]);
2882 break;
2883 }
2884
2886 {
2889 int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
2890
2891 LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctSingle");
2894
2897
2900
2903 l_sbool_const(1), ""),
2904 opblocks[opno + 1],
2905 opblocks[jumpdistinct]);
2906 break;
2907 }
2908
2910 {
2913 int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
2914
2915 LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctMulti");
2918
2921
2924
2927 l_sbool_const(1), ""),
2928 opblocks[opno + 1],
2929 opblocks[jumpdistinct]);
2930 break;
2931 }
2932
2934 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
2935 v_state, op, v_econtext);
2936 LLVMBuildBr(b, opblocks[opno + 1]);
2937 break;
2938
2940 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
2941 v_state, op, v_econtext);
2942 LLVMBuildBr(b, opblocks[opno + 1]);
2943 break;
2944
2945 case EEOP_LAST:
2946 Assert(false);
2947 break;
2948 }
2949 }
2950
2952
2953 /*
2954 * Don't immediately emit function, instead do so the first time the
2955 * expression is actually evaluated. That allows to emit a lot of
2956 * functions together, avoiding a lot of repeated llvm and memory
2957 * remapping overhead.
2958 */
2959 {
2960
2962
2963 cstate->context = context;
2964 cstate->funcname = funcname;
2965
2966 state->evalfunc = ExecRunCompiledExpr;
2967 state->evalfunc_private = cstate;
2968 }
2969
2971
2973 INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter,
2974 endtime, starttime);
2975
2976 return true;
2977}
2978
2979/*
2980 * Run compiled expression.
2981 *
2982 * This will only be called the first time a JITed expression is called. We
2983 * first make sure the expression is still up-to-date, and then get a pointer to
2984 * the emitted function. The latter can be the first thing that triggers
2985 * optimizing and emitting all the generated functions.
2986 */
2987static Datum
2989{
2990 CompiledExprState *cstate = state->evalfunc_private;
2991 ExprStateEvalFunc func;
2992
2993 CheckExprStillValid(state, econtext);
2994
2997 cstate->funcname);
2999 Assert(func);
3000
3001 /* remove indirection via this function for future calls */
3002 state->evalfunc = func;
3003
3004 return func(state, econtext, isNull);
3005}
3006
3007static LLVMValueRef
3011{
3016
3017 v_fn = llvm_function_reference(context, b, mod, fcinfo);
3018
3022 v_fcinfo,
3024 "v_fcinfo_isnull");
3026
3028
3029 if (v_fcinfo_isnull)
3031
3032#if LLVM_VERSION_MAJOR < 22
3033
3034 /*
3035 * Add lifetime-end annotation, signaling that writes to memory don't have
3036 * to be retained (important for inlining potential).
3037 */
3038 {
3041 LLVMValueRef params[2];
3042
3043 params[0] = l_int64_const(lc, sizeof(NullableDatum) * fcinfo->nargs);
3044 params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
3045 l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
3046
3047 params[0] = l_int64_const(lc, sizeof(fcinfo->isnull));
3048 params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
3049 l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
3050 }
3051#endif
3052
3053 return v_retval;
3054}
3055
3056/*
3057 * Implement an expression step by calling the function funcname.
3058 */
3059static LLVMValueRef
3062 int nargs, LLVMValueRef *v_args)
3063{
3065 LLVMValueRef *params;
3066 int argno = 0;
3068
3069 /* cheap pre-check as llvm just asserts out */
3070 if (LLVMCountParams(v_fn) != (nargs + 2))
3071 elog(ERROR, "parameter mismatch: %s expects %d passed %d",
3072 funcname, LLVMCountParams(v_fn), nargs + 2);
3073
3074 params = palloc_array(LLVMValueRef, (2 + nargs));
3075
3076 params[argno++] = v_state;
3077 params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
3078
3079 for (int i = 0; i < nargs; i++)
3080 params[argno++] = v_args[i];
3081
3082 v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, argno, "");
3083
3084 pfree(params);
3085
3086 return v_ret;
3087}
3088
3089#if LLVM_VERSION_MAJOR < 22
3090static LLVMValueRef
3092{
3095 LLVMTypeRef param_types[2];
3097
3098 /* variadic pointer argument */
3099 const char *nm = "llvm.lifetime.end.p0";
3100
3102 if (fn)
3103 return fn;
3104
3106 param_types[0] = LLVMInt64TypeInContext(lc);
3107 param_types[1] = l_ptr(LLVMInt8TypeInContext(lc));
3108
3110 lengthof(param_types), false);
3112
3114
3116
3117 return fn;
3118}
3119#endif
#define Assert(condition)
Definition c.h:943
#define lengthof(array)
Definition c.h:873
CompareType
Definition cmptype.h:32
@ COMPARE_LE
Definition cmptype.h:35
@ COMPARE_GT
Definition cmptype.h:38
@ COMPARE_GE
Definition cmptype.h:37
@ COMPARE_LT
Definition cmptype.h:34
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
void CheckExprStillValid(ExprState *state, ExprContext *econtext)
ExprEvalOp ExecEvalStepOp(ExprState *state, ExprEvalStep *op)
ExprEvalOp
Definition execExpr.h:67
@ EEOP_OLD_VAR
Definition execExpr.h:85
@ EEOP_ASSIGN_TMP
Definition execExpr.h:110
@ EEOP_SUBPLAN
Definition execExpr.h:275
@ EEOP_CONVERT_ROWTYPE
Definition execExpr.h:262
@ EEOP_FUNCEXPR_STRICT_FUSAGE
Definition execExpr.h:127
@ EEOP_ARRAYEXPR
Definition execExpr.h:196
@ EEOP_JSONEXPR_PATH
Definition execExpr.h:268
@ EEOP_NOT_DISTINCT
Definition execExpr.h:190
@ EEOP_DOMAIN_TESTVAL
Definition execExpr.h:245
@ EEOP_PARAM_EXTERN
Definition execExpr.h:174
@ EEOP_HASHDATUM_NEXT32_STRICT
Definition execExpr.h:259
@ EEOP_IOCOERCE_SAFE
Definition execExpr.h:188
@ EEOP_BOOL_AND_STEP
Definition execExpr.h:136
@ EEOP_DONE_RETURN
Definition execExpr.h:69
@ EEOP_WHOLEROW
Definition execExpr.h:96
@ EEOP_JSONEXPR_COERCION_FINISH
Definition execExpr.h:270
@ EEOP_HASHDATUM_FIRST_STRICT
Definition execExpr.h:257
@ EEOP_AGGREF
Definition execExpr.h:271
@ EEOP_FUNCEXPR_STRICT_1
Definition execExpr.h:124
@ EEOP_INNER_VAR
Definition execExpr.h:82
@ EEOP_AGG_PLAIN_PERGROUP_NULLCHECK
Definition execExpr.h:283
@ EEOP_HASHDATUM_NEXT32
Definition execExpr.h:258
@ EEOP_ROWCOMPARE_FINAL
Definition execExpr.h:207
@ EEOP_AGG_STRICT_DESERIALIZE
Definition execExpr.h:278
@ EEOP_IOCOERCE
Definition execExpr.h:187
@ EEOP_RETURNINGEXPR
Definition execExpr.h:195
@ EEOP_GROUPING_FUNC
Definition execExpr.h:272
@ EEOP_DOMAIN_CHECK
Definition execExpr.h:252
@ EEOP_BOOLTEST_IS_NOT_FALSE
Definition execExpr.h:170
@ EEOP_PARAM_SET
Definition execExpr.h:177
@ EEOP_NEXTVALUEEXPR
Definition execExpr.h:194
@ EEOP_NEW_SYSVAR
Definition execExpr.h:93
@ EEOP_AGG_PLAIN_TRANS_BYREF
Definition execExpr.h:289
@ EEOP_QUAL
Definition execExpr.h:148
@ EEOP_AGG_PRESORTED_DISTINCT_MULTI
Definition execExpr.h:291
@ EEOP_AGG_PLAIN_TRANS_BYVAL
Definition execExpr.h:286
@ EEOP_SCAN_VAR
Definition execExpr.h:84
@ EEOP_CASE_TESTVAL_EXT
Definition execExpr.h:181
@ EEOP_BOOL_NOT_STEP
Definition execExpr.h:145
@ EEOP_ASSIGN_SCAN_VAR
Definition execExpr.h:105
@ EEOP_NEW_VAR
Definition execExpr.h:86
@ EEOP_SCAN_SYSVAR
Definition execExpr.h:91
@ EEOP_SCALARARRAYOP
Definition execExpr.h:263
@ EEOP_DOMAIN_NOTNULL
Definition execExpr.h:249
@ EEOP_WINDOW_FUNC
Definition execExpr.h:273
@ EEOP_INNER_FETCHSOME
Definition execExpr.h:75
@ EEOP_NULLTEST_ROWISNOTNULL
Definition execExpr.h:164
@ EEOP_ASSIGN_OUTER_VAR
Definition execExpr.h:104
@ EEOP_ROW
Definition execExpr.h:198
@ EEOP_MAKE_READONLY
Definition execExpr.h:184
@ EEOP_FIELDSTORE_FORM
Definition execExpr.h:226
@ EEOP_ASSIGN_OLD_VAR
Definition execExpr.h:106
@ EEOP_SBSREF_SUBSCRIPTS
Definition execExpr.h:229
@ EEOP_FUNCEXPR_STRICT_2
Definition execExpr.h:125
@ EEOP_SBSREF_FETCH
Definition execExpr.h:242
@ EEOP_FUNCEXPR_STRICT
Definition execExpr.h:123
@ EEOP_NULLIF
Definition execExpr.h:191
@ EEOP_CURRENTOFEXPR
Definition execExpr.h:193
@ EEOP_INNER_SYSVAR
Definition execExpr.h:89
@ EEOP_ASSIGN_TMP_MAKE_RO
Definition execExpr.h:112
@ EEOP_CONST
Definition execExpr.h:115
@ EEOP_BOOL_OR_STEP_LAST
Definition execExpr.h:142
@ EEOP_JSONEXPR_COERCION
Definition execExpr.h:269
@ EEOP_BOOL_OR_STEP_FIRST
Definition execExpr.h:140
@ EEOP_XMLEXPR
Definition execExpr.h:265
@ EEOP_AGG_STRICT_INPUT_CHECK_NULLS
Definition execExpr.h:282
@ EEOP_SBSREF_ASSIGN
Definition execExpr.h:239
@ EEOP_OUTER_SYSVAR
Definition execExpr.h:90
@ EEOP_ASSIGN_INNER_VAR
Definition execExpr.h:103
@ EEOP_BOOL_OR_STEP
Definition execExpr.h:141
@ EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1
Definition execExpr.h:281
@ EEOP_OUTER_FETCHSOME
Definition execExpr.h:76
@ EEOP_AGG_STRICT_INPUT_CHECK_ARGS
Definition execExpr.h:280
@ EEOP_NULLTEST_ROWISNULL
Definition execExpr.h:163
@ EEOP_BOOLTEST_IS_TRUE
Definition execExpr.h:167
@ EEOP_FUNCEXPR
Definition execExpr.h:122
@ EEOP_NULLTEST_ISNOTNULL
Definition execExpr.h:160
@ EEOP_ROWCOMPARE_STEP
Definition execExpr.h:204
@ EEOP_MERGE_SUPPORT_FUNC
Definition execExpr.h:274
@ EEOP_AGG_DESERIALIZE
Definition execExpr.h:279
@ EEOP_LAST
Definition execExpr.h:296
@ EEOP_HASHDATUM_FIRST
Definition execExpr.h:256
@ EEOP_DISTINCT
Definition execExpr.h:189
@ EEOP_JUMP_IF_NOT_TRUE
Definition execExpr.h:156
@ EEOP_FUNCEXPR_FUSAGE
Definition execExpr.h:126
@ EEOP_AGG_PRESORTED_DISTINCT_SINGLE
Definition execExpr.h:290
@ EEOP_BOOL_AND_STEP_FIRST
Definition execExpr.h:135
@ EEOP_JUMP
Definition execExpr.h:151
@ EEOP_DONE_NO_RETURN
Definition execExpr.h:72
@ EEOP_PARAM_CALLBACK
Definition execExpr.h:175
@ EEOP_DOMAIN_TESTVAL_EXT
Definition execExpr.h:246
@ EEOP_OLD_SYSVAR
Definition execExpr.h:92
@ EEOP_BOOL_AND_STEP_LAST
Definition execExpr.h:137
@ EEOP_NEW_FETCHSOME
Definition execExpr.h:79
@ EEOP_AGG_ORDERED_TRANS_DATUM
Definition execExpr.h:292
@ EEOP_OLD_FETCHSOME
Definition execExpr.h:78
@ EEOP_ASSIGN_NEW_VAR
Definition execExpr.h:107
@ EEOP_SBSREF_OLD
Definition execExpr.h:236
@ EEOP_SQLVALUEFUNCTION
Definition execExpr.h:192
@ EEOP_HASHDATUM_SET_INITVAL
Definition execExpr.h:255
@ EEOP_JUMP_IF_NOT_NULL
Definition execExpr.h:155
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYREF
Definition execExpr.h:288
@ EEOP_FIELDSTORE_DEFORM
Definition execExpr.h:219
@ EEOP_BOOLTEST_IS_FALSE
Definition execExpr.h:169
@ EEOP_BOOLTEST_IS_NOT_TRUE
Definition execExpr.h:168
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL
Definition execExpr.h:284
@ EEOP_PARAM_EXEC
Definition execExpr.h:173
@ EEOP_JSON_CONSTRUCTOR
Definition execExpr.h:266
@ EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL
Definition execExpr.h:285
@ EEOP_NULLTEST_ISNULL
Definition execExpr.h:159
@ EEOP_MINMAX
Definition execExpr.h:210
@ EEOP_JUMP_IF_NULL
Definition execExpr.h:154
@ EEOP_ARRAYCOERCE
Definition execExpr.h:197
@ EEOP_FIELDSELECT
Definition execExpr.h:213
@ EEOP_CASE_TESTVAL
Definition execExpr.h:180
@ EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF
Definition execExpr.h:287
@ EEOP_HASHED_SCALARARRAYOP
Definition execExpr.h:264
@ EEOP_OUTER_VAR
Definition execExpr.h:83
@ EEOP_AGG_ORDERED_TRANS_TUPLE
Definition execExpr.h:293
@ EEOP_SCAN_FETCHSOME
Definition execExpr.h:77
@ EEOP_IS_JSON
Definition execExpr.h:267
const TupleTableSlotOps TTSOpsVirtual
Definition execTuples.c:84
Datum(* ExprStateEvalFunc)(ExprState *expression, ExprContext *econtext, bool *isNull)
Definition execnodes.h:82
#define FIELDNO_EXPRSTATE_RESULTSLOT
Definition execnodes.h:117
#define FIELDNO_EXPRCONTEXT_CASENULL
Definition execnodes.h:313
#define FIELDNO_EXPRCONTEXT_INNERTUPLE
Definition execnodes.h:288
#define FIELDNO_EXPRSTATE_FLAGS
Definition execnodes.h:102
#define FIELDNO_EXPRCONTEXT_DOMAINNULL
Definition execnodes.h:319
#define FIELDNO_EXPRCONTEXT_DOMAINDATUM
Definition execnodes.h:317
#define FIELDNO_EXPRCONTEXT_CASEDATUM
Definition execnodes.h:311
#define FIELDNO_EXPRCONTEXT_OLDTUPLE
Definition execnodes.h:323
#define FIELDNO_AGGSTATE_CURPERTRANS
Definition execnodes.h:2449
#define FIELDNO_EXPRSTATE_RESNULL
Definition execnodes.h:109
#define FIELDNO_EXPRCONTEXT_NEWTUPLE
Definition execnodes.h:325
#define FIELDNO_EXPRCONTEXT_AGGNULLS
Definition execnodes.h:307
#define FIELDNO_EXPRSTATE_RESVALUE
Definition execnodes.h:111
#define FIELDNO_AGGSTATE_CURRENT_SET
Definition execnodes.h:2454
#define FIELDNO_EXPRCONTEXT_AGGVALUES
Definition execnodes.h:305
#define FIELDNO_EXPRCONTEXT_OUTERTUPLE
Definition execnodes.h:290
#define FIELDNO_AGGSTATE_ALL_PERGROUPS
Definition execnodes.h:2501
#define FIELDNO_EXPRSTATE_PARENT
Definition execnodes.h:145
#define FIELDNO_EXPRCONTEXT_SCANTUPLE
Definition execnodes.h:286
#define FIELDNO_AGGSTATE_CURAGGCONTEXT
Definition execnodes.h:2446
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define palloc0_object(type)
Definition fe_memutils.h:75
#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL
Definition fmgr.h:91
#define funcname
static struct @177 value
#define INSTR_TIME_SET_CURRENT(t)
Definition instr_time.h:426
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition instr_time.h:439
int b
Definition isn.c:74
int i
Definition isn.c:77
#define PGJIT_DEFORM
Definition jit.h:24
LLVMTypeRef StructFunctionCallInfoData
Definition llvmjit.c:70
LLVMJitContext * llvm_create_context(int jitFlags)
Definition llvmjit.c:224
LLVMTypeRef StructExprState
Definition llvmjit.c:73
LLVMTypeRef StructExprEvalStep
Definition llvmjit.c:72
LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname)
Definition llvmjit.c:465
LLVMTypeRef TypeParamBool
Definition llvmjit.c:58
LLVMTypeRef StructMemoryContextData
Definition llvmjit.c:69
LLVMTypeRef StructAggStatePerGroupData
Definition llvmjit.c:75
LLVMTypeRef llvm_pg_var_type(const char *varname)
Definition llvmjit.c:423
LLVMValueRef llvm_function_reference(LLVMJitContext *context, LLVMBuilderRef builder, LLVMModuleRef mod, FunctionCallInfo fcinfo)
Definition llvmjit.c:541
char * llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
Definition llvmjit.c:342
LLVMTypeRef llvm_pg_var_func_type(const char *varname)
Definition llvmjit.c:443
LLVMTypeRef StructTupleTableSlot
Definition llvmjit.c:65
LLVMTypeRef TypeStorageBool
Definition llvmjit.c:59
LLVMTypeRef TypeDatum
Definition llvmjit.c:57
LLVMModuleRef llvm_mutable_module(LLVMJitContext *context)
Definition llvmjit.c:317
LLVMTypeRef StructAggState
Definition llvmjit.c:74
LLVMValueRef AttributeTemplate
Definition llvmjit.c:79
LLVMTypeRef StructExprContext
Definition llvmjit.c:71
void * llvm_get_function(LLVMJitContext *context, const char *funcname)
Definition llvmjit.c:363
LLVMTypeRef StructNullableDatum
Definition llvmjit.c:61
LLVMValueRef ExecEvalSubroutineTemplate
Definition llvmjit.c:80
LLVMValueRef ExecEvalBoolSubroutineTemplate
Definition llvmjit.c:81
LLVMTypeRef StructAggStatePerTransData
Definition llvmjit.c:76
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
Definition llvmjit.c:517
LLVMValueRef slot_compile_deform(LLVMJitContext *context, TupleDesc desc, const TupleTableSlotOps *ops, int natts)
void llvm_enter_fatal_on_oom(void)
void llvm_leave_fatal_on_oom(void)
static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull)
#define build_EvalXFunc(b, mod, funcname, v_state, op,...)
bool llvm_compile_expr(ExprState *state)
static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname, LLVMValueRef v_state, ExprEvalStep *op, int natts, LLVMValueRef *v_args)
static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod)
static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, LLVMModuleRef mod, FunctionCallInfo fcinfo, LLVMValueRef *v_fcinfo_isnull)
LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r)
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE
Definition nodeAgg.h:252
#define FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL
Definition nodeAgg.h:254
#define FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE
Definition nodeAgg.h:257
#define castNode(_type_, nodeptr)
Definition nodes.h:182
static int sig
Definition pg_ctl.c:81
#define FIELDNO_NULLABLE_DATUM_ISNULL
Definition postgres.h:88
uint64_t Datum
Definition postgres.h:70
static int fb(int x)
FunctionCallInfo transfn_fcinfo
Definition nodeAgg.h:170
const char * funcname
LLVMJitContext * context
struct JitContext * es_jit
Definition execnodes.h:800
int es_jit_flags
Definition execnodes.h:799
uint8 nullflag
Definition execExpr.h:373
bool * anynull
Definition execExpr.h:399
struct ExprEvalStep::@63::@64 fetch
struct ExprEvalStep::@63::@71 func
WindowFuncExprState * wfstate
Definition execExpr.h:684
ExecEvalBoolSubroutine subscriptfunc
Definition execExpr.h:568
struct ExprEvalStep::@63::@69 returningexpr
struct ExprEvalStep::@63::@72 boolexpr
struct ExprEvalStep::@63::@80 iocoerce
struct ExprEvalStep::@63::@67 assign_var
AggStatePerTrans pertrans
Definition execExpr.h:731
struct JsonExprState * jsestate
Definition execExpr.h:756
ExecEvalSubroutine paramfunc
Definition execExpr.h:432
FunctionCallInfo fcinfo_data_in
Definition execExpr.h:461
struct ExprEvalStep::@63::@91 sbsref_subscript
TupleDesc known_desc
Definition execExpr.h:329
NullableDatum * args
Definition execExpr.h:715
bool * nulls
Definition execExpr.h:531
Datum * resvalue
Definition execExpr.h:310
NullableDatum * iresult
Definition execExpr.h:610
struct ExprEvalStep::@63::@65 var
struct ExprEvalStep::@63::@68 assign_tmp
const TupleTableSlotOps * kind
Definition execExpr.h:331
struct ExprEvalStep::@63::@108 agg_presorted_distinctcheck
FunctionCallInfo fcinfo_data
Definition execExpr.h:389
struct ExprEvalStep::@63::@78 casetest
int jumpdistinct
Definition execExpr.h:733
FmgrInfo * finfo_in
Definition execExpr.h:460
struct ExprEvalStep::@63::@70 constval
struct ExprEvalStep::@63::@95 hashdatum
struct ExprEvalStep::@63::@105 agg_deserialize
struct ExprEvalStep::@63::@106 agg_strict_input_check
struct ExprEvalStep::@63::@73 qualexpr
struct ExprEvalStep::@63::@103 window_func
struct ExprEvalStep::@63::@79 make_readonly
union ExprEvalStep::@63 d
Datum value
Definition execExpr.h:381
struct ExprEvalStep::@63::@92 sbsref
CompareType cmptype
Definition execExpr.h:523
struct ExprEvalStep::@63::@86 rowcompare_step
bool * resnull
Definition execExpr.h:311
struct ExprEvalStep::@63::@94 hashdatum_initvalue
struct ExprEvalStep::@63::@74 jump
struct ExprEvalStep::@63::@77 cparam
FunctionCallInfo fcinfo_data_out
Definition execExpr.h:458
struct ExprEvalStep::@63::@101 aggref
Datum init_value
Definition execExpr.h:598
struct ExprEvalStep::@63::@109 agg_trans
struct ExprEvalStep::@63::@111 jsonexpr
FmgrInfo * finfo
Definition execExpr.h:388
ExprContext * aggcontext
Definition execExpr.h:732
struct ExprEvalStep::@63::@87 rowcompare_final
struct ExprEvalStep::@63::@107 agg_plain_pergroup_nullcheck
bool fn_strict
Definition fmgr.h:61
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition fmgr.h:95
int jump_eval_coercion
Definition execnodes.h:1143
Datum value
Definition postgres.h:87
EState * state
Definition execnodes.h:1203
static void * fn(void *arg)
#define FIELDNO_TUPLETABLESLOT_ISNULL
Definition tuptable.h:132
#define FIELDNO_TUPLETABLESLOT_VALUES
Definition tuptable.h:130
#define FIELDNO_TUPLETABLESLOT_NVALID
Definition tuptable.h:125