private void PerformInsert(Program program, TableNode tableNode, IRow oldRow, IRow newRow, BitArray valueFlags, bool uncheckedValue) { switch (PropagateInsert) { case PropagateAction.True: tableNode.Insert(program, oldRow, newRow, valueFlags, uncheckedValue); break; case PropagateAction.Ensure: case PropagateAction.Ignore: using (Row sourceRow = new Row(program.ValueManager, tableNode.DataType.RowType)) { newRow.CopyTo(sourceRow); using (IRow currentRow = tableNode.Select(program, sourceRow)) { if (currentRow != null) { if (PropagateInsert == PropagateAction.Ensure) { tableNode.Update(program, currentRow, newRow, valueFlags, false, uncheckedValue); } } else { tableNode.Insert(program, oldRow, newRow, valueFlags, uncheckedValue); } } } break; } }
// Update protected override void InternalExecuteUpdate(Program program, IRow oldRow, IRow newRow, BitArray valueFlags, bool checkConcurrency, bool uncheckedValue) { if (PropagateUpdate) { TableNode sourceNode = SourceNode; Row localOldRow = new Row(program.ValueManager, sourceNode.DataType.RowType, (NativeRow)oldRow.AsNative); try { localOldRow.ValuesOwned = false; Row localNewRow = new Row(program.ValueManager, sourceNode.DataType.RowType, (NativeRow)newRow.AsNative); try { localNewRow.ValuesOwned = false; sourceNode.Update(program, localOldRow, localNewRow, valueFlags, checkConcurrency, uncheckedValue); } finally { localNewRow.Dispose(); } } finally { localOldRow.Dispose(); } } }
// Update protected override void InternalExecuteUpdate(Program program, IRow oldRow, IRow newRow, BitArray valueFlags, bool checkConcurrency, bool uncheckedValue) { base.InternalExecuteUpdate(program, oldRow, newRow, valueFlags, checkConcurrency, uncheckedValue); if (PropagateUpdate) { int columnIndex; for (int index = 1; index < Nodes.Count; index++) { Schema.TableVarColumn column = TableVar.Columns[_extendColumnOffset + index - 1]; if (column.ColumnType == Schema.TableVarColumnType.Stored) { columnIndex = newRow.DataType.Columns.IndexOfName(column.Column.Name); if (columnIndex >= 0) { TableNode tableNode = Nodes[index] as TableNode; if (tableNode == null) { ExtractRowNode extractRowNode = Nodes[index] as ExtractRowNode; if (extractRowNode != null) { tableNode = (TableNode)extractRowNode.Nodes[0]; } } if (tableNode == null) { throw new RuntimeException(RuntimeException.Codes.InternalError, "Could not determine update path for extend column."); } bool referencesUpdatedColumn = ReferencesUpdatedColumn(tableNode, valueFlags); // If the value is a row // If the newValue is nil // If the oldValue is not nil // delete the table node // else // If the oldValue is nil // insert the row // else // update the row // If the value is a table // If the newValue is nil // If the oldValue is not nil // delete all rows // else // If the oldValue is nil // insert all rows // else // foreach row in oldvalue // if there is a corresponding row in new value by the clustering key // update the row // else // delete the row // for each row in newvalue // if there is no corresponding row in old value by the clustering key // insert the row if (column.DataType is Schema.IRowType) { IRow oldValue = (IRow)oldRow.GetValue(columnIndex); IRow newValue = (IRow)newRow.GetValue(columnIndex); if (newValue.IsNil) { if (!oldValue.IsNil) { PushRow(program, oldRow); try { tableNode.Delete(program, oldValue, checkConcurrency, uncheckedValue); } finally { PopRow(program); } } } else { if (oldValue.IsNil) { PushRow(program, newRow); try { tableNode.Insert(program, null, newValue, null, uncheckedValue); } finally { PopRow(program); } } else { if (referencesUpdatedColumn) { PushRow(program, oldRow); try { tableNode.Delete(program, oldValue, checkConcurrency, uncheckedValue); } finally { PopRow(program); } PushRow(program, newRow); try { tableNode.Insert(program, null, newValue, null, uncheckedValue); } finally { PopRow(program); } } else { PushRow(program, newRow); try { tableNode.Update(program, oldValue, newValue, null, checkConcurrency, uncheckedValue); } finally { PopRow(program); } } } } } else { TableValue oldValue = (TableValue)oldRow.GetValue(columnIndex); TableValue newValue = (TableValue)newRow.GetValue(columnIndex); if (newValue.IsNil) { if (!oldValue.IsNil) { PushRow(program, oldRow); try { using (ITable oldValueCursor = oldValue.OpenCursor()) { while (oldValueCursor.Next()) { using (IRow oldValueCursorRow = oldValueCursor.Select()) { tableNode.Delete(program, oldValueCursorRow, checkConcurrency, uncheckedValue); } } } } finally { PopRow(program); } } } else { if (referencesUpdatedColumn) { PushRow(program, oldRow); try { using (ITable oldValueCursor = oldValue.OpenCursor()) { while (oldValueCursor.Next()) { using (IRow oldValueCursorRow = oldValueCursor.Select()) { tableNode.Delete(program, oldValueCursorRow, checkConcurrency, uncheckedValue); } } } } finally { PopRow(program); } PushRow(program, newRow); try { using (ITable newValueCursor = newValue.OpenCursor()) { while (newValueCursor.Next()) { using (IRow newValueCursorRow = newValueCursor.Select()) { tableNode.Insert(program, null, newValueCursorRow, null, uncheckedValue); } } } } finally { PopRow(program); } } else { PushRow(program, newRow); try { if (oldValue.IsNil) { using (ITable newValueCursor = newValue.OpenCursor()) { while (newValueCursor.Next()) { using (IRow newValueCursorRow = newValueCursor.Select()) { tableNode.Insert(program, null, newValueCursorRow, null, uncheckedValue); } } } } else { using (ITable oldValueCursor = oldValue.OpenCursor()) { using (ITable newValueCursor = newValue.OpenCursor()) { while (oldValueCursor.Next()) { using (IRow oldValueCursorRow = oldValueCursor.Select()) { if (newValueCursor.FindKey(oldValueCursorRow)) { using (IRow newValueCursorRow = newValueCursor.Select()) { tableNode.Update(program, oldValueCursorRow, newValueCursorRow, null, checkConcurrency, uncheckedValue); } } else { tableNode.Delete(program, oldValueCursorRow, checkConcurrency, uncheckedValue); } } } newValueCursor.Reset(); while (newValueCursor.Next()) { using (IRow newValueCursorRow = newValueCursor.Select()) { if (!oldValueCursor.FindKey(newValueCursorRow)) { tableNode.Insert(program, null, newValueCursorRow, null, uncheckedValue); } } } } } } } finally { PopRow(program); } } } } } } } } }