diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c index 12521e3e46a..62a7e1c37fb 100644 --- a/src/backend/jit/llvm/llvmjit_deform.c +++ b/src/backend/jit/llvm/llvmjit_deform.c @@ -109,22 +109,27 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, */ for (attnum = 0; attnum < desc->natts; attnum++) { - CompactAttribute *att = TupleDescCompactAttr(desc, attnum); + CompactAttribute *catt = TupleDescCompactAttr(desc, attnum); + Form_pg_attribute attr = TupleDescAttr(desc, attnum); /* * If the column is declared NOT NULL then it must be present in every * tuple, unless there's a "missing" entry that could provide a - * non-NULL value for it. That in turn guarantees that the NULL bitmap - * - if there are any NULLable columns - is at least long enough to - * cover columns up to attnum. + * non-NULL value for it or the column is a virtual generated column. + * That in turn guarantees that the NULL bitmap - if there are any + * NULLable columns - is at least long enough to cover columns up to + * attnum. * * Be paranoid and also check !attisdropped, even though the * combination of attisdropped && attnotnull combination shouldn't * exist. */ - if (att->attnullability == ATTNULLABLE_VALID && - !att->atthasmissing && - !att->attisdropped) + if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL) + break; + + if (catt->attnullability == ATTNULLABLE_VALID && + !catt->atthasmissing && + !catt->attisdropped) guaranteed_column_number = attnum; } @@ -392,6 +397,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, for (attnum = 0; attnum < natts; attnum++) { CompactAttribute *att = TupleDescCompactAttr(desc, attnum); + Form_pg_attribute attr = TupleDescAttr(desc, attnum); + LLVMValueRef v_incby; int alignto = att->attalignby; LLVMValueRef l_attno = l_int16_const(lc, attnum); @@ -436,7 +443,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, * into account, because if they're present the heaptuple's natts * would have indicated that a slot_getmissingattrs() is needed. */ - if (att->attnullability != ATTNULLABLE_VALID) + if (att->attnullability != ATTNULLABLE_VALID || + attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL) { LLVMBasicBlockRef b_ifnotnull; LLVMBasicBlockRef b_ifnull; @@ -614,6 +622,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, known_alignment += att->attlen; } else if (att->attnullability == ATTNULLABLE_VALID && + attr->attgenerated != ATTRIBUTE_GENERATED_VIRTUAL && (att->attlen % alignto) == 0) { /*