当前位置: 首页 > 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. 登录成…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...