Thread

  1. Re: on_error table, saving error info to a table

    jian he <jian.universality@gmail.com> — 2026-05-11T02:06:23Z

    On Wed, May 6, 2026 at 4:08 PM jian he <jian.universality@gmail.com> wrote:
    >
    > v9-0002: Introduce a (ModifyTableContext *) field in CopyFromStateData.
    > Initialize all useful subordinate structures, including such as
    > ModifyTableState, EState, and ModifyTableState->ResultRelInfo.  Set
    > cstate->escontext->details_wanted to true to ensure that all input conversion
    > error metadata is captured in cstate->escontext.  Use this metadata to construct
    > a TupleTableSlot, and then delegate the remaining processing to ExecInsert.
    >
    > Before calling ExecInsert() to insert error metadata into the ERROR_TABLE, we
    > must first populate a ModifyTableState, similar to how it is done in
    > ExecInitModifyTable.
    >
    > By comparing side-by-side with ExecInitModifyTable, it is ok to populate the
    > necessary information for the ERROR_TABLE using the following functions:
    > ExecInitRangeTable, ExecInitResultRelation, ExecOpenIndices, and
    > CheckValidResultRel.
    > This will allow the ERROR_TABLE to safely use ExecInsert().
    >
    
    example
    CREATE TABLE t(a int);
    INSERT INTO t VALUES (1);
    
    Execution flow:
    ProcessQuery:
        queryDesc = CreateQueryDesc(plan, sourceText,
                                    GetActiveSnapshot(), InvalidSnapshot,
                                    dest, params, queryEnv, 0);
    
    CreateQueryDesc:
        qd->snapshot = RegisterSnapshot(snapshot);
    
    standard_ExecutorStart:
        estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
    
    For COPY FROM, PortalRunUtility -> ProcessUtility ->
    standard_ProcessUtility -> DoCopy ensures that an ActiveSnapshot
    is available through PortalRunUtility()->PlannedStmtRequiresSnapshot().
    
    Therefore, I think it is OK for the CopyFrom function to register a
    active snapshot
    (EState->es_snapshot) during constructing the EState, in case snapshot access is
    needed later.
    
        EState *estate = CreateExecutorState(); /* for ExecConstraints() */
    
    Add:
        estate->es_snapshot =
            RegisterSnapshot(GetActiveSnapshot());
        estate->es_crosscheck_snapshot =
            RegisterSnapshot(InvalidSnapshot);
    
    Similarly, it would be better let
    CopyFromStateData->ModifyTableContext->EState->es_snapshot
    also Register the current ActiveSnapshot.
    Just in case the ExecInsert function needs to use it.
    
    In the attached v10, the code flow for inserting content into the error-saving
    table involves constructing an EState, while the population and release of its
    subfields align more closely with how ExecutorStart, ExecutorFinish,
    and ExecutorEnd deal with EState.
    
    
    
    --
    jian
    https://www.enterprisedb.com/