当前位置: 首页 > news >正文

Postgresql源码(113)表达式JIT计算简单分析

相关
《Postgresql源码(85)查询执行——表达式解析器分析(select 1+1如何执行)》
《Postgresql源码(113)表达式JIT计算简单分析》

1 普通表达式计算

普通表达式计算发生在优化器preprocess_expression中,会先把能算出来的函数都计算一遍,把值添加到plan中。

#0  ExecInterpExpr (state=0x16188b8, econtext=0x1618df8, isnull=0x7ffcbbb1b6af) at execExprInterp.c:508
#1  0x000000000072b06f in ExecInterpExprStillValid (state=0x16188b8, econtext=0x1618df8, isNull=0x7ffcbbb1b6af) at execExprInterp.c:1870
#2  0x00000000008abc53 in ExecEvalExprSwitchContext (state=0x16188b8, econtext=0x1618df8, isNull=0x7ffcbbb1b6af) at ../../../../src/include/executor/executor.h:355
#3  0x00000000008b33d5 in evaluate_expr (expr=0x15524d8, result_type=23, result_typmod=-1, result_collation=0) at clauses.c:4902
#4  0x00000000008b26f8 in evaluate_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args=0x1552438, funcvariadic=false,func_tuple=0x7f8ed3ebc3f8, context=0x7ffcbbb1ccb0) at clauses.c:4409
#5  0x00000000008b1a47 in simplify_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffcbbb1b8c8, funcvariadic=false,process_args=true, allow_non_const=true, context=0x7ffcbbb1ccb0) at clauses.c:3997
#6  0x00000000008af028 in eval_const_expressions_mutator (node=0x1521488, context=0x7ffcbbb1ccb0) at clauses.c:2551
#7  0x00000000007e7ed9 in expression_tree_mutator_impl (node=0x15214d8, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffcbbb1ccb0) at nodeFuncs.c:3298
#8  0x00000000008b13ec in eval_const_expressions_mutator (node=0x15214d8, context=0x7ffcbbb1ccb0) at clauses.c:3616
#9  0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1521528, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffcbbb1ccb0) at nodeFuncs.c:3384
#10 0x00000000008b13ec in eval_const_expressions_mutator (node=0x1521528, context=0x7ffcbbb1ccb0) at clauses.c:3616
#11 0x00000000008ae720 in eval_const_expressions (root=0x1521648, node=0x1521528) at clauses.c:2183
#12 0x0000000000885d2a in preprocess_expression (root=0x1521648, expr=0x1521528, kind=1) at planner.c:1144
#13 0x0000000000885173 in subquery_planner (glob=0x1520e08, parse=0x1520f18, parent_root=0x0, hasRecursion=false, tuple_fraction=0) at planner.c:811
#14 0x0000000000884293 in standard_planner (parse=0x1520f18, query_string=0x151fe78 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:413
#15 0x000000000088403a in planner (parse=0x1520f18, query_string=0x151fe78 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:281
#16 0x00000000009b5ec0 in pg_plan_query (querytree=0x1520f18, query_string=0x151fe78 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:904
#17 0x00000000009b600c in pg_plan_queries (querytrees=0x15215f8, query_string=0x151fe78 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:996
#18 0x00000000009b638c in exec_simple_query (query_string=0x151fe78 "select 1000+abs(-10000)+100;") at postgres.c:1193
#19 0x00000000009bab95 in PostgresMain (dbname=0x15572f8 "postgres", username=0x151bad8 "mingjie") at postgres.c:4637
#20 0x00000000008f1d6d in BackendRun (port=0x154db80) at postmaster.c:4464
#21 0x00000000008f1706 in BackendStartup (port=0x154db80) at postmaster.c:4192
#22 0x00000000008edfd1 in ServerLoop () at postmaster.c:1782
#23 0x00000000008ed9a1 in PostmasterMain (argc=1, argv=0x1519a80) at postmaster.c:1466
#24 0x00000000007b8201 in main (argc=1, argv=0x1519a80) at main.c:198

1.1 计算select 1000+abs(-10000)+100;

select 1000+abs(-10000)+100;

Query Tree
在这里插入图片描述
优化器处理:ExecInterpExpr过程
在这里插入图片描述

1.1.1 第一步计算abs(-10000)

