private static UpdatePlan planForInsert()

in modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java [129:352]


    private static UpdatePlan planForInsert(
        QueryDescriptor planKey,
        GridSqlStatement stmt,
        IgniteH2Indexing idx,
        IgniteLogger log,
        boolean forceFillAbsentPKsWithDefaults
    ) throws IgniteCheckedException {
        GridSqlQuery sel = null;

        GridSqlElement target;

        GridSqlColumn[] cols;

        boolean isTwoStepSubqry;

        int rowsNum;

        GridSqlTable tbl;

        GridQueryRowDescriptor desc;

        List<GridSqlElement[]> elRows = null;

        UpdateMode mode;

        if (stmt instanceof GridSqlInsert) {
            mode = UpdateMode.INSERT;

            GridSqlInsert ins = (GridSqlInsert)stmt;

            target = ins.into();

            tbl = DmlAstUtils.gridTableForElement(target);

            GridH2Table h2Tbl = tbl.dataTable();

            assert h2Tbl != null;

            desc = h2Tbl.rowDescriptor();

            cols = ins.columns();

            if (noQuery(ins.rows()))
                elRows = ins.rows();
            else
                sel = DmlAstUtils.selectForInsertOrMerge(cols, ins.rows(), ins.query());

            isTwoStepSubqry = (ins.query() != null);
            rowsNum = isTwoStepSubqry ? 0 : ins.rows().size();
        }
        else if (stmt instanceof GridSqlMerge) {
            mode = UpdateMode.MERGE;

            GridSqlMerge merge = (GridSqlMerge)stmt;

            target = merge.into();

            tbl = DmlAstUtils.gridTableForElement(target);
            desc = tbl.dataTable().rowDescriptor();

            cols = merge.columns();

            if (noQuery(merge.rows()))
                elRows = merge.rows();
            else
                sel = DmlAstUtils.selectForInsertOrMerge(cols, merge.rows(), merge.query());

            isTwoStepSubqry = (merge.query() != null);
            rowsNum = isTwoStepSubqry ? 0 : merge.rows().size();
        }
        else {
            throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']',
                IgniteQueryErrorCode.UNEXPECTED_OPERATION);
        }

        // Let's set the flag only for subqueries that have their FROM specified.
        isTwoStepSubqry &= (sel != null && (sel instanceof GridSqlUnion ||
            (sel instanceof GridSqlSelect && ((GridSqlSelect)sel).from() != null)));

        int keyColIdx = -1;
        int valColIdx = -1;

        boolean hasKeyProps = false;
        boolean hasValProps = false;

        if (desc == null)
            throw new IgniteSQLException("Row descriptor undefined for table '" + tbl.dataTable().getName() + "'",
                IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);

        GridCacheContext<?, ?> cctx = desc.context();

        String[] colNames = new String[cols.length];

        int[] colTypes = new int[cols.length];

        GridQueryTypeDescriptor type = desc.type();

        Set<String> rowKeys = desc.getRowKeyColumnNames();

        boolean onlyVisibleColumns = true;

        for (int i = 0; i < cols.length; i++) {
            GridSqlColumn col = cols[i];

            if (!col.column().getVisible())
                onlyVisibleColumns = false;

            String colName = col.columnName();

            colNames[i] = colName;

            colTypes[i] = col.resultType().type();

            rowKeys.remove(colName);

            int colId = col.column().getColumnId();

            if (desc.isKeyColumn(colId)) {
                keyColIdx = i;

                continue;
            }

            if (desc.isValueColumn(colId)) {
                valColIdx = i;

                continue;
            }

            GridQueryProperty prop = desc.type().property(colName);

            assert prop != null : "Property '" + colName + "' not found.";

            if (prop.key())
                hasKeyProps = true;
            else
                hasValProps = true;
        }

        rowKeys.removeIf(rowKey -> desc.type().property(rowKey).defaultValue() != null);

        boolean fillAbsentPKsWithNullsOrDefaults = type.fillAbsentPKsWithDefaults()
                || forceFillAbsentPKsWithDefaults;

        if (fillAbsentPKsWithNullsOrDefaults && onlyVisibleColumns && !rowKeys.isEmpty()) {
            String[] extendedColNames = new String[rowKeys.size() + colNames.length];
            int[] extendedColTypes = new int[rowKeys.size() + colTypes.length];

            System.arraycopy(colNames, 0, extendedColNames, 0, colNames.length);
            System.arraycopy(colTypes, 0, extendedColTypes, 0, colTypes.length);

            int currId = colNames.length;

            for (String key : rowKeys) {
                Column col = tbl.dataTable().getColumn(key);

                extendedColNames[currId] = col.getName();
                extendedColTypes[currId] = col.getType();

                currId++;
            }

            colNames = extendedColNames;
            colTypes = extendedColTypes;
        }

        verifyDmlColumns(tbl.dataTable(), F.viewReadOnly(Arrays.asList(cols), TO_H2_COL));

        KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true);
        KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false);

        String selectSql = sel != null ? sel.getSQL() : null;

        DmlDistributedPlanInfo distributed = null;

        if (rowsNum == 0 && !F.isEmpty(selectSql)) {
            distributed = checkPlanCanBeDistributed(
                idx,
                planKey,
                selectSql,
                tbl.dataTable().cacheName(),
                log
            );
        }

        List<List<DmlArgument>> rows = null;

        if (elRows != null) {
            assert sel == null;

            rows = new ArrayList<>(elRows.size());

            for (GridSqlElement[] elRow : elRows) {
                List<DmlArgument> row = new ArrayList<>(cols.length);

                for (GridSqlElement el : elRow) {
                    DmlArgument arg = DmlArguments.create(el);

                    row.add(arg);
                }

                rows.add(row);
            }
        }

        return new UpdatePlan(
            mode,
            tbl.dataTable(),
            colNames,
            colTypes,
            keySupplier,
            valSupplier,
            keyColIdx,
            valColIdx,
            selectSql,
            !isTwoStepSubqry,
            rows,
            rowsNum,
            null,
            distributed,
            false,
            fillAbsentPKsWithNullsOrDefaults
        );
    }