class YieldableUpdate extends YieldableUpDel {

        final Update statement;
        final Column[] columns;
        final int[] updateColumnIndexes;
        final int columnCount;

        public YieldableUpdate(Update statement, AsyncHandler<AsyncResult<Integer>> asyncHandler) {
            super(statement, asyncHandler, statement.tableFilter, statement.limitExpr,
                    statement.condition);
            this.statement = statement;
            columns = table.getColumns();
            columnCount = columns.length;

            int size = statement.columns.size();
            updateColumnIndexes = new int[size];
            for (int i = 0; i < size; i++) {
                updateColumnIndexes[i] = statement.columns.get(i).getColumnId();
            }
        }

        @Override
        protected int getRightMask() {
            return Right.UPDATE;
        }

        @Override
        protected int getTriggerType() {
            return Trigger.UPDATE;
        }

        @Override
        public int[] getUpdateColumnIndexes() {
            return updateColumnIndexes;
        }

        @Override
        protected boolean upDelRow(Row oldRow) {
            Row newRow = createNewRow(oldRow);
            table.validateConvertUpdateSequence(session, newRow);
            boolean done = false;
            if (table.fireRow()) {
                done = table.fireBeforeRow(session, oldRow, newRow);
            }
            if (!done) {
                updateRow(oldRow, newRow);
            }
            return !done;
        }

        private Row createNewRow(Row oldRow) {
            Row newRow = table.getTemplateRow();
            newRow.setKey(oldRow.getKey()); // 复用原来的行号
            for (int i = 0; i < columnCount; i++) {
                Column column = columns[i];
                Expression newExpr = statement.expressionMap.get(column);
                Value newValue;
                if (newExpr == null) {
                    newValue = oldRow.getValue(i);
                } else if (newExpr == ValueExpression.getDefault()) {
                    newValue = table.getDefaultValue(session, column);
                } else {
                    newValue = column.convert(newExpr.getValue(session));
                }
                newRow.setValue(i, newValue);
            }
            return newRow;
        }

        private void updateRow(Row oldRow, Row newRow) {<FILL_FUNCTION_BODY>}
    }

            onPendingOperationStart();
            table.updateRow(session, oldRow, newRow, updateColumnIndexes, true).onComplete(ar -> {
                if (ar.isSucceeded() && table.fireRow()) {
                    table.fireAfterRow(session, oldRow, newRow, false);
                }
                onPendingOperationComplete(ar);
            });
        
<methods>public void <init>(com.lealone.db.session.ServerSession) ,public int getPriority() ,public boolean isCacheable() ,public void setCondition(com.lealone.sql.expression.Expression) ,public void setLimit(com.lealone.sql.expression.Expression) ,public void setTableFilter(com.lealone.sql.optimizer.TableFilter) ,public int update() <variables>protected com.lealone.sql.expression.Expression condition,protected com.lealone.sql.expression.Expression limitExpr,protected com.lealone.sql.optimizer.TableFilter tableFilter