ExecInterpExpr(gdb) p	*state
$6 = {type = T_ExprState, flags = 6 '\006', resnull = false, resvalue = 0, resultslot = 0x0, steps = 0x16189e8,evalfunc = 0x7288a3 <ExecInterpExpr>, expr = 0x15522f8,                                 → 指向上面FuncExprevalfunc_private = 0x7288a3 <ExecInterpExpr>,	steps_len = 2, steps_alloc = 16, parent = 0x0, ext_params = 0x0, innermost_caseval = 0x0, innermost_casenull = 0x0,innermost_domainval =	0x0, innermost_domainnull = 0x0}

先看第0步,跳转到哪
第一步:EEOP_FUNCEXPR_STRICT
第二步:EEOP_DONE

(gdb) p/x state->steps[0]->opcode
$23 = 0x72914f
(gdb) p/x state->steps[1]->opcode
$30 = 0x72893a(gdb) p reverse_dispatch_table
$24 = {
...
{opcode = 0x72893a <ExecInterpExpr+151>, op = EEOP_DONE},
{opcode = 0x72914f <ExecInterpExpr+2220>, op = EEOP_FUNCEXPR_STRICT}
...
}

当前分支所需数据

(gdb) p state->steps[0]->d.func
$14 = {finfo = 0x1618948, fcinfo_data = 0x1618998, fn_addr = 0xa51c5d <int4abs>, nargs = 1}

