Exemplo n.º 1
0
func (u *updateNode) Next() (bool, error) {
	next, err := u.run.rows.Next()
	if !next {
		if err == nil {
			// We're done. Finish the batch.
			err = u.tw.finalize()
		}
		return false, err
	}

	if u.run.explain == explainDebug {
		return true, nil
	}

	tracing.AnnotateTrace()

	oldValues := u.run.rows.Values()

	// Our updated value expressions occur immediately after the plain
	// columns in the output.
	updateValues := oldValues[len(u.tw.ru.fetchCols):]
	oldValues = oldValues[:len(u.tw.ru.fetchCols)]

	u.checkHelper.loadRow(u.tw.ru.fetchColIDtoRowIndex, oldValues, false)
	u.checkHelper.loadRow(u.updateColsIdx, updateValues, true)
	if err := u.checkHelper.check(&u.p.evalCtx); err != nil {
		return false, err
	}

	// Ensure that the values honor the specified column widths.
	for i := range updateValues {
		if err := sqlbase.CheckValueWidth(u.tw.ru.updateCols[i], updateValues[i]); err != nil {
			return false, err
		}
	}

	// Update the row values.
	for i, col := range u.tw.ru.updateCols {
		val := updateValues[i]
		if !col.Nullable && val == parser.DNull {
			return false, sqlbase.NewNonNullViolationError(col.Name)
		}
	}

	newValues, err := u.tw.row(append(oldValues, updateValues...))
	if err != nil {
		return false, err
	}

	resultRow, err := u.rh.cookResultRow(newValues)
	if err != nil {
		return false, err
	}
	u.run.resultRow = resultRow

	return true, nil
}
Exemplo n.º 2
0
func (u *updateNode) Next() bool {
	if u.run.done || u.run.err != nil {
		return false
	}

	if !u.run.rows.Next() {
		// We're done. Finish the batch.
		err := u.tw.finalize()
		u.run.err = err
		u.run.done = true
		return false
	}

	tracing.AnnotateTrace()

	oldValues := u.run.rows.Values()

	// Our updated value expressions occur immediately after the plain
	// columns in the output.
	updateValues := oldValues[len(u.tableDesc.Columns):]
	oldValues = oldValues[:len(u.tableDesc.Columns)]

	// Ensure that the values honor the specified column widths.
	for i := range updateValues {
		if err := sqlbase.CheckValueWidth(u.updateCols[i], updateValues[i]); err != nil {
			u.run.err = err
			return false
		}
	}

	// Update the row values.
	for i, col := range u.updateCols {
		val := updateValues[i]
		if !col.Nullable && val == parser.DNull {
			u.run.err = fmt.Errorf("null value in column %q violates not-null constraint", col.Name)
			return false
		}
	}

	newValues, err := u.tw.row(append(oldValues, updateValues...))
	if err != nil {
		u.run.err = err
		return false
	}

	resultRow, err := u.rh.cookResultRow(newValues)
	if err != nil {
		u.run.err = err
		return false
	}
	u.run.resultRow = resultRow

	return true
}
Exemplo n.º 3
0
func (n *insertNode) Next() bool {
	if n.run.done || n.run.err != nil {
		return false
	}

	if !n.run.rows.Next() {
		// We're done. Finish the batch.
		n.run.err = n.tw.finalize()
		n.run.done = true
		return false
	}

	rowVals := n.run.rows.Values()

	// The values for the row may be shorter than the number of columns being
	// inserted into. Generate default values for those columns using the
	// default expressions.
	for i := len(rowVals); i < len(n.insertCols); i++ {
		if n.defaultExprs == nil {
			rowVals = append(rowVals, parser.DNull)
			continue
		}
		d, err := n.defaultExprs[i].Eval(n.p.evalCtx)
		if err != nil {
			n.run.err = err
			return false
		}
		rowVals = append(rowVals, d)
	}

	// Check to see if NULL is being inserted into any non-nullable column.
	for _, col := range n.tableDesc.Columns {
		if !col.Nullable {
			if i, ok := n.insertColIDtoRowIndex[col.ID]; !ok || rowVals[i] == parser.DNull {
				n.run.err = fmt.Errorf("null value in column %q violates not-null constraint", col.Name)
				return false
			}
		}
	}

	// Ensure that the values honor the specified column widths.
	for i := range rowVals {
		if err := sqlbase.CheckValueWidth(n.insertCols[i], rowVals[i]); err != nil {
			n.run.err = err
			return false
		}
	}

	if len(n.checkExprs) > 0 {
		// Populate qvals.
		for ref, qval := range n.qvals {
			// The colIdx is 0-based, we need to change it to 1-based.
			ri, has := n.insertColIDtoRowIndex[sqlbase.ColumnID(ref.colIdx+1)]
			if !has {
				n.run.err = fmt.Errorf("failed to to find column %d in row", sqlbase.ColumnID(ref.colIdx+1))
				return false
			}
			qval.datum = rowVals[ri]
		}
		for _, expr := range n.checkExprs {
			if d, err := expr.Eval(n.p.evalCtx); err != nil {
				n.run.err = err
				return false
			} else if res, err := parser.GetBool(d); err != nil {
				n.run.err = err
				return false
			} else if !res {
				// Failed to satisfy CHECK constraint.
				n.run.err = fmt.Errorf("failed to satisfy CHECK constraint (%s)", expr.String())
				return false
			}
		}
	}

	_, err := n.tw.row(rowVals)
	if err != nil {
		n.run.err = err
		return false
	}

	for i, val := range rowVals {
		if n.run.rowTemplate != nil {
			n.run.rowTemplate[n.run.rowIdxToRetIdx[i]] = val
		}
	}

	resultRow, err := n.rh.cookResultRow(n.run.rowTemplate)
	if err != nil {
		n.run.err = err
		return false
	}
	n.run.resultRow = resultRow

	return true
}
Exemplo n.º 4
0
func (n *insertNode) Next() (bool, error) {
	ctx := context.TODO()
	if next, err := n.run.rows.Next(); !next {
		if err == nil {
			// We're done. Finish the batch.
			err = n.tw.finalize(ctx)
		}
		return false, err
	}

	if n.run.explain == explainDebug {
		return true, nil
	}

	rowVals := n.run.rows.Values()

	// The values for the row may be shorter than the number of columns being
	// inserted into. Generate default values for those columns using the
	// default expressions.
	for i := len(rowVals); i < len(n.insertCols); i++ {
		if n.defaultExprs == nil {
			rowVals = append(rowVals, parser.DNull)
			continue
		}
		d, err := n.defaultExprs[i].Eval(&n.p.evalCtx)
		if err != nil {
			return false, err
		}
		rowVals = append(rowVals, d)
	}

	// Check to see if NULL is being inserted into any non-nullable column.
	for _, col := range n.tableDesc.Columns {
		if !col.Nullable {
			if i, ok := n.insertColIDtoRowIndex[col.ID]; !ok || rowVals[i] == parser.DNull {
				return false, sqlbase.NewNonNullViolationError(col.Name)
			}
		}
	}

	// Ensure that the values honor the specified column widths.
	for i := range rowVals {
		if err := sqlbase.CheckValueWidth(n.insertCols[i], rowVals[i]); err != nil {
			return false, err
		}
	}

	n.checkHelper.loadRow(n.insertColIDtoRowIndex, rowVals, false)
	if err := n.checkHelper.check(&n.p.evalCtx); err != nil {
		return false, err
	}

	_, err := n.tw.row(ctx, rowVals)
	if err != nil {
		return false, err
	}

	for i, val := range rowVals {
		if n.run.rowTemplate != nil {
			n.run.rowTemplate[n.run.rowIdxToRetIdx[i]] = val
		}
	}

	resultRow, err := n.rh.cookResultRow(n.run.rowTemplate)
	if err != nil {
		return false, err
	}
	n.run.resultRow = resultRow

	return true, nil
}