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);
66
67/* macro making it easier to call ExecEval* functions */
68#define build_EvalXFunc(b, mod, funcname, v_state, op, ...) \
69 build_EvalXFuncInt(b, mod, funcname, v_state, op, \
70 lengthof(((LLVMValueRef[]){__VA_ARGS__})), \
71 ((LLVMValueRef[]){__VA_ARGS__}))
72
73
74/*
75 * JIT compile expression.
76 */
77bool
79{
80 PlanState *parent = state->parent;
81 char *funcname;
82
83 LLVMJitContext *context = NULL;
84
91
92 /* state itself */
96
97 /* returnvalue */
99
100 /* tmp vars in state */
103
104 /* slots */
111
112 /* nulls/values of slots */
125
126 /* stuff in econtext */
129
130 instr_time starttime;
134
136
137 /*
138 * Right now we don't support compiling expressions without a parent, as
139 * we need access to the EState.
140 */
141 Assert(parent);
142
143 /* get or create JIT context */
144 if (parent->state->es_jit)
145 context = (LLVMJitContext *) parent->state->es_jit;
146 else
147 {
148 context = llvm_create_context(parent->state->es_jit_flags);
149 parent->state->es_jit = &context->base;
150 }
151
152 INSTR_TIME_SET_CURRENT(starttime);
153
154 mod = llvm_mutable_module(context);
156
158
159 funcname = llvm_expand_funcname(context, "evalexpr");
160
161 /* create function */
163 llvm_pg_var_func_type("ExecInterpExprStillValid"));
167
168 entry = LLVMAppendBasicBlockInContext(lc, eval_fn, "entry");
169
170 /* build state */
174
176
179 v_state,
181 "v.state.resvalue");
184 v_state,
186 "v.state.resnull");
189 v_state,
191 "v.state.parent");
192
193 /* build global slots */
198 "v_scanslot");
203 "v_innerslot");
208 "v_outerslot");
213 "v_oldslot");
218 "v_newslot");
221 v_state,
223 "v_resultslot");
224
225 /* build global values/isnull pointers */
230 "v_scanvalues");
235 "v_scannulls");
240 "v_innervalues");
245 "v_innernulls");
250 "v_outervalues");
255 "v_outernulls");
258 v_oldslot,
260 "v_oldvalues");
263 v_oldslot,
265 "v_oldnulls");
268 v_newslot,
270 "v_newvalues");
273 v_newslot,
275 "v_newnulls");
280 "v_resultvalues");
285 "v_resultnulls");
286
287 /* aggvalues/aggnulls */
292 "v.econtext.aggvalues");
297 "v.econtext.aggnulls");
298
299 /* allocate blocks for each op upfront, so we can do jumps easily */
301 for (int opno = 0; opno < state->steps_len; opno++)
302 opblocks[opno] = l_bb_append_v(eval_fn, "b.op.%d.start", opno);
303
304 /* jump from entry to first block */
306
307 for (int opno = 0; opno < state->steps_len; opno++)
308 {
309 ExprEvalStep *op;
310 ExprEvalOp opcode;
313
315
316 op = &state->steps[opno];
317 opcode = ExecEvalStepOp(state, op);
318
321
322 switch (opcode)
323 {
324 case EEOP_DONE_RETURN:
325 {
328
331
333
335 break;
336 }
337
340 break;
341
347 {
348 TupleDesc desc = NULL;
353 const TupleTableSlotOps *tts_ops = NULL;
354
355 b_fetch = l_bb_before_v(opblocks[opno + 1],
356 "op.%d.fetch", opno);
357
358 if (op->d.fetch.known_desc)
359 desc = op->d.fetch.known_desc;
360
361 if (op->d.fetch.fixed)
362 tts_ops = op->d.fetch.kind;
363
364 /* step should not have been generated */
365 Assert(tts_ops != &TTSOpsVirtual);
366
367 if (opcode == EEOP_INNER_FETCHSOME)
369 else if (opcode == EEOP_OUTER_FETCHSOME)
371 else if (opcode == EEOP_SCAN_FETCHSOME)
373 else if (opcode == EEOP_OLD_FETCHSOME)
375 else
377
378 /*
379 * Check if all required attributes are available, or
380 * whether deforming is required.
381 */
382 v_nvalid =
385 v_slot,
387 "");
391 ""),
392 opblocks[opno + 1], b_fetch);
393
395
396 /*
397 * If the tupledesc of the to-be-deformed tuple is known,
398 * and JITing of deforming is enabled, build deform
399 * function specific to tupledesc and the exact number of
400 * to-be-extracted attributes.
401 */
402 if (tts_ops && desc && (context->base.flags & PGJIT_DEFORM))
403 {
406 slot_compile_deform(context, desc,
407 tts_ops,
408 op->d.fetch.last_var);
410 INSTR_TIME_ACCUM_DIFF(context->base.instr.deform_counter,
412 }
413
414 if (l_jit_deform)
415 {
416 LLVMValueRef params[1];
417
418 params[0] = v_slot;
419
420 l_call(b,
423 params, lengthof(params), "");
424 }
425 else
426 {
427 LLVMValueRef params[2];
428
429 params[0] = v_slot;
430 params[1] = l_int32_const(lc, op->d.fetch.last_var);
431
432 l_call(b,
433 llvm_pg_var_func_type("slot_getsomeattrs_int"),
434 llvm_pg_func(mod, "slot_getsomeattrs_int"),
435 params, lengthof(params), "");
436 }
437
438 LLVMBuildBr(b, opblocks[opno + 1]);
439 break;
440 }
441
442 case EEOP_INNER_VAR:
443 case EEOP_OUTER_VAR:
444 case EEOP_SCAN_VAR:
445 case EEOP_OLD_VAR:
446 case EEOP_NEW_VAR:
447 {
449 isnull;
453
454 if (opcode == EEOP_INNER_VAR)
455 {
458 }
459 else if (opcode == EEOP_OUTER_VAR)
460 {
463 }
464 else if (opcode == EEOP_SCAN_VAR)
465 {
468 }
469 else if (opcode == EEOP_OLD_VAR)
470 {
473 }
474 else
475 {
478 }
479
484 LLVMBuildStore(b, isnull, v_resnullp);
485
486 LLVMBuildBr(b, opblocks[opno + 1]);
487 break;
488 }
489
492 case EEOP_SCAN_SYSVAR:
493 case EEOP_OLD_SYSVAR:
494 case EEOP_NEW_SYSVAR:
495 {
497
498 if (opcode == EEOP_INNER_SYSVAR)
500 else if (opcode == EEOP_OUTER_SYSVAR)
502 else if (opcode == EEOP_SCAN_SYSVAR)
504 else if (opcode == EEOP_OLD_SYSVAR)
506 else
508
509 build_EvalXFunc(b, mod, "ExecEvalSysVar",
511
512 LLVMBuildBr(b, opblocks[opno + 1]);
513 break;
514 }
515
516 case EEOP_WHOLEROW:
517 build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
518 v_state, op, v_econtext);
519 LLVMBuildBr(b, opblocks[opno + 1]);
520 break;
521
527 {
536
537 if (opcode == EEOP_ASSIGN_INNER_VAR)
538 {
541 }
542 else if (opcode == EEOP_ASSIGN_OUTER_VAR)
543 {
546 }
547 else if (opcode == EEOP_ASSIGN_SCAN_VAR)
548 {
551 }
552 else if (opcode == EEOP_ASSIGN_OLD_VAR)
553 {
556 }
557 else
558 {
561 }
562
563 /* load data */
567
568 /* compute addresses of targets */
570 v_rvaluep = l_gep(b,
571 TypeDatum,
573 &v_resultnum, 1, "");
577 &v_resultnum, 1, "");
578
579 /* and store */
582
583 LLVMBuildBr(b, opblocks[opno + 1]);
584 break;
585 }
586
587 case EEOP_ASSIGN_TMP:
589 {
591 v_isnull;
595 size_t resultnum = op->d.assign_tmp.resultnum;
596
597 /* load data */
600
601 /* compute addresses of targets */
602 v_resultnum = l_int32_const(lc, resultnum);
603 v_rvaluep =
605 v_risnullp =
607
608 /* store nullness */
610
611 /* make value readonly if necessary */
612 if (opcode == EEOP_ASSIGN_TMP_MAKE_RO)
613 {
616
617 b_notnull = l_bb_before_v(opblocks[opno + 1],
618 "op.%d.assign_tmp.notnull", opno);
619
620 /* check if value is NULL */
623 l_sbool_const(0), ""),
624 b_notnull, opblocks[opno + 1]);
625
626 /* if value is not null, convert to RO datum */
628 v_params[0] = v_value;
629 v_value =
630 l_call(b,
631 llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
632 llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
634
635 /*
636 * Falling out of the if () with builder in b_notnull,
637 * which is fine - the null is already stored above.
638 */
639 }
640
641 /* and finally store result */
643
644 LLVMBuildBr(b, opblocks[opno + 1]);
645 break;
646 }
647
648 case EEOP_CONST:
649 {
652
655
658
659 LLVMBuildBr(b, opblocks[opno + 1]);
660 break;
661 }
662
663 case EEOP_FUNCEXPR:
667 {
668 FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
671
672 if (opcode == EEOP_FUNCEXPR_STRICT ||
673 opcode == EEOP_FUNCEXPR_STRICT_1 ||
674 opcode == EEOP_FUNCEXPR_STRICT_2)
675 {
679
680 /*
681 * Block for the actual function call, if args are
682 * non-NULL.
683 */
684 b_nonull = l_bb_before_v(opblocks[opno + 1],
685 "b.%d.no-null-args", opno);
686
687 /* should make sure they're optimized beforehand */
688 if (op->d.func.nargs == 0)
689 elog(ERROR, "argumentless strict functions are pointless");
690
691 v_fcinfo =
693
694 /*
695 * set resnull to true, if the function is actually
696 * called, it'll be reset
697 */
699
700 /* create blocks for checking args, one for each */
702 palloc(sizeof(LLVMBasicBlockRef) * op->d.func.nargs);
703 for (int argno = 0; argno < op->d.func.nargs; argno++)
705 l_bb_before_v(b_nonull, "b.%d.isnull.%d", opno,
706 argno);
707
708 /* jump to check of first argument */
710
711 /* check each arg for NULLness */
712 for (int argno = 0; argno < op->d.func.nargs; argno++)
713 {
716
718
719 /*
720 * Compute block to jump to if argument is not
721 * null.
722 */
723 if (argno + 1 == op->d.func.nargs)
725 else
727
728 /* and finally load & check NULLness of arg */
733 l_sbool_const(1),
734 ""),
735 opblocks[opno + 1],
737 }
738
740 }
741
742 v_retval = BuildV1Call(context, b, mod, fcinfo,
746
747 LLVMBuildBr(b, opblocks[opno + 1]);
748 break;
749 }
750
752 build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
753 v_state, op, v_econtext);
754 LLVMBuildBr(b, opblocks[opno + 1]);
755 break;
756
757
759 build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
760 v_state, op, v_econtext);
761 LLVMBuildBr(b, opblocks[opno + 1]);
762 break;
763
764 /*
765 * Treat them the same for now, optimizer can remove
766 * redundancy. Could be worthwhile to optimize during emission
767 * though.
768 */
772 {
782
784 "b.%d.boolisnull", opno);
786 "b.%d.boolcheckfalse", opno);
788 "b.%d.boolisfalse", opno);
790 "b.%d.boolisanynull", opno);
792 "b.%d.boolcont", opno);
793
796
797 if (opcode == EEOP_BOOL_AND_STEP_FIRST)
799
802
803 /* check if current input is NULL */
806 l_sbool_const(1), ""),
809
810 /* build block that sets anynull */
812 /* set boolanynull to true */
814 /* and jump to next block */
816
817 /* build block checking for false */
821 l_datum_const(0), ""),
823 b_boolcont);
824
825 /*
826 * Build block handling FALSE. Value is false, so short
827 * circuit.
828 */
830 /* result is already set to FALSE, need not change it */
831 /* and jump to the end of the AND expression */
833
834 /* Build block that continues if bool is TRUE. */
836
838
839 /* set value to NULL if any previous values were NULL */
842 l_sbool_const(0), ""),
843 opblocks[opno + 1], b_boolisanynull);
844
846 /* set resnull to true */
848 /* reset resvalue */
850
851 LLVMBuildBr(b, opblocks[opno + 1]);
852 break;
853 }
854
855 /*
856 * Treat them the same for now, optimizer can remove
857 * redundancy. Could be worthwhile to optimize during emission
858 * though.
859 */
863 {
868
874
876 "b.%d.boolisnull", opno);
878 "b.%d.boolchecktrue", opno);
880 "b.%d.boolistrue", opno);
882 "b.%d.boolisanynull", opno);
884 "b.%d.boolcont", opno);
885
888
889 if (opcode == EEOP_BOOL_OR_STEP_FIRST)
893
896 l_sbool_const(1), ""),
899
900 /* build block that sets anynull */
902 /* set boolanynull to true */
904 /* and jump to next block */
906
907 /* build block checking for true */
911 l_datum_const(1), ""),
913 b_boolcont);
914
915 /*
916 * Build block handling True. Value is true, so short
917 * circuit.
918 */
920 /* result is already set to TRUE, need not change it */
921 /* and jump to the end of the OR expression */
923
924 /* build block that continues if bool is FALSE */
926
928
929 /* set value to NULL if any previous values were NULL */
932 l_sbool_const(0), ""),
933 opblocks[opno + 1], b_boolisanynull);
934
936 /* set resnull to true */
938 /* reset resvalue */
940
941 LLVMBuildBr(b, opblocks[opno + 1]);
942 break;
943 }
944
946 {
949
950 /* compute !boolvalue */
955 l_datum_const(0),
956 ""),
957 TypeDatum, "");
958
959 /*
960 * Store it back in resvalue. We can ignore resnull here;
961 * if it was true, it stays true, and the value we store
962 * in resvalue doesn't matter.
963 */
965
966 LLVMBuildBr(b, opblocks[opno + 1]);
967 break;
968 }
969
970 case EEOP_QUAL:
971 {
976
978 "op.%d.qualfail", opno);
979
982
986 l_sbool_const(1), ""),
988 l_datum_const(0), ""),
989 "");
990
994 opblocks[opno + 1]);
995
996 /* build block handling NULL or false */
998 /* set resnull to false */
1000 /* set resvalue to false */
1002 /* and jump out */
1004 break;
1005 }
1006
1007 case EEOP_JUMP:
1008 {
1010 break;
1011 }
1012
1013 case EEOP_JUMP_IF_NULL:
1014 {
1016
1017 /* Transfer control if current result is null */
1018
1020
1023 l_sbool_const(1), ""),
1024 opblocks[op->d.jump.jumpdone],
1025 opblocks[opno + 1]);
1026 break;
1027 }
1028
1030 {
1032
1033 /* Transfer control if current result is non-null */
1034
1036
1039 l_sbool_const(0), ""),
1040 opblocks[op->d.jump.jumpdone],
1041 opblocks[opno + 1]);
1042 break;
1043 }
1044
1045
1047 {
1051
1052 /* Transfer control if current result is null or false */
1053
1056
1058 LLVMBuildOr(b,
1060 l_sbool_const(1), ""),
1062 l_datum_const(0), ""),
1063 "");
1064
1067 opblocks[op->d.jump.jumpdone],
1068 opblocks[opno + 1]);
1069 break;
1070 }
1071
1073 {
1076
1077 v_resvalue =
1080 l_sbool_const(1), ""),
1081 l_datum_const(1),
1082 l_datum_const(0),
1083 "");
1086
1087 LLVMBuildBr(b, opblocks[opno + 1]);
1088 break;
1089 }
1090
1092 {
1095
1096 v_resvalue =
1099 l_sbool_const(1), ""),
1100 l_datum_const(0),
1101 l_datum_const(1),
1102 "");
1105
1106 LLVMBuildBr(b, opblocks[opno + 1]);
1107 break;
1108 }
1109
1111 build_EvalXFunc(b, mod, "ExecEvalRowNull",
1112 v_state, op, v_econtext);
1113 LLVMBuildBr(b, opblocks[opno + 1]);
1114 break;
1115
1117 build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
1118 v_state, op, v_econtext);
1119 LLVMBuildBr(b, opblocks[opno + 1]);
1120 break;
1121
1126 {
1128 b_notnull;
1130
1131 b_isnull = l_bb_before_v(opblocks[opno + 1],
1132 "op.%d.isnull", opno);
1133 b_notnull = l_bb_before_v(opblocks[opno + 1],
1134 "op.%d.isnotnull", opno);
1135
1136 /* check if value is NULL */
1139 l_sbool_const(1), ""),
1141
1142 /* if value is NULL, return false */
1144
1145 /* result is not null */
1147
1148 if (opcode == EEOP_BOOLTEST_IS_TRUE ||
1149 opcode == EEOP_BOOLTEST_IS_FALSE)
1150 {
1152 }
1153 else
1154 {
1156 }
1157
1158 LLVMBuildBr(b, opblocks[opno + 1]);
1159
1161
1162 if (opcode == EEOP_BOOLTEST_IS_TRUE ||
1164 {
1165 /*
1166 * if value is not null NULL, return value (already
1167 * set)
1168 */
1169 }
1170 else
1171 {
1174
1177 v_value,
1178 l_datum_const(0),
1179 ""),
1180 TypeDatum, "");
1182 }
1183 LLVMBuildBr(b, opblocks[opno + 1]);
1184 break;
1185 }
1186
1187 case EEOP_PARAM_EXEC:
1188 build_EvalXFunc(b, mod, "ExecEvalParamExec",
1189 v_state, op, v_econtext);
1190 LLVMBuildBr(b, opblocks[opno + 1]);
1191 break;
1192
1193 case EEOP_PARAM_EXTERN:
1194 build_EvalXFunc(b, mod, "ExecEvalParamExtern",
1195 v_state, op, v_econtext);
1196 LLVMBuildBr(b, opblocks[opno + 1]);
1197 break;
1198
1200 {
1203
1205 llvm_pg_var_type("TypeExecEvalSubroutine"));
1206
1207 v_params[0] = v_state;
1209 v_params[2] = v_econtext;
1210 l_call(b,
1212 v_func,
1213 v_params, lengthof(v_params), "");
1214
1215 LLVMBuildBr(b, opblocks[opno + 1]);
1216 break;
1217 }
1218
1219 case EEOP_PARAM_SET:
1220 build_EvalXFunc(b, mod, "ExecEvalParamSet",
1221 v_state, op, v_econtext);
1222 LLVMBuildBr(b, opblocks[opno + 1]);
1223 break;
1224
1226 {
1227 int jumpdone = op->d.sbsref_subscript.jumpdone;
1231
1233 llvm_pg_var_type("TypeExecEvalBoolSubroutine"));
1234
1235 v_params[0] = v_state;
1237 v_params[2] = v_econtext;
1238 v_ret = l_call(b,
1240 v_func,
1241 v_params, lengthof(v_params), "");
1243
1246 l_sbool_const(1), ""),
1247 opblocks[opno + 1],
1248 opblocks[jumpdone]);
1249 break;
1250 }
1251
1252 case EEOP_SBSREF_OLD:
1253 case EEOP_SBSREF_ASSIGN:
1254 case EEOP_SBSREF_FETCH:
1255 {
1258
1260 llvm_pg_var_type("TypeExecEvalSubroutine"));
1261
1262 v_params[0] = v_state;
1264 v_params[2] = v_econtext;
1265 l_call(b,
1267 v_func,
1268 v_params, lengthof(v_params), "");
1269
1270 LLVMBuildBr(b, opblocks[opno + 1]);
1271 break;
1272 }
1273
1274 case EEOP_CASE_TESTVAL:
1275 {
1279 v_casenull;
1280
1282 l_ptr(TypeDatum));
1285
1290
1291 LLVMBuildBr(b, opblocks[opno + 1]);
1292 break;
1293 }
1294
1296 {
1299
1300 v_casevalue =
1303 v_econtext,
1305 v_casenull =
1308 v_econtext,
1312
1313 LLVMBuildBr(b, opblocks[opno + 1]);
1314 break;
1315 }
1316
1317 case EEOP_MAKE_READONLY:
1318 {
1326
1327 b_notnull = l_bb_before_v(opblocks[opno + 1],
1328 "op.%d.readonly.notnull", opno);
1329
1332
1334
1335 /* store null isnull value in result */
1337
1338 /* check if value is NULL */
1341 l_sbool_const(1), ""),
1342 opblocks[opno + 1], b_notnull);
1343
1344 /* if value is not null, convert to RO datum */
1346
1348 l_ptr(TypeDatum));
1349
1351
1352 v_params[0] = v_value;
1353 v_ret =
1354 l_call(b,
1355 llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
1356 llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
1357 v_params, lengthof(v_params), "");
1359
1360 LLVMBuildBr(b, opblocks[opno + 1]);
1361 break;
1362 }
1363
1364 case EEOP_IOCOERCE:
1365 {
1367 fcinfo_in;
1369 v_fn_in;
1376
1379
1384
1387
1389 "op.%d.skipoutputnull", opno);
1391 "op.%d.calloutput", opno);
1392 b_input = l_bb_before_v(opblocks[opno + 1],
1393 "op.%d.input", opno);
1395 "op.%d.inputcall", opno);
1396
1401
1407 "v_fcinfo_in_isnull");
1408
1409 /* output functions are not called on nulls */
1413 l_sbool_const(1), ""),
1415 b_calloutput);
1416
1420
1423
1424 /* set arg[0] */
1426 v_resvalue,
1429 l_sbool_const(0),
1431 /* and call output function (can never return NULL) */
1432 v_output = l_call(b,
1435 1, "funccall_coerce_out");
1437
1438 /* build block handling input function call */
1440
1441 /* phi between resnull and output function call branches */
1442 {
1445
1448
1451
1452 v_output = LLVMBuildPhi(b, TypeDatum, "output");
1456 }
1457
1458 /*
1459 * If input function is strict, skip if input string is
1460 * NULL.
1461 */
1462 if (op->d.iocoerce.finfo_in->fn_strict)
1463 {
1466 l_datum_const(0), ""),
1467 opblocks[opno + 1],
1468 b_inputcall);
1469 }
1470 else
1471 {
1473 }
1474
1476 /* set arguments */
1477 /* arg0: output */
1482
1483 /* arg1: ioparam: preset in execExpr.c */
1484 /* arg2: typmod: preset in execExpr.c */
1485
1486 /* reset fcinfo_in->isnull */
1488 /* and call function */
1489 v_retval = l_call(b,
1491 v_fn_in, &v_fcinfo_in, 1,
1492 "funccall_iocoerce_in");
1493
1495
1496 LLVMBuildBr(b, opblocks[opno + 1]);
1497 break;
1498 }
1499
1500 case EEOP_IOCOERCE_SAFE:
1501 build_EvalXFunc(b, mod, "ExecEvalCoerceViaIOSafe",
1502 v_state, op);
1503 LLVMBuildBr(b, opblocks[opno + 1]);
1504 break;
1505
1506 case EEOP_DISTINCT:
1507 case EEOP_NOT_DISTINCT:
1508 {
1509 FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1510
1513
1518
1521
1523
1528
1529 b_noargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.noargnull", opno);
1530 b_checkbothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.checkbothargnull", opno);
1531 b_bothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.bothargnull", opno);
1532 b_anyargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.anyargnull", opno);
1533
1535
1536 /* load args[0|1].isnull for both arguments */
1539 l_sbool_const(1), "");
1542 l_sbool_const(1), "");
1543
1546
1547 /*
1548 * Check function arguments for NULLness: If either is
1549 * NULL, we check if both args are NULL. Otherwise call
1550 * comparator.
1551 */
1553 b_noargnull);
1554
1555 /*
1556 * build block checking if any arg is null
1557 */
1560 b_anyargnull);
1561
1562
1563 /* Both NULL? Then is not distinct... */
1566 if (opcode == EEOP_NOT_DISTINCT)
1568 else
1570
1571 LLVMBuildBr(b, opblocks[opno + 1]);
1572
1573 /* Only one is NULL? Then is distinct... */
1576 if (opcode == EEOP_NOT_DISTINCT)
1578 else
1580 LLVMBuildBr(b, opblocks[opno + 1]);
1581
1582 /* neither argument is null: compare */
1584
1585 v_result = BuildV1Call(context, b, mod, fcinfo,
1587
1588 if (opcode == EEOP_DISTINCT)
1589 {
1590 /* Must invert result of "=" */
1591 v_result =
1594 v_result,
1595 l_datum_const(0), ""),
1596 TypeDatum, "");
1597 }
1598
1601
1602 LLVMBuildBr(b, opblocks[opno + 1]);
1603 break;
1604 }
1605
1606 case EEOP_NULLIF:
1607 {
1608 FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1609
1621
1622 b_hasnull = l_bb_before_v(opblocks[opno + 1],
1623 "b.%d.null-args", opno);
1624 b_nonull = l_bb_before_v(opblocks[opno + 1],
1625 "b.%d.no-null-args", opno);
1627 "b.%d.argsequal", opno);
1628
1630
1631 /* save original arg[0] */
1633
1634 /* if either argument is NULL they can't be equal */
1637
1639 LLVMBuildOr(b,
1641 l_sbool_const(1), ""),
1643 l_sbool_const(1), ""),
1644 "");
1645
1647
1648 /* one (or both) of the arguments are null, return arg[0] */
1652 LLVMBuildBr(b, opblocks[opno + 1]);
1653
1654 /* build block to invoke function and check result */
1656
1657 /*
1658 * If first argument is of varlena type, it might be an
1659 * expanded datum. We need to ensure that the value
1660 * passed to the comparison function is a read-only
1661 * pointer. However, if we end by returning the first
1662 * argument, that will be the original read-write pointer
1663 * if it was read-write.
1664 */
1665 if (op->d.func.make_ro)
1666 {
1669
1670 v_params[0] = v_arg0;
1671 v_arg0_ro =
1672 l_call(b,
1673 llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
1674 llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
1675 v_params, lengthof(v_params), "");
1677 l_funcvaluep(b, v_fcinfo, 0));
1678 }
1679
1680 v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull);
1681
1682 /*
1683 * If result not null and arguments are equal return null,
1684 * else return arg[0] (same result as if there'd been
1685 * NULLs, hence reuse b_hasnull).
1686 */
1690 l_sbool_const(0),
1691 ""),
1693 v_retval,
1694 l_datum_const(1),
1695 ""),
1696 "");
1698
1699 /* build block setting result to NULL, if args are equal */
1703
1704 LLVMBuildBr(b, opblocks[opno + 1]);
1705 break;
1706 }
1707
1709 build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
1710 v_state, op);
1711 LLVMBuildBr(b, opblocks[opno + 1]);
1712 break;
1713
1714 case EEOP_CURRENTOFEXPR:
1715 build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
1716 v_state, op);
1717 LLVMBuildBr(b, opblocks[opno + 1]);
1718 break;
1719
1720 case EEOP_NEXTVALUEEXPR:
1721 build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
1722 v_state, op);
1723 LLVMBuildBr(b, opblocks[opno + 1]);
1724 break;
1725
1726 case EEOP_RETURNINGEXPR:
1727 {
1732
1733 b_isnull = l_bb_before_v(opblocks[opno + 1],
1734 "op.%d.row.isnull", opno);
1735
1736 /*
1737 * The next op actually evaluates the expression. If the
1738 * OLD/NEW row doesn't exist, skip that and return NULL.
1739 */
1742 v_state,
1744 "v.state.flags");
1746
1748
1752 v_nullflag, ""),
1753 l_sbool_const(0), ""),
1754 opblocks[opno + 1], b_isnull);
1755
1757
1760
1762 break;
1763 }
1764
1765 case EEOP_ARRAYEXPR:
1766 build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
1767 v_state, op);
1768 LLVMBuildBr(b, opblocks[opno + 1]);
1769 break;
1770
1771 case EEOP_ARRAYCOERCE:
1772 build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
1773 v_state, op, v_econtext);
1774 LLVMBuildBr(b, opblocks[opno + 1]);
1775 break;
1776
1777 case EEOP_ROW:
1778 build_EvalXFunc(b, mod, "ExecEvalRow",
1779 v_state, op);
1780 LLVMBuildBr(b, opblocks[opno + 1]);
1781 break;
1782
1784 {
1790
1792
1793 b_null = l_bb_before_v(opblocks[opno + 1],
1794 "op.%d.row-null", opno);
1795 b_compare = l_bb_before_v(opblocks[opno + 1],
1796 "op.%d.row-compare", opno);
1798 l_bb_before_v(opblocks[opno + 1],
1799 "op.%d.row-compare-result",
1800 opno);
1801
1802 /*
1803 * If function is strict, and either arg is null, we're
1804 * done.
1805 */
1807 {
1812
1813 v_fcinfo = l_ptr_const(fcinfo,
1815
1818
1820 LLVMBuildOr(b,
1822 LLVMIntEQ,
1823 v_argnull0,
1824 l_sbool_const(1),
1825 ""),
1827 v_argnull1,
1828 l_sbool_const(1), ""),
1829 "");
1830
1832 }
1833 else
1834 {
1836 }
1837
1838 /* build block invoking comparison function */
1840
1841 /* call function */
1842 v_retval = BuildV1Call(context, b, mod, fcinfo,
1845
1846 /* if result of function is NULL, force NULL result */
1849 LLVMIntEQ,
1851 l_sbool_const(0),
1852 ""),
1854 b_null);
1855
1856 /* build block analyzing the !NULL comparator result */
1858
1859 /* if results equal, compare next, otherwise done */
1862 LLVMIntEQ,
1863 v_retval,
1864 l_datum_const(0), ""),
1865 opblocks[opno + 1],
1867
1868 /*
1869 * Build block handling NULL input or NULL comparator
1870 * result.
1871 */
1875
1876 break;
1877 }
1878
1880 {
1881 CompareType cmptype = op->d.rowcompare_final.cmptype;
1882
1886
1887 /*
1888 * Btree comparators return 32 bit results, need to be
1889 * careful about sign (used as a 64 bit value it's
1890 * otherwise wrong).
1891 */
1892 v_cmpresult =
1896
1897 switch (cmptype)
1898 {
1899 case COMPARE_LT:
1901 break;
1902 case COMPARE_LE:
1904 break;
1905 case COMPARE_GT:
1907 break;
1908 case COMPARE_GE:
1910 break;
1911 default:
1912 /* EQ and NE cases aren't allowed here */
1913 Assert(false);
1914 predicate = 0; /* prevent compiler warning */
1915 break;
1916 }
1917
1919 predicate,
1921 l_int32_const(lc, 0),
1922 "");
1924
1927
1928 LLVMBuildBr(b, opblocks[opno + 1]);
1929 break;
1930 }
1931
1932 case EEOP_MINMAX:
1933 build_EvalXFunc(b, mod, "ExecEvalMinMax",
1934 v_state, op);
1935 LLVMBuildBr(b, opblocks[opno + 1]);
1936 break;
1937
1938 case EEOP_FIELDSELECT:
1939 build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
1940 v_state, op, v_econtext);
1941 LLVMBuildBr(b, opblocks[opno + 1]);
1942 break;
1943
1945 build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
1946 v_state, op, v_econtext);
1947 LLVMBuildBr(b, opblocks[opno + 1]);
1948 break;
1949
1951 build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
1952 v_state, op, v_econtext);
1953 LLVMBuildBr(b, opblocks[opno + 1]);
1954 break;
1955
1957 {
1961 v_casenull;
1962
1964 l_ptr(TypeDatum));
1967
1972
1973 LLVMBuildBr(b, opblocks[opno + 1]);
1974 break;
1975 }
1976
1978 {
1981
1982 v_casevalue =
1985 v_econtext,
1987 "");
1988 v_casenull =
1991 v_econtext,
1993 "");
1996
1997 LLVMBuildBr(b, opblocks[opno + 1]);
1998 break;
1999 }
2000
2002 build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
2003 v_state, op);
2004 LLVMBuildBr(b, opblocks[opno + 1]);
2005 break;
2006
2007 case EEOP_DOMAIN_CHECK:
2008 build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
2009 v_state, op);
2010 LLVMBuildBr(b, opblocks[opno + 1]);
2011 break;
2012
2014 {
2016
2018
2021 LLVMBuildBr(b, opblocks[opno + 1]);
2022 break;
2023 }
2024
2029 {
2039
2040 /*
2041 * When performing the next hash and not in strict mode we
2042 * perform a rotation of the previously stored hash value
2043 * before doing the NULL check. We want to do this even
2044 * when we receive a NULL Datum to hash. In strict mode,
2045 * we do this after the NULL check so as not to waste the
2046 * effort of rotating the bits when we're going to throw
2047 * away the hash value and return NULL.
2048 */
2049 if (opcode == EEOP_HASHDATUM_NEXT32)
2050 {
2053 LLVMValueRef tmp;
2054
2055 tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
2056 l_ptr(TypeDatum));
2057
2058 /*
2059 * Fetch the previously hashed value from where the
2060 * previous hash operation stored it.
2061 */
2062 v_prevhash = l_load(b, TypeDatum, tmp, "prevhash");
2063
2064 /*
2065 * Rotate bits left by 1 bit. Be careful not to
2066 * overflow uint32 when working with Datum.
2067 */
2069 "");
2071 l_datum_const(0xffffffff), "");
2073 l_datum_const(31), "");
2075 "rotatedhash");
2076 }
2077
2078 /*
2079 * Block for the actual function call, if args are
2080 * non-NULL.
2081 */
2083 "b.%d.ifnotnull",
2084 opno);
2085
2086 /* we expect the hash function to have 1 argument */
2087 if (fcinfo->nargs != 1)
2088 elog(ERROR, "incorrect number of function arguments");
2089
2090 v_fcinfo = l_ptr_const(fcinfo,
2092
2094 "b.%d.isnull.0", opno);
2095
2097
2098 /*
2099 * Determine what to do if we find the argument to be
2100 * NULL.
2101 */
2102 if (opcode == EEOP_HASHDATUM_FIRST_STRICT ||
2104 {
2106 "b.%d.strictnull",
2107 opno);
2108
2110
2111 /*
2112 * In strict node, NULL inputs result in NULL. Save
2113 * the NULL result and goto jumpdone.
2114 */
2118 }
2119 else
2120 {
2122 "b.%d.null",
2123 opno);
2124
2126
2127
2129
2130 if (opcode == EEOP_HASHDATUM_NEXT32)
2131 {
2133
2134 /*
2135 * Save the rotated hash value and skip to the
2136 * next op.
2137 */
2139 }
2140 else
2141 {
2142 Assert(opcode == EEOP_HASHDATUM_FIRST);
2143
2144 /*
2145 * Store a zero Datum when the Datum to hash is
2146 * NULL
2147 */
2149 }
2150
2151 LLVMBuildBr(b, opblocks[opno + 1]);
2152 }
2153
2155
2156 /* emit code to check if the input parameter is NULL */
2160 LLVMIntEQ,
2162 l_sbool_const(1),
2163 ""),
2165 b_ifnotnull);
2166
2168
2169 /*
2170 * Rotate the previously stored hash value when performing
2171 * NEXT32 in strict mode. In non-strict mode we already
2172 * did this before checking for NULLs.
2173 */
2174 if (opcode == EEOP_HASHDATUM_NEXT32_STRICT)
2175 {
2178 LLVMValueRef tmp;
2179
2180 tmp = l_ptr_const(&op->d.hashdatum.iresult->value,
2181 l_ptr(TypeDatum));
2182
2183 /*
2184 * Fetch the previously hashed value from where the
2185 * previous hash operation stored it.
2186 */
2187 v_prevhash = l_load(b, TypeDatum, tmp, "prevhash");
2188
2189 /*
2190 * Rotate bits left by 1 bit. Be careful not to
2191 * overflow uint32 when working with Datum.
2192 */
2194 "");
2196 l_datum_const(0xffffffff), "");
2198 l_datum_const(31), "");
2200 "rotatedhash");
2201 }
2202
2203 /* call the hash function */
2204 v_retval = BuildV1Call(context, b, mod, fcinfo,
2206
2207 /*
2208 * For NEXT32 ops, XOR (^) the returned hash value with
2209 * the existing hash value.
2210 */
2211 if (opcode == EEOP_HASHDATUM_NEXT32 ||
2214 "xorhash");
2215
2218
2219 LLVMBuildBr(b, opblocks[opno + 1]);
2220 break;
2221 }
2222
2224 build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
2225 v_state, op, v_econtext);
2226 LLVMBuildBr(b, opblocks[opno + 1]);
2227 break;
2228
2229 case EEOP_SCALARARRAYOP:
2230 build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
2231 v_state, op);
2232 LLVMBuildBr(b, opblocks[opno + 1]);
2233 break;
2234
2236 build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp",
2237 v_state, op, v_econtext);
2238 LLVMBuildBr(b, opblocks[opno + 1]);
2239 break;
2240
2241 case EEOP_XMLEXPR:
2242 build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
2243 v_state, op);
2244 LLVMBuildBr(b, opblocks[opno + 1]);
2245 break;
2246
2248 build_EvalXFunc(b, mod, "ExecEvalJsonConstructor",
2249 v_state, op, v_econtext);
2250 LLVMBuildBr(b, opblocks[opno + 1]);
2251 break;
2252
2253 case EEOP_IS_JSON:
2254 build_EvalXFunc(b, mod, "ExecEvalJsonIsPredicate",
2255 v_state, op);
2256 LLVMBuildBr(b, opblocks[opno + 1]);
2257 break;
2258
2259 case EEOP_JSONEXPR_PATH:
2260 {
2261 JsonExprState *jsestate = op->d.jsonexpr.jsestate;
2263
2264 /*
2265 * Call ExecEvalJsonExprPath(). It returns the address of
2266 * the step to perform next.
2267 */
2268 v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExprPath",
2269 v_state, op, v_econtext);
2270
2271 /*
2272 * Build a switch to map the return value (v_ret above),
2273 * which is a runtime value of the step address to perform
2274 * next, to either jump_empty, jump_error,
2275 * jump_eval_coercion, or jump_end.
2276 */
2277 if (jsestate->jump_empty >= 0 ||
2278 jsestate->jump_error >= 0 ||
2279 jsestate->jump_eval_coercion >= 0)
2280 {
2286 b_empty,
2287 b_error,
2288 b_coercion;
2289
2290 b_empty =
2291 l_bb_before_v(opblocks[opno + 1],
2292 "op.%d.jsonexpr_empty", opno);
2293 b_error =
2294 l_bb_before_v(opblocks[opno + 1],
2295 "op.%d.jsonexpr_error", opno);
2296 b_coercion =
2297 l_bb_before_v(opblocks[opno + 1],
2298 "op.%d.jsonexpr_coercion", opno);
2299 b_done =
2300 l_bb_before_v(opblocks[opno + 1],
2301 "op.%d.jsonexpr_done", opno);
2302
2304 v_ret,
2305 b_done,
2306 3);
2307 /* Returned jsestate->jump_empty? */
2308 if (jsestate->jump_empty >= 0)
2309 {
2312 }
2313 /* ON EMPTY code */
2315 if (jsestate->jump_empty >= 0)
2316 LLVMBuildBr(b, opblocks[jsestate->jump_empty]);
2317 else
2319
2320 /* Returned jsestate->jump_error? */
2321 if (jsestate->jump_error >= 0)
2322 {
2325 }
2326 /* ON ERROR code */
2328 if (jsestate->jump_error >= 0)
2329 LLVMBuildBr(b, opblocks[jsestate->jump_error]);
2330 else
2332
2333 /* Returned jsestate->jump_eval_coercion? */
2334 if (jsestate->jump_eval_coercion >= 0)
2335 {
2338 }
2339 /* jump_eval_coercion code */
2341 if (jsestate->jump_eval_coercion >= 0)
2343 else
2345
2347 }
2348
2349 LLVMBuildBr(b, opblocks[jsestate->jump_end]);
2350 break;
2351 }
2352
2354 build_EvalXFunc(b, mod, "ExecEvalJsonCoercion",
2355 v_state, op, v_econtext);
2356
2357 LLVMBuildBr(b, opblocks[opno + 1]);
2358 break;
2359
2361 build_EvalXFunc(b, mod, "ExecEvalJsonCoercionFinish",
2362 v_state, op);
2363
2364 LLVMBuildBr(b, opblocks[opno + 1]);
2365 break;
2366
2367 case EEOP_AGGREF:
2368 {
2371 isnull;
2372
2374
2375 /* load agg value / null */
2376 value = l_load_gep1(b, TypeDatum, v_aggvalues, v_aggno, "aggvalue");
2377 isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
2378
2379 /* and store result */
2381 LLVMBuildStore(b, isnull, v_resnullp);
2382
2383 LLVMBuildBr(b, opblocks[opno + 1]);
2384 break;
2385 }
2386
2387 case EEOP_GROUPING_FUNC:
2388 build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
2389 v_state, op);
2390 LLVMBuildBr(b, opblocks[opno + 1]);
2391 break;
2392
2393 case EEOP_WINDOW_FUNC:
2394 {
2399 isnull;
2400
2401 /*
2402 * At this point aggref->wfuncno is not yet set (it's set
2403 * up in ExecInitWindowAgg() after initializing the
2404 * expression). So load it from memory each time round.
2405 */
2406 v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
2409
2410 /* load window func value / null */
2412 "windowvalue");
2414 "windownull");
2415
2417 LLVMBuildStore(b, isnull, v_resnullp);
2418
2419 LLVMBuildBr(b, opblocks[opno + 1]);
2420 break;
2421 }
2422
2424 build_EvalXFunc(b, mod, "ExecEvalMergeSupportFunc",
2425 v_state, op, v_econtext);
2426 LLVMBuildBr(b, opblocks[opno + 1]);
2427 break;
2428
2429 case EEOP_SUBPLAN:
2430 build_EvalXFunc(b, mod, "ExecEvalSubPlan",
2431 v_state, op, v_econtext);
2432 LLVMBuildBr(b, opblocks[opno + 1]);
2433 break;
2434
2437 {
2440
2445
2446 if (opcode == EEOP_AGG_STRICT_DESERIALIZE)
2447 {
2451
2453 "op.%d.deserialize", opno);
2454
2455 v_fcinfo = l_ptr_const(fcinfo,
2458
2461 LLVMIntEQ,
2462 v_argnull0,
2463 l_sbool_const(1),
2464 ""),
2468 }
2469
2470 aggstate = castNode(AggState, state->parent);
2471 fcinfo = op->d.agg_deserialize.fcinfo_data;
2472
2473 v_tmpcontext =
2474 l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2477 v_retval = BuildV1Call(context, b, mod, fcinfo,
2480
2483
2484 LLVMBuildBr(b, opblocks[opno + 1]);
2485 break;
2486 }
2487
2491 {
2492 int nargs = op->d.agg_strict_input_check.nargs;
2494 bool *nulls = op->d.agg_strict_input_check.nulls;
2495 int jumpnull;
2496
2500
2501 Assert(nargs > 0);
2502
2503 jumpnull = op->d.agg_strict_input_check.jumpnull;
2506
2507 /* create blocks for checking args */
2509 for (int argno = 0; argno < nargs; argno++)
2510 {
2512 l_bb_before_v(opblocks[opno + 1],
2513 "op.%d.check-null.%d",
2514 opno, argno);
2515 }
2516
2518
2519 /* strict function, check for NULL args */
2520 for (int argno = 0; argno < nargs; argno++)
2521 {
2525
2527
2528 if (argno + 1 == nargs)
2529 b_argnotnull = opblocks[opno + 1];
2530 else
2532
2535 else
2536 {
2538
2540 v_argisnull =
2543 "");
2544 }
2545
2548 LLVMIntEQ,
2550 l_sbool_const(1), ""),
2551 opblocks[jumpnull],
2552 b_argnotnull);
2553 }
2554
2555 break;
2556 }
2557
2559 {
2560 int jumpnull;
2565
2567
2568 /*
2569 * pergroup_allaggs = aggstate->all_pergroups
2570 * [op->d.agg_plain_pergroup_nullcheck.setoff];
2571 */
2573 l_ptr(StructAggState), "");
2574
2579 "aggstate.all_pergroups");
2580
2582
2585
2589 l_datum_const(0), ""),
2590 opblocks[jumpnull],
2591 opblocks[opno + 1]);
2592 break;
2593 }
2594
2601 {
2603 AggStatePerTrans pertrans;
2604 FunctionCallInfo fcinfo;
2605
2609
2612
2615
2617
2622
2624
2626
2628
2631
2632 aggstate = castNode(AggState, state->parent);
2633 pertrans = op->d.agg_trans.pertrans;
2634
2635 fcinfo = pertrans->transfn_fcinfo;
2636
2637 v_aggstatep =
2639 v_pertransp = l_ptr_const(pertrans,
2641
2642 /*
2643 * pergroup = &aggstate->all_pergroups
2644 * [op->d.agg_trans.setoff] [op->d.agg_trans.transno];
2645 */
2651 "aggstate.all_pergroups");
2654 v_pergroupp =
2655 l_gep(b,
2659 &v_transno, 1, "");
2660
2661
2664 {
2668
2674 "notransvalue");
2675
2676 b_init = l_bb_before_v(opblocks[opno + 1],
2677 "op.%d.inittrans", opno);
2678 b_no_init = l_bb_before_v(opblocks[opno + 1],
2679 "op.%d.no_inittrans", opno);
2680
2683 l_sbool_const(1), ""),
2684 b_init,
2685 b_no_init);
2686
2687 /* block to init the transition value if necessary */
2688 {
2689 LLVMValueRef params[4];
2690
2692
2695
2696 params[0] = v_aggstatep;
2697 params[1] = v_pertransp;
2698 params[2] = v_pergroupp;
2699 params[3] = v_aggcontext;
2700
2701 l_call(b,
2702 llvm_pg_var_func_type("ExecAggInitGroup"),
2703 llvm_pg_func(mod, "ExecAggInitGroup"),
2704 params, lengthof(params),
2705 "");
2706
2707 LLVMBuildBr(b, opblocks[opno + 1]);
2708 }
2709
2711 }
2712
2717 {
2720
2722 "op.%d.strictpass", opno);
2723 v_transnull =
2728 "transnull");
2729
2732 l_sbool_const(1), ""),
2733 opblocks[opno + 1],
2734 b_strictpass);
2735
2737 }
2738
2739
2740 v_fcinfo = l_ptr_const(fcinfo,
2744
2750 "aggstate.current_set");
2756 "aggstate.curaggcontext");
2762 "aggstate.curpertrans");
2763
2764 /* set aggstate globals */
2769
2770 /* invoke transition function in per-tuple context */
2771 v_tmpcontext =
2772 l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2775
2776 /* store transvalue in fcinfo->args[0] */
2782 "transvalue");
2783 v_transnullp =
2788 "transnullp");
2790 l_load(b,
2791 TypeDatum,
2793 "transvalue"),
2794 l_funcvaluep(b, v_fcinfo, 0));
2796 l_load(b, TypeStorageBool, v_transnullp, "transnull"),
2797 l_funcnullp(b, v_fcinfo, 0));
2798
2799 /* and invoke transition function */
2800 v_retval = BuildV1Call(context, b, mod, fcinfo,
2802
2803 /*
2804 * For pass-by-ref datatype, must copy the new value into
2805 * aggcontext and free the prior transValue. But if
2806 * transfn returned a pointer to its first input, we don't
2807 * need to do anything. Also, if transfn returned a
2808 * pointer to a R/W expanded object that is already a
2809 * child of the aggcontext, assume we can adopt that value
2810 * without copying it.
2811 */
2815 {
2822 LLVMValueRef params[6];
2823
2824 b_call = l_bb_before_v(opblocks[opno + 1],
2825 "op.%d.transcall", opno);
2826 b_nocall = l_bb_before_v(opblocks[opno + 1],
2827 "op.%d.transnocall", opno);
2828
2831
2832 /*
2833 * DatumGetPointer(newVal) !=
2834 * DatumGetPointer(pergroup->transValue))
2835 */
2839 v_retval, ""),
2840 b_nocall, b_call);
2841
2842 /* returned datum not passed datum, reparent */
2844
2845 params[0] = v_aggstatep;
2846 params[1] = v_pertransp;
2847 params[2] = v_retval;
2848 params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
2849 TypeParamBool, "");
2850 params[4] = v_transvalue;
2851 params[5] = LLVMBuildTrunc(b, v_transnull,
2852 TypeParamBool, "");
2853
2854 v_fn = llvm_pg_func(mod, "ExecAggCopyTransValue");
2855 v_newval =
2856 l_call(b,
2858 v_fn,
2859 params, lengthof(params),
2860 "");
2861
2862 /* store trans value */
2865
2867 LLVMBuildBr(b, opblocks[opno + 1]);
2868
2869 /* returned datum passed datum, no need to reparent */
2871 }
2872
2873 /* store trans value */
2876
2878
2879 LLVMBuildBr(b, opblocks[opno + 1]);
2880 break;
2881 }
2882
2884 {
2887 int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
2888
2889 LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctSingle");
2892
2895
2898
2901 l_sbool_const(1), ""),
2902 opblocks[opno + 1],
2903 opblocks[jumpdistinct]);
2904 break;
2905 }
2906
2908 {
2911 int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct;
2912
2913 LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctMulti");
2916
2919
2922
2925 l_sbool_const(1), ""),
2926 opblocks[opno + 1],
2927 opblocks[jumpdistinct]);
2928 break;
2929 }
2930
2932 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
2933 v_state, op, v_econtext);
2934 LLVMBuildBr(b, opblocks[opno + 1]);
2935 break;
2936
2938 build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
2939 v_state, op, v_econtext);
2940 LLVMBuildBr(b, opblocks[opno + 1]);
2941 break;
2942
2943 case EEOP_LAST:
2944 Assert(false);
2945 break;
2946 }
2947 }
2948
2950
2951 /*
2952 * Don't immediately emit function, instead do so the first time the
2953 * expression is actually evaluated. That allows to emit a lot of
2954 * functions together, avoiding a lot of repeated llvm and memory
2955 * remapping overhead.
2956 */
2957 {
2958
2960
2961 cstate->context = context;
2962 cstate->funcname = funcname;
2963
2964 state->evalfunc = ExecRunCompiledExpr;
2965 state->evalfunc_private = cstate;
2966 }
2967
2969
2971 INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter,
2972 endtime, starttime);
2973
2974 return true;
2975}
2976
2977/*
2978 * Run compiled expression.
2979 *
2980 * This will only be called the first time a JITed expression is called. We
2981 * first make sure the expression is still up-to-date, and then get a pointer to
2982 * the emitted function. The latter can be the first thing that triggers
2983 * optimizing and emitting all the generated functions.
2984 */
2985static Datum
2987{
2988 CompiledExprState *cstate = state->evalfunc_private;
2989 ExprStateEvalFunc func;
2990
2991 CheckExprStillValid(state, econtext);
2992
2995 cstate->funcname);
2997 Assert(func);
2998
2999 /* remove indirection via this function for future calls */
3000 state->evalfunc = func;
3001
3002 return func(state, econtext, isNull);
3003}
3004
3005static LLVMValueRef
3009{
3015
3017
3018 v_fn = llvm_function_reference(context, b, mod, fcinfo);
3019
3023 v_fcinfo,
3025 "v_fcinfo_isnull");
3027
3029
3030 if (v_fcinfo_isnull)
3032
3033 /*
3034 * Add lifetime-end annotation, signaling that writes to memory don't have
3035 * to be retained (important for inlining potential).
3036 */
3037 {
3039 LLVMValueRef params[2];
3040
3041 params[0] = l_int64_const(lc, sizeof(NullableDatum) * fcinfo->nargs);
3042 params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8TypeInContext(lc)));
3043 l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
3044
3045 params[0] = l_int64_const(lc, sizeof(fcinfo->isnull));
3046 params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
3047 l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
3048 }
3049
3050 return v_retval;
3051}
3052
3053/*
3054 * Implement an expression step by calling the function funcname.
3055 */
3056static LLVMValueRef
3059 int nargs, LLVMValueRef *v_args)
3060{
3062 LLVMValueRef *params;
3063 int argno = 0;
3065
3066 /* cheap pre-check as llvm just asserts out */
3067 if (LLVMCountParams(v_fn) != (nargs + 2))
3068 elog(ERROR, "parameter mismatch: %s expects %d passed %d",
3069 funcname, LLVMCountParams(v_fn), nargs + 2);
3070
3071 params = palloc_array(LLVMValueRef, (2 + nargs));
3072
3073 params[argno++] = v_state;
3074 params[argno++] = l_ptr_const(op, l_ptr(StructExprEvalStep));
3075
3076 for (int i = 0; i < nargs; i++)
3077 params[argno++] = v_args[i];
3078
3079 v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, argno, "");
3080
3081 pfree(params);
3082
3083 return v_ret;
3084}
3085
3086static LLVMValueRef
3088{
3091 LLVMTypeRef param_types[2];
3093
3094 /* variadic pointer argument */
3095 const char *nm = "llvm.lifetime.end.p0";
3096
3098 if (fn)
3099 return fn;
3100
3102 param_types[0] = LLVMInt64TypeInContext(lc);
3103 param_types[1] = l_ptr(LLVMInt8TypeInContext(lc));
3104
3106 lengthof(param_types), false);
3108
3110
3112
3113 return fn;
3114}
#define Assert(condition)
Definition c.h:873
#define lengthof(array)
Definition c.h:803
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:39
#define elog(elevel,...)
Definition elog.h:226
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:70
#define FIELDNO_EXPRSTATE_RESULTSLOT
Definition execnodes.h:105
#define FIELDNO_EXPRCONTEXT_CASENULL
Definition execnodes.h:301
#define FIELDNO_EXPRCONTEXT_INNERTUPLE
Definition execnodes.h:276
#define FIELDNO_EXPRSTATE_FLAGS
Definition execnodes.h:90
#define FIELDNO_EXPRCONTEXT_DOMAINNULL
Definition execnodes.h:307
#define FIELDNO_EXPRCONTEXT_DOMAINDATUM
Definition execnodes.h:305
#define FIELDNO_EXPRCONTEXT_CASEDATUM
Definition execnodes.h:299
#define FIELDNO_EXPRCONTEXT_OLDTUPLE
Definition execnodes.h:311
#define FIELDNO_AGGSTATE_CURPERTRANS
Definition execnodes.h:2437
#define FIELDNO_EXPRSTATE_RESNULL
Definition execnodes.h:97
#define FIELDNO_EXPRCONTEXT_NEWTUPLE
Definition execnodes.h:313
#define FIELDNO_EXPRCONTEXT_AGGNULLS
Definition execnodes.h:295
#define FIELDNO_EXPRSTATE_RESVALUE
Definition execnodes.h:99
#define FIELDNO_AGGSTATE_CURRENT_SET
Definition execnodes.h:2442
#define FIELDNO_EXPRCONTEXT_AGGVALUES
Definition execnodes.h:293
#define FIELDNO_EXPRCONTEXT_OUTERTUPLE
Definition execnodes.h:278
#define FIELDNO_AGGSTATE_ALL_PERGROUPS
Definition execnodes.h:2489
#define FIELDNO_EXPRSTATE_PARENT
Definition execnodes.h:133
#define FIELDNO_EXPRCONTEXT_SCANTUPLE
Definition execnodes.h:274
#define FIELDNO_AGGSTATE_CURAGGCONTEXT
Definition execnodes.h:2434
#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 @172 value
#define INSTR_TIME_SET_CURRENT(t)
Definition instr_time.h:122
#define INSTR_TIME_ACCUM_DIFF(x, y, z)
Definition instr_time.h:184
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:766
int es_jit_flags
Definition execnodes.h:765
uint8 nullflag
Definition execExpr.h:373
bool * anynull
Definition execExpr.h:399
struct ExprEvalStep::@58::@103 agg_presorted_distinctcheck
WindowFuncExprState * wfstate
Definition execExpr.h:684
struct ExprEvalStep::@58::@96 aggref
ExecEvalBoolSubroutine subscriptfunc
Definition execExpr.h:568
struct ExprEvalStep::@58::@64 returningexpr
struct ExprEvalStep::@58::@67 boolexpr
struct ExprEvalStep::@58::@89 hashdatum_initvalue
struct ExprEvalStep::@58::@102 agg_plain_pergroup_nullcheck
AggStatePerTrans pertrans
Definition execExpr.h:731
struct ExprEvalStep::@58::@106 jsonexpr
struct ExprEvalStep::@58::@101 agg_strict_input_check
struct JsonExprState * jsestate
Definition execExpr.h:756
struct ExprEvalStep::@58::@66 func
struct ExprEvalStep::@58::@87 sbsref
struct ExprEvalStep::@58::@81 rowcompare_step
ExecEvalSubroutine paramfunc
Definition execExpr.h:432
FunctionCallInfo fcinfo_data_in
Definition execExpr.h:461
TupleDesc known_desc
Definition execExpr.h:329
NullableDatum * args
Definition execExpr.h:715
struct ExprEvalStep::@58::@62 assign_var
bool * nulls
Definition execExpr.h:531
Datum * resvalue
Definition execExpr.h:310
struct ExprEvalStep::@58::@90 hashdatum
NullableDatum * iresult
Definition execExpr.h:610
const TupleTableSlotOps * kind
Definition execExpr.h:331
struct ExprEvalStep::@58::@73 casetest
struct ExprEvalStep::@58::@68 qualexpr
FunctionCallInfo fcinfo_data
Definition execExpr.h:389
int jumpdistinct
Definition execExpr.h:733
struct ExprEvalStep::@58::@104 agg_trans
FmgrInfo * finfo_in
Definition execExpr.h:460
struct ExprEvalStep::@58::@69 jump
Datum value
Definition execExpr.h:381
struct ExprEvalStep::@58::@82 rowcompare_final
CompareType cmptype
Definition execExpr.h:523
struct ExprEvalStep::@58::@100 agg_deserialize
struct ExprEvalStep::@58::@65 constval
bool * resnull
Definition execExpr.h:311
struct ExprEvalStep::@58::@72 cparam
struct ExprEvalStep::@58::@86 sbsref_subscript
FunctionCallInfo fcinfo_data_out
Definition execExpr.h:458
struct ExprEvalStep::@58::@74 make_readonly
struct ExprEvalStep::@58::@75 iocoerce
union ExprEvalStep::@58 d
Datum init_value
Definition execExpr.h:598
FmgrInfo * finfo
Definition execExpr.h:388
ExprContext * aggcontext
Definition execExpr.h:732
struct ExprEvalStep::@58::@98 window_func
struct ExprEvalStep::@58::@59 fetch
struct ExprEvalStep::@58::@63 assign_tmp
struct ExprEvalStep::@58::@60 var
bool fn_strict
Definition fmgr.h:61
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
Definition fmgr.h:95
int jump_eval_coercion
Definition execnodes.h:1109
Datum value
Definition postgres.h:87
EState * state
Definition execnodes.h:1169
static void * fn(void *arg)
#define FIELDNO_TUPLETABLESLOT_ISNULL
Definition tuptable.h:125
#define FIELDNO_TUPLETABLESLOT_VALUES
Definition tuptable.h:123
#define FIELDNO_TUPLETABLESLOT_NVALID
Definition tuptable.h:118