进入分支干活,计算abs(-10000)结果

		EEO_CASE(EEOP_FUNCEXPR_STRICT){FunctionCallInfo fcinfo = op->d.func.fcinfo_data;NullableDatum *args = fcinfo->args;int			nargs = op->d.func.nargs;Datum		d;/* strict function, so check for NULL args */for (int argno = 0; argno < nargs; argno++){if (args[argno].isnull){*op->resnull = true;goto strictfail;}}fcinfo->isnull = false;d = op->d.func.fn_addr(fcinfo);  // 用函数地址调用函数拿到结果*op->resvalue = d;*op->resnull = fcinfo->isnull;strictfail:EEO_NEXT();}

(下面内存可参考《Postgresql源码(85)查询执行——表达式解析器分析(select 1+1如何执行)》)
在回忆一下表达式计算ExecInterpExpr函数的过程,核心就是这个op也就是step,这个ExprEvalStep结构体在执行ExecInterpExpr时作为核心结构体中的数据传入,具体在ExprState→steps中保存,这是一个数据,每一个元素代表一次计算,由ExprEvalStep结构记录当前计算的内存:

在这里插入图片描述

1.1.2 第二步计算1000+10000

同上,注意上面第一步和现在的steps_len都是2,也就是都做一次计算。

就是说每次计算都是由eval_const_expressions_mutator遍历树时,发现function节点后,发生的。

(gdb) p *state
$31 = {type = T_ExprState, flags = 6 '\006', resnull = false, resvalue = 0, resultslot = 0x0, steps = 0x16189e8, evalfunc = 0x7288a3 <ExecInterpExpr>, expr = 0x1552398,                 // FuncExpr->args = {Const{1000}, Const{10000}}evalfunc_private = 0x7288a3 <ExecInterpExpr>, steps_len = 2, steps_alloc = 16, parent = 0x0, ext_params = 0x0, innermost_caseval = 0x0, innermost_casenull = 0x0,innermost_domainval = 0x0, innermost_domainnull = 0x0}

1.1.3 第三步计算11000+100

同上

2 JIT表达式计算

2.1 计算select 1000+abs(-10000)+100;

第一次进入jit堆栈jit_compile_expr,state→expr = (FuncExpr)表示abs(-10000)

因为不是parent表达式,不再继续计算

#0  jit_compile_expr (state=0x1deae18) at jit.c:180
#1  0x000000000071fa6b in ExecReadyExpr (state=0x1deae18) at execExpr.c:874
#2  0x000000000071e60b in ExecInitExpr (node=0x1dfabb8, parent=0x0) at execExpr.c:152
#3  0x00000000008b3395 in evaluate_expr (expr=0x1dfabb8, result_type=23, result_typmod=-1, result_collation=0) at clauses.c:4892
#4  0x00000000008b26f8 in evaluate_function (funcid=1397, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args=0x1dfab68, funcvariadic=false, func_tuple=0x7fd9588871a8, context=0x7ffdd8867f20) at clauses.c:4409
#5  0x00000000008b1a47 in simplify_function (funcid=1397, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffdd8865960, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffdd8867f20) at clauses.c:3997
#6  0x00000000008aee93 in eval_const_expressions_mutator (node=0x1cf92e8, context=0x7ffdd8867f20) at clauses.c:2503
#7  0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1cf9338, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3384
#8  0x00000000008b1a05 in simplify_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffdd8866248, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffdd8867f20) at clauses.c:3988
#9  0x00000000008af028 in eval_const_expressions_mutator (node=0x1cf9388, context=0x7ffdd8867f20) at clauses.c:2551
#10 0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1cf9428, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3384
#11 0x00000000008b1a05 in simplify_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffdd8866b38, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffdd8867f20) at clauses.c:3988
#12 0x00000000008af028 in eval_const_expressions_mutator (node=0x1cf9478, context=0x7ffdd8867f20) at clauses.c:2551
#13 0x00000000007e7ed9 in expression_tree_mutator_impl (node=0x1cf94c8, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3298
#14 0x00000000008b13ec in eval_const_expressions_mutator (node=0x1cf94c8, context=0x7ffdd8867f20) at clauses.c:3616
#15 0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1cf9518, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3384
#16 0x00000000008b13ec in eval_const_expressions_mutator (node=0x1cf9518, context=0x7ffdd8867f20) at clauses.c:3616
#17 0x00000000008ae720 in eval_const_expressions (root=0x1cf9638, node=0x1cf9518) at clauses.c:2183
#18 0x0000000000885d2a in preprocess_expression (root=0x1cf9638, expr=0x1cf9518, kind=1) at planner.c:1144
#19 0x0000000000885173 in subquery_planner (glob=0x1cf8df8, parse=0x1cf8f08, parent_root=0x0, hasRecursion=false, tuple_fraction=0) at planner.c:811
#20 0x0000000000884293 in standard_planner (parse=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:413
#21 0x000000000088403a in planner (parse=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:281
#22 0x00000000009b5ec0 in pg_plan_query (querytree=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:904
#23 0x00000000009b600c in pg_plan_queries (querytrees=0x1cf95e8, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:996
#24 0x00000000009b638c in exec_simple_query (query_string=0x1cf7e68 "select 1000+abs(-10000)+100;") at postgres.c:1193
#25 0x00000000009bab95 in PostgresMain (dbname=0x1d2f2e8 "postgres", username=0x1cf3ac8 "mingjie") at postgres.c:4637
#26 0x00000000008f1d6d in BackendRun (port=0x1d25b70) at postmaster.c:4464
#27 0x00000000008f1706 in BackendStartup (port=0x1d25b70) at postmaster.c:4192
#28 0x00000000008edfd1 in ServerLoop () at postmaster.c:1782
#29 0x00000000008ed9a1 in PostmasterMain (argc=1, argv=0x1cf1a70) at postmaster.c:1466
#30 0x00000000007b8201 in main (argc=1, argv=0x1cf1a70) at main.c:198
第二次进入jit堆栈jit_compile_expr,state→expr = (FuncExpr)表示1000+10000

因为不是parent表达式,不再继续计算。

#0  jit_compile_expr (state=0x1deae18) at jit.c:165
#1  0x000000000071fa6b in ExecReadyExpr (state=0x1deae18) at execExpr.c:874
#2  0x000000000071e60b in ExecInitExpr (node=0x1dfac58, parent=0x0) at execExpr.c:152
#3  0x00000000008b3395 in evaluate_expr (expr=0x1dfac58, result_type=23, result_typmod=-1, result_collation=0) at clauses.c:4892
#4  0x00000000008b26f8 in evaluate_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args=0x1dfaac8, funcvariadic=false, func_tuple=0x7fd9588876b8, context=0x7ffdd8867f20) at clauses.c:4409
#5  0x00000000008b1a47 in simplify_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffdd8866248, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffdd8867f20) at clauses.c:3997
#6  0x00000000008af028 in eval_const_expressions_mutator (node=0x1cf9388, context=0x7ffdd8867f20) at clauses.c:2551
#7  0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1cf9428, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3384
#8  0x00000000008b1a05 in simplify_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffdd8866b38, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffdd8867f20) at clauses.c:3988
#9  0x00000000008af028 in eval_const_expressions_mutator (node=0x1cf9478, context=0x7ffdd8867f20) at clauses.c:2551
#10 0x00000000007e7ed9 in expression_tree_mutator_impl (node=0x1cf94c8, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3298
#11 0x00000000008b13ec in eval_const_expressions_mutator (node=0x1cf94c8, context=0x7ffdd8867f20) at clauses.c:3616
#12 0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1cf9518, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3384
#13 0x00000000008b13ec in eval_const_expressions_mutator (node=0x1cf9518, context=0x7ffdd8867f20) at clauses.c:3616
#14 0x00000000008ae720 in eval_const_expressions (root=0x1cf9638, node=0x1cf9518) at clauses.c:2183
#15 0x0000000000885d2a in preprocess_expression (root=0x1cf9638, expr=0x1cf9518, kind=1) at planner.c:1144
#16 0x0000000000885173 in subquery_planner (glob=0x1cf8df8, parse=0x1cf8f08, parent_root=0x0, hasRecursion=false, tuple_fraction=0) at planner.c:811
#17 0x0000000000884293 in standard_planner (parse=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:413
#18 0x000000000088403a in planner (parse=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:281
#19 0x00000000009b5ec0 in pg_plan_query (querytree=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:904
#20 0x00000000009b600c in pg_plan_queries (querytrees=0x1cf95e8, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:996
#21 0x00000000009b638c in exec_simple_query (query_string=0x1cf7e68 "select 1000+abs(-10000)+100;") at postgres.c:1193
#22 0x00000000009bab95 in PostgresMain (dbname=0x1d2f2e8 "postgres", username=0x1cf3ac8 "mingjie") at postgres.c:4637
#23 0x00000000008f1d6d in BackendRun (port=0x1d25b70) at postmaster.c:4464
#24 0x00000000008f1706 in BackendStartup (port=0x1d25b70) at postmaster.c:4192
#25 0x00000000008edfd1 in ServerLoop () at postmaster.c:1782
#26 0x00000000008ed9a1 in PostmasterMain (argc=1, argv=0x1cf1a70) at postmaster.c:1466
#27 0x00000000007b8201 in main (argc=1, argv=0x1cf1a70) at main.c:198
第三次进入jit堆栈jit_compile_expr,state→expr = (FuncExpr)表示11000+100

因为不是parent表达式,不再继续计算。

#0  jit_compile_expr (state=0x1deae18) at jit.c:165
#1  0x000000000071fa6b in ExecReadyExpr (state=0x1deae18) at execExpr.c:874
#2  0x000000000071e60b in ExecInitExpr (node=0x1dfad98, parent=0x0) at execExpr.c:152
#3  0x00000000008b3395 in evaluate_expr (expr=0x1dfad98, result_type=23, result_typmod=-1, result_collation=0) at clauses.c:4892
#4  0x00000000008b26f8 in evaluate_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args=0x1dfacf8, funcvariadic=false, func_tuple=0x7fd9588876b8, context=0x7ffdd8867f20) at clauses.c:4409
#5  0x00000000008b1a47 in simplify_function (funcid=177, result_type=23, result_typmod=-1, result_collid=0, input_collid=0, args_p=0x7ffdd8866b38, funcvariadic=false, process_args=true, allow_non_const=true, context=0x7ffdd8867f20) at clauses.c:3997
#6  0x00000000008af028 in eval_const_expressions_mutator (node=0x1cf9478, context=0x7ffdd8867f20) at clauses.c:2551
#7  0x00000000007e7ed9 in expression_tree_mutator_impl (node=0x1cf94c8, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3298
#8  0x00000000008b13ec in eval_const_expressions_mutator (node=0x1cf94c8, context=0x7ffdd8867f20) at clauses.c:3616
#9  0x00000000007e82e4 in expression_tree_mutator_impl (node=0x1cf9518, mutator=0x8ae95b <eval_const_expressions_mutator>, context=0x7ffdd8867f20) at nodeFuncs.c:3384
#10 0x00000000008b13ec in eval_const_expressions_mutator (node=0x1cf9518, context=0x7ffdd8867f20) at clauses.c:3616
#11 0x00000000008ae720 in eval_const_expressions (root=0x1cf9638, node=0x1cf9518) at clauses.c:2183
#12 0x0000000000885d2a in preprocess_expression (root=0x1cf9638, expr=0x1cf9518, kind=1) at planner.c:1144
#13 0x0000000000885173 in subquery_planner (glob=0x1cf8df8, parse=0x1cf8f08, parent_root=0x0, hasRecursion=false, tuple_fraction=0) at planner.c:811
#14 0x0000000000884293 in standard_planner (parse=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:413
#15 0x000000000088403a in planner (parse=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at planner.c:281
#16 0x00000000009b5ec0 in pg_plan_query (querytree=0x1cf8f08, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:904
#17 0x00000000009b600c in pg_plan_queries (querytrees=0x1cf95e8, query_string=0x1cf7e68 "select 1000+abs(-10000)+100;", cursorOptions=2048, boundParams=0x0) at postgres.c:996
#18 0x00000000009b638c in exec_simple_query (query_string=0x1cf7e68 "select 1000+abs(-10000)+100;") at postgres.c:1193
#19 0x00000000009bab95 in PostgresMain (dbname=0x1d2f2e8 "postgres", username=0x1cf3ac8 "mingjie") at postgres.c:4637
#20 0x00000000008f1d6d in BackendRun (port=0x1d25b70) at postmaster.c:4464
#21 0x00000000008f1706 in BackendStartup (port=0x1d25b70) at postmaster.c:4192
#22 0x00000000008edfd1 in ServerLoop () at postmaster.c:1782
#23 0x00000000008ed9a1 in PostmasterMain (argc=1, argv=0x1cf1a70) at postmaster.c:1466
#24 0x00000000007b8201 in main (argc=1, argv=0x1cf1a70) at main.c:198
第四次进入jit堆栈jit_compile_expr,state→expr = (List)记录TargetEntry

TargetEntry的expr记录结果11100

{ xpr = {type = T_TargetEntry}, expr = Const{constvalue = 11100} ,resno = 1, resname = 0xcbfb88 "?column?", ressortgroupref = 0, resorigtbl = 0, resorigcol = 0, resjunk = false}

进入jit_compile_expr→llvm_compile_expr开始编译表达式

#0  llvm_compile_expr (state=0x1deb218) at llvmjit_expr.c:80
#1  0x0000000000bd3698 in jit_compile_expr (state=0x1deb218) at jit.c:177
#2  0x000000000071fa6b in ExecReadyExpr (state=0x1deb218) at execExpr.c:874
#3  0x000000000071eecb in ExecBuildProjectionInfo (targetList=0x1dfb890, econtext=0x1deaf40, slot=0x1deb130, parent=0x1deae30, inputDesc=0x0) at execExpr.c:479
#4  0x0000000000749d1b in ExecAssignProjectionInfo (planstate=0x1deae30, inputDesc=0x0) at execUtils.c:547
#5  0x00000000007827d0 in ExecInitResult (node=0x1dfb7b0, estate=0x1deac08, eflags=32) at nodeResult.c:221
#6  0x00000000007403d1 in ExecInitNode (node=0x1dfb7b0, estate=0x1deac08, eflags=32) at execProcnode.c:167
#7  0x0000000000735daf in InitPlan (queryDesc=0x1d1fb98, eflags=32) at execMain.c:968
#8  0x0000000000734c85 in standard_ExecutorStart (queryDesc=0x1d1fb98, eflags=32) at execMain.c:266
#9  0x00000000007349fa in ExecutorStart (queryDesc=0x1d1fb98, eflags=0) at execMain.c:145
#10 0x00000000009bc3dc in PortalStart (portal=0x1da1368, params=0x0, eflags=0, snapshot=0x0) at pquery.c:517
#11 0x00000000009b6419 in exec_simple_query (query_string=0x1cf7e68 "select 1000+abs(-10000)+100;") at postgres.c:1235
#12 0x00000000009bab95 in PostgresMain (dbname=0x1d2f2e8 "postgres", username=0x1cf3ac8 "mingjie") at postgres.c:4637
#13 0x00000000008f1d6d in BackendRun (port=0x1d25b70) at postmaster.c:4464
#14 0x00000000008f1706 in BackendStartup (port=0x1d25b70) at postmaster.c:4192
#15 0x00000000008edfd1 in ServerLoop () at postmaster.c:1782
#16 0x00000000008ed9a1 in PostmasterMain (argc=1, argv=0x1cf1a70) at postmaster.c:1466
#17 0x00000000007b8201 in main (argc=1, argv=0x1cf1a70) at main.c:198

llvm_compile_expr函数从功能来看是严格对标ExecInterpExpr表达式计算的,例如计算函数表达式的结果EEOP_FUNCEXPR_STRICT分支:
在这里插入图片描述

4 用例

set max_parallel_workers_per_gather to 0;
set jit_expressions to on;
set jit_tuple_deforming to on;
set jit_above_cost to 0;
set jit_inline_above_cost to 0;
set jit_optimize_above_cost to 0;
explain analyze select abs(-10000)+1000+100;
select 1000+abs(-10000)+100;

相关文章:

Postgresql源码(113)表达式JIT计算简单分析

相关 《Postgresql源码&#xff08;85&#xff09;查询执行——表达式解析器分析&#xff08;select 11如何执行&#xff09;》 《Postgresql源码&#xff08;113&#xff09;表达式JIT计算简单分析》 1 普通表达式计算 普通表达式计算发生在优化器preprocess_expression中&am…...

CMU15-213 课程笔记 04-Floating Point

文章目录 浮点数如何用二进制表示IEEE 浮点数标准IEEE 浮点数实现IEEE 浮点数在内存里 E exp - bias 计算指数M 1.xxx 尾数计算举例&#xff1a;对一个浮点数进行转换一些关于浮点数的计算等等 浮点数如何用二进制表示 计算机内部的浮点数不是这样存在内存里的&#xff08;至…...

DockerKubernetes ❀ Service下Port端口区分

文章目录 概述案例 概述 在Kubernetes中&#xff0c;Service&#xff08;svc&#xff09;是一种抽象机制&#xff0c;用于将一组 Pod 暴露给其他应用程序或服务。Service 可以有三种类型的端口&#xff1a; nodePort&#xff1a;这是 Service 在节点上公开的端口。可以使用此…...

【C++】笔试训练(一)

目录 一、选择题二、编程1、组队竞赛2、删除公共字符 一、选择题 1、以下for循环的执行次数是&#xff08;&#xff09; for (int x 0, y 0; (y 123) && (x < 4); x);A 是无限循环 B 循环次数不定 C 4次 D 3次 答案&#xff1a;C 2、以下程序的运行结果是&…...

数据结构与算法之集合: Leetcode 349. 两个数组的交集 (Typescript版)

两个数组的交集 https://leetcode.cn/problems/intersection-of-two-arrays/description/ 描述 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1 输入&#xff1a;nums1 [1,2,…...

Unity 内存性能分析器 (Memory Profiler)

一、 安装 安装有两种方式一&#xff1a; add package : com.unity.memoryprofiler方式二&#xff1a; From Packages : Unity Registry 搜索 Memory Profiler 二、 使用 打开&#xff1a;Windows - > Analysis - > Memory Profiler 打开MemoryProfiler界面&#xff0…...

前端携带Bearer Token

前端携带Bearer Token 在前端使用 axios 发送请求时&#xff0c;可以通过设置请求头来携带 Bearer Token。Bearer Token 是一种常用的身份验证方式&#xff0c;它通常用于 OAuth2 授权流程中。 要在 axios 中携带 Bearer Token&#xff0c;可以通过设置 Authorization 请求头…...

leetcode 周赛 364

参考视频&#xff1a; 单调栈【力扣周赛 364】 文章目录 8048. 最大二进制奇数100049. 美丽塔 I100048. 美丽塔 II100047. 统计树中的合法路径数目 8048. 最大二进制奇数 题目链接 给你一个 二进制 字符串 s &#xff0c;其中至少包含一个 1 。 你必须按某种方式 重新排列 字…...

开机自启动Linux and windows

1、背景 服务器由于更新等原因重启&#xff0c;部署到该服务上的响应的应用需要自启动 2、Linux 2.1 方式一 编写启动应用的sh脚本授权该脚本权限 chmod 777 xxx.sh 修改rc.loacl 位置&#xff1a;/etc/rc.local 脚本&#xff1a;sh /home/xxxx.sh & 授权rc.local …...

科技云报道:大模型的阴面:无法忽视的安全隐忧

科技云报道原创。 在AI大模型的身上&#xff0c;竟也出现了“to be or not to be”问题。 争议是伴随着大模型的能力惊艳四座而来的&#xff0c;争议的核心问题在于安全。安全有两个方面&#xff0c;一个是大模型带来的对人类伦理的思考&#xff0c;一个是大模型本身带来的隐…...

2023年前端流行什么技术和框架了?

Web前端三大主流框架有React、Vue.js和Angular&#xff0c;由于接触过Vue.js&#xff0c;接下来主讲最新的Vue3.0&#xff01; Vue3.0作为最新版本的Vue.js框架&#xff0c;拥有更强大的性能和更丰富的功能&#xff0c;为低代码开发平台注入了全新的活力。而JNPF快速开发平台作…...

Nginx 背锅解析漏洞

Nginx 背锅解析漏洞 文章目录 Nginx 背锅解析漏洞1 在线漏洞解读:2 环境搭建3 影响版本&#xff1a;4 漏洞复现4.1 访问页面4.2 上传文件 4.3 上传失败4.4 使用bp进行分析包4.5 对返回图片位置进行访问4.6 执行php代码技巧-图片后缀加./php4.7 分析原因 --》cgi.fix_pathinfo--…...

AI与传统数据库 - ChatGPT风过之后 | 从Duet AI说开来

作者&#xff1a;Ni Demai&#xff0c;是NineData数据库产品专家&#xff0c;曾任阿里云数据库国际产品总负责人&#xff0c;华为高斯 GaussDB 创始团队核心架构师&#xff0c;IBM Db2 资深研发工程师。 Demai 专注 Cloud-Native database 架构设计&#xff0c;分析型 MPP&…...

L1-032 Left-pad C++解法

一、题目再现 根据新浪微博上的消息&#xff0c;有一位开发者不满NPM&#xff08;Node Package Manager&#xff09;的做法&#xff0c;收回了自己的开源代码&#xff0c;其中包括一个叫left-pad的模块&#xff0c;就是这个模块把javascript里面的React/Babel干瘫痪了。这是个…...

Python 用列表实现模拟手机通讯录(简易版)

"""列表实现好友管理系统知识点&#xff1a;1、列表存储信息2、列表增删改查3、嵌套循环4、字符串分割和拼接&#xff08;重点&#xff09;5、列表索引"""# 暂存好友信息&#xff08;程序结束数据删除&#xff09; friend_info list()input_buf…...

macOS使用官方安装包安装python

新手程序员可能想知道如何在 Mac 上正确安装 Python&#xff0c;这里介绍在 macOS 上安装 Python 的方法。 操作步骤 1.从 Python 官方网站 (python.org) 下载最新的 Python 版本. 单击 macOS 链接并选择最新的 Python 版本。 2.下载完成后&#xff0c;双击包开始安装Python…...

如何重装Windows Mirosoft Store

重装Windows Mirosoft Store 如何重装Windows Mirosoft Store呢&#xff1f;如何下载Windows Mirosoft Store呢&#xff1f;Windows Mirosoft Store不见了咋办&#xff1f;Windows 自带软件不见了咋办等等&#xff1f;写在前面 1.文件准备2.安装 如何重装Windows Mirosoft Stor…...

软考高级系统架构设计师系列论文真题七:基于构件的软件开发

软考高级系统架构设计师系列论文真题七:基于构件的软件开发 一、基于构件的软件开发二、找准核心论点三、理论素材准备四、精品范文赏析1.摘要2.正文3.总结软考高级系统架构设计师系列论文之:百篇软考高级架构设计师论文范文软考高级系统架构设计师系列之:论文题目类型、论文…...

git rebase 修改中间的commit

0. 前言 今天在移植最新版本 kfence 功能的时候&#xff0c;一共需要移植大概40多个 patch&#xff0c;中间有很多patch 存在冲突&#xff0c;需要手动修改后才能合并。当所有的patch 都合并完成进行编译的时候&#xff0c;发现其中一个 patch 手动合并出了个错误。 假如共有…...

登录业务实现 - token登录鉴权

登录业务实现&#xff1a; 登录成功/失败实现 -> pinia管理用户数据及数据持久化 -> 不同登录状态的模板适配 -> 请求拦截器携带token&#xff08;登录鉴权&#xff09; -> 退出登录实现 -> token失效&#xff08;401响应拦截&#xff09; 1. 登录成…...

H3C IRF 四台交换机堆叠实战:环型拓扑配置详解

1. 四台H3C交换机IRF堆叠入门指南 第一次接触H3C交换机的IRF堆叠功能时&#xff0c;我完全被它的强大所震撼。简单来说&#xff0c;IRF&#xff08;Intelligent Resilient Framework&#xff09;技术可以把多台物理交换机虚拟成一台逻辑设备&#xff0c;不仅简化管理&#xff…...

Qt5.14.2与VS2019整合开发避坑指南(从安装到第一个GUI项目)

Qt5.14.2与VS2019整合开发避坑指南&#xff08;从安装到第一个GUI项目&#xff09; 在Windows平台进行Qt开发时&#xff0c;Visual Studio作为强大的IDE环境&#xff0c;与Qt框架的结合能够显著提升开发效率。本文将深入剖析Qt5.14.2与VS2019整合过程中的关键环节&#xff0c;从…...

League Akari:英雄联盟玩家的终极自动化工具包

League Akari&#xff1a;英雄联盟玩家的终极自动化工具包 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari 是一款基于官方 LCU A…...

Arduino串口乱码?波特率选9600还是115200?一次讲清串口通信的配置与避坑指南

Arduino串口通信终极指南&#xff1a;从波特率选择到实战避坑 当你第一次在Arduino串口监视器看到一堆乱码时&#xff0c;那种挫败感我深有体会。串口通信作为Arduino与外界对话的核心通道&#xff0c;其稳定性直接影响项目成败。本文将带你深入串口通信的底层逻辑&#xff0c…...

颠覆级植物大战僵尸修改工具:一站式资源管理与战局掌控解决方案

颠覆级植物大战僵尸修改工具&#xff1a;一站式资源管理与战局掌控解决方案 【免费下载链接】pvztoolkit 植物大战僵尸 PC 版综合修改器 项目地址: https://gitcode.com/gh_mirrors/pv/pvztoolkit 还在为植物大战僵尸中阳光不足而焦虑吗&#xff1f;面对海量僵尸浪潮却束…...

RT-Thread PM组件实战:手把手教你为STM32L4移植低功耗驱动(含RTC时间补偿)

RT-Thread PM组件深度实战&#xff1a;STM32L4低功耗移植与RTC时间补偿全解析 1. 低功耗设计的工程挑战与解决方案 在电池供电的嵌入式设备开发中&#xff0c;我们常常面临一个核心矛盾&#xff1a;如何平衡系统性能与能耗。以智能水表为例&#xff0c;常规模式下MCU工作电流可…...

2026年OpenClaw怎么部署?京东云零基础2分钟安装及百炼APIKey配置流程

2026年OpenClaw怎么部署&#xff1f;京东云零基础2分钟安装及百炼APIKey配置流程。OpenClaw&#xff08;曾用名Clawdbot&#xff09;是一款轻量化、可扩展的开源AI智能体执行框架&#xff0c;支持自然语言指令驱动、多模型灵活切换与全场景任务自动化。对于新手而言&#xff0c…...

Phi-3-mini-4k-instruct-gguf作品展:面向开发者的技术文档摘要生成样例

Phi-3-mini-4k-instruct-gguf作品展&#xff1a;面向开发者的技术文档摘要生成样例 1. 模型简介 Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本。这个经过优化的模型特别适合处理问答、文本改写、摘要整理和简短创作等任务。作为开发者工具&…...

避坑指南:pyzbar识别模糊二维码的5种图像预处理技巧(Python+OpenCV)

提升pyzbar识别率&#xff1a;5种图像预处理技术解决模糊二维码难题 1. 模糊二维码识别的核心挑战 在现实应用中&#xff0c;二维码识别经常遇到各种图像质量问题。我曾在一个物流仓储项目中亲眼目睹&#xff0c;由于包装反光和运输磨损&#xff0c;标准识别流程的失败率高达40…...

HARMONYOS应用实例261:分段函数绘制

分段函数绘制 功能:定义分段函数规则,自动绘制不连续的函数图像。 支持创建多个分段函数,每个分段可以是不同类型 支持三种函数类型:一次函数、二次函数、常量函数 可调节每个分段的函数系数(a、b、c) 可设置每个分段的定义域(起点和终点) 可控制端点是否包含(开区间或…...