Re: PG 15 (and to a smaller degree 14) regression due to ExprEvalStep size
Andres Freund <andres@anarazel.de>
Hi,
On 2022-07-27 17:01:13 +0900, Amit Langote wrote:
> Here's an updated version of the patch, with mostly cosmetic changes.
> In particular, I added comments describing the new llvm_compile_expr()
> blobs.
- I've asked a couple times before: Why do we need space for every possible
datatype at once in JsonItemCoercions? Can there be multiple "concurrent"
coercions in process?
The whole coercion stuff just seems incredibly clunky (in a slightly
different shape before this patch). ExecEvalJsonExprItemCoercion() calls
ExecPrepareJsonItemCoercion(), which gets a pointer to one of the per-type
elements in JsonItemCoercionsState, dispatching on the type of the json
object. Then we later call ExecGetJsonItemCoercion() (via a convoluted
path), which again will dispatch on the type (extracting the json object
again afaics!), to then somehow eventually get the coerced value.
I cannot make any sense of this. This code should not have been committed
in this state.
- Looks like there's still some recursive expression states, namely
JsonExprState->{result_coercion, coercions}?
- Looks like the JsonExpr code in ExecInitExprRec() is big enough to
potentially benefit from splitting out into a separate function?
- looks like JsonExprPostEvalState could be moved to execExprInterp.c?
- I ran the patch against LLVM 14 built with assertions enabled, and it
triggers an assertion failure:
#3 0x00007f75d165c242 in __GI___assert_fail (
assertion=0x7f75c278d511 "getOperand(0)->getType() == getOperand(1)->getType() && \"Both operands to ICmp instruction are not of the same type!\"",
file=0x7f75c2780366 "/home/andres/src/llvm-project-14/llvm/include/llvm/IR/Instructions.h", line=1192,
function=0x7f75c27d9dcc "void llvm::ICmpInst::AssertOK()") at assert.c:101
#4 0x00007f75c2b9b25c in llvm::ICmpInst::AssertOK (this=0x55e019290ca0) at /home/andres/src/llvm-project-14/llvm/include/llvm/IR/Instructions.h:1191
#5 0x00007f75c2b9b0ea in llvm::ICmpInst::ICmpInst (this=0x55e019290ca0, pred=llvm::CmpInst::ICMP_EQ, LHS=0x55e019290c10, RHS=0x55e01928ce80, NameStr="")
at /home/andres/src/llvm-project-14/llvm/include/llvm/IR/Instructions.h:1246
#6 0x00007f75c2b93c99 in llvm::IRBuilderBase::CreateICmp (this=0x55e0192894f0, P=llvm::CmpInst::ICMP_EQ, LHS=0x55e019290c10, RHS=0x55e01928ce80, Name="")
at /home/andres/src/llvm-project-14/llvm/include/llvm/IR/IRBuilder.h:2202
#7 0x00007f75c2c1bc5d in LLVMBuildICmp (B=0x55e0192894f0, Op=LLVMIntEQ, LHS=0x55e019290c10, RHS=0x55e01928ce80, Name=0x7f75d0d24cbc "")
at /home/andres/src/llvm-project-14/llvm/lib/IR/Core.cpp:3927
#8 0x00007f75d0d20b1f in llvm_compile_expr (state=0x55e019201380) at /home/andres/src/postgresql/src/backend/jit/llvm/llvmjit_expr.c:2392
...
#19 0x000055e0184c16d4 in exec_simple_query (query_string=0x55e01912f6e0 "SELECT JSON_EXISTS(NULL::jsonb, '$');") at /home/andres/src/postgresql/src/backend/tcop/postgres.c:1204
this triggers easily interactively - which is nice because that allows to
dump the types:
p getOperand(0)->getType()->dump() -> prints i64
p getOperand(1)->getType()->dump() -> prints i32
The immediate issue is that you're setting v_jumpaddrp up as a pointer to a
pointer to size_t - but then compare it to i32.
I first was confused why the code tries to load the jump target
dynamically. But then I saw that the interpreted code sets it dynamically -
why? That's completely unnecessary overhead afaics? There's just two
possible jump targets, no?
- why is EvalJsonPathVar() in execExprInterp.c, when it's only ever called
from within jsonpath_exec.c?
- s/JsobbValue/JsonbValue/
Greetings,
Andres Freund
Commits
-
JSON_TABLE: Add support for NESTED paths and columns
- bb766cde63b4 17.0 landed
-
Add basic JSON_TABLE() functionality
- de3600452b61 17.0 landed
-
Add SQL/JSON query functions
- 6185c9737cf4 17.0 landed
-
Add soft error handling to some expression nodes
- aaaf9449ec6b 17.0 landed
-
Adjust populate_record_field() to handle errors softly
- 1edb3b491bee 17.0 landed
-
Refactor code used by jsonpath executor to fetch variables
- faa2b953ba3b 17.0 landed
-
Add more SQL/JSON constructor functions
- 03734a7fed7d 17.0 landed
-
SQL/JSON: support the IS JSON predicate
- 6ee30209a6f1 16.0 landed
-
SQL/JSON: add standard JSON constructor functions
- 7081ac46ace8 16.0 landed
-
Add static assertion ensuring sizeof(ExprEvalStep) <= 64 bytes
- 78be04e4c672 16.0 landed
-
Remove size increase in ExprEvalStep caused by hashed saops
- 30efc3b5a364 15.0 landed
- fe3caa143937 16.0 landed
-
pgstat: reduce timer overhead by leaving timer running.
- 4a37527fde3c 15.0 landed
- 056cc366fafa 16.0 landed
-
expression eval: Fix EEOP_JSON_CONSTRUCTOR and EEOP_JSONEXPR size.
- 5a1ab894f758 15.0 landed
- 67b26703b415 16.0 landed
-
SQL/JSON query functions
- 1a36bc9dba8e 15.0 cited
-
Speedup ScalarArrayOpExpr evaluation
- 50e17ad281b8 14.0 cited