public virtual void DetermineOrder(Plan plan) { // Set up the order columns Order = new Schema.Order(_requestedOrder.MetaData); Order.IsInherited = false; Schema.OrderColumn newColumn; Schema.OrderColumn column; for (int index = 0; index < _requestedOrder.Columns.Count; index++) { column = _requestedOrder.Columns[index]; newColumn = new Schema.OrderColumn(TableVar.Columns[column.Column], column.Ascending, column.IncludeNils); newColumn.Sort = column.Sort; newColumn.IsDefaultSort = column.IsDefaultSort; Error.AssertWarn(newColumn.Sort != null, "Sort is null"); if (newColumn.IsDefaultSort) { plan.AttachDependency(newColumn.Sort); } else { if (newColumn.Sort.HasDependencies()) { plan.AttachDependencies(newColumn.Sort.Dependencies); } } Order.Columns.Add(newColumn); } Compiler.EnsureOrderUnique(plan, TableVar, Order); }
// A scan order can be any order which includes all the columns in closed conditions, in any order, // followed by all the columns in open conditions, in any order, // if there is a scan condition, it must be the last order column, open or closed protected Schema.Order FindScanOrder(Plan plan) { Schema.Order newOrder; foreach (Schema.Key key in SourceTableVar.Keys) { newOrder = Compiler.OrderFromKey(plan, key); if (IsValidScanOrder(plan, newOrder, _closedConditions, _openConditions, _scanCondition)) { return(newOrder); } } foreach (Schema.Order order in TableVar.Orders) { if (IsValidScanOrder(plan, order, _closedConditions, _openConditions, _scanCondition)) { return(order); } } newOrder = new Schema.Order(); Schema.OrderColumn newOrderColumn; for (int index = 0; index < _closedConditions.Count; index++) { if (!Object.ReferenceEquals(_closedConditions[index], _scanCondition)) { newOrderColumn = new Schema.OrderColumn(_closedConditions[index].Column, true); newOrderColumn.Sort = Compiler.GetUniqueSort(plan, newOrderColumn.Column.DataType); plan.AttachDependency(newOrderColumn.Sort); newOrder.Columns.Add(newOrderColumn); } } for (int index = 0; index < _openConditions.Count; index++) { if (!Object.ReferenceEquals(_openConditions[index], _scanCondition)) { newOrderColumn = new Schema.OrderColumn(_openConditions[index].Column, true); newOrderColumn.Sort = Compiler.GetUniqueSort(plan, newOrderColumn.Column.DataType); plan.AttachDependency(newOrderColumn.Sort); newOrder.Columns.Add(newOrderColumn); } } if (_scanCondition != null) { newOrderColumn = new Schema.OrderColumn(_scanCondition.Column, true); newOrderColumn.Sort = Compiler.GetUniqueSort(plan, newOrderColumn.Column.DataType); plan.AttachDependency(newOrderColumn.Sort); newOrder.Columns.Add(newOrderColumn); } return(newOrder); }
public int EvaluateSort(Schema.OrderColumn orderColumn, object indexValue, object compareValue) { #if USEICOMPARABLE IComparable indexComparable = AIndexValue as IComparable; if (indexComparable != null) { return(indexComparable.CompareTo(ACompareValue) * (AOrderColumn.Ascending ? 1 : -1)); } else { #endif // NOTE: Use currently executing program because the whole point is that this is inner loop sort code. // We don't want to have to use a new program, or Program program = _serverProcess.ExecutingProgram; //LProgram.Stack.PushWindow(0); //try //{ program.Stack.Push(indexValue); program.Stack.Push(compareValue); try { return(((int)orderColumn.Sort.CompareNode.Execute(program)) * (orderColumn.Ascending ? 1 : -1)); } finally { program.Stack.Pop(); program.Stack.Pop(); } //} //finally //{ // LProgram.Stack.PopWindow(); //} #if USEICOMPARABLE } #endif }
protected PlanNode EmitBrowseComparisonNode ( Plan plan, Schema.Order order, bool forward, bool inclusive, int originIndex ) { PlanNode node = null; Schema.OrderColumn originColumn = order.Columns[originIndex]; if (originColumn.Ascending != forward) { if (inclusive && (originIndex == order.Columns.Count - 1)) { node = EmitBrowseColumnNode(plan, originColumn, Instructions.InclusiveLess); } else { node = EmitBrowseColumnNode(plan, originColumn, Instructions.Less); } } else { if (inclusive && (originIndex == order.Columns.Count - 1)) { node = EmitBrowseColumnNode(plan, originColumn, Instructions.InclusiveGreater); } else { node = EmitBrowseColumnNode(plan, originColumn, Instructions.Greater); } } return(node); }
protected Expression EmitBrowseComparisonExpression ( Schema.Order order, bool forward, bool inclusive, int originIndex ) { Expression expression = null; Schema.OrderColumn originColumn = order.Columns[originIndex]; if (originColumn.Ascending != forward) { if (inclusive && (originIndex == order.Columns.Count - 1)) { expression = EmitBrowseColumnExpression(originColumn, Instructions.InclusiveLess); } else { expression = EmitBrowseColumnExpression(originColumn, Instructions.Less); } } else { if (inclusive && (originIndex == order.Columns.Count - 1)) { expression = EmitBrowseColumnExpression(originColumn, Instructions.InclusiveGreater); } else { expression = EmitBrowseColumnExpression(originColumn, Instructions.Greater); } } return(expression); }
// TODO: Compile row types for each index, saving column indexes to prevent the need for lookup during insert, update, and delete. private void Create(IValueManager manager) { TableType = TableVar.DataType; RowType = TableType.RowType; Schema.RowType keyRowType; Schema.RowType dataRowType; // Create the indexes required to store data as described by the given table variable // Determine Fanout, Capacity, Clustering Key Schema.Order clusteringKey = manager.FindClusteringOrder(TableVar); keyRowType = new Schema.RowType(clusteringKey.Columns); dataRowType = new Schema.RowType(); foreach (Schema.Column column in TableVar.DataType.Columns) { if (!clusteringKey.Columns.Contains(column.Name)) { dataRowType.Columns.Add(new Schema.Column(column.Name, column.DataType)); } } // Add an internal identifier for uniqueness of keys in nonunique indexes #if USEINTERNALID _internalIDColumn = new Schema.TableVarColumn(new Schema.Column(InternalIDColumnName, manager.DataTypes.SystemGuid), Schema.TableVarColumnType.InternalID); dataRowType.Columns.Add(_internalIDColumn.Column); #endif // Create the Clustered index ClusteredIndex = new NativeRowTree ( clusteringKey, keyRowType, dataRowType, _fanout, _capacity, true ); // DataLength and DataColumns for all non clustered indexes is the key length and columns of the clustered key dataRowType = keyRowType; // Create non clustered indexes for each key and order (unique sets) Schema.Order key; foreach (Schema.Key nonClusteredKey in TableVar.Keys) { if (!nonClusteredKey.IsSparse && nonClusteredKey.Enforced) { if (!manager.OrderIncludesKey(ClusteredIndex.Key, nonClusteredKey)) { key = manager.OrderFromKey(nonClusteredKey); if (!NonClusteredIndexes.Contains(key)) { keyRowType = new Schema.RowType(key.Columns); NonClusteredIndexes.Add ( new NativeRowTree ( key, keyRowType, dataRowType, _fanout, _capacity, false ) ); } } } else { // This is a potentially non-unique index, so add a GUID to ensure uniqueness of the key in the BTree key = manager.OrderFromKey(nonClusteredKey); #if USEINTERNALID Schema.OrderColumn uniqueColumn = new Schema.OrderColumn(_internalIDColumn, key.IsAscending); uniqueColumn.Sort = manager.GetUniqueSort(uniqueColumn.Column.DataType); key.Columns.Add(uniqueColumn); #endif if (!NonClusteredIndexes.Contains(key)) { keyRowType = new Schema.RowType(key.Columns); NonClusteredIndexes.Add ( new NativeRowTree ( key, keyRowType, dataRowType, _fanout, _capacity, false ) ); } } } foreach (Schema.Order order in TableVar.Orders) { // This is a potentially non-unique index, so add a GUID to ensure uniqueness of the key in the BTree key = new Schema.Order(order); #if USEINTERNALID if (!manager.OrderIncludesOrder(key, clusteringKey)) { Schema.OrderColumn uniqueColumn = new Schema.OrderColumn(_internalIDColumn, order.IsAscending); uniqueColumn.Sort = manager.GetUniqueSort(uniqueColumn.Column.DataType); key.Columns.Add(uniqueColumn); } #endif if (!NonClusteredIndexes.Contains(key)) { keyRowType = new Schema.RowType(key.Columns); NonClusteredIndexes.Add ( new NativeRowTree ( key, keyRowType, dataRowType, _fanout, _capacity, false ) ); } } }
protected PlanNode EmitBrowseColumnNode(Plan plan, Schema.OrderColumn column, string instruction) { PlanNode node = Compiler.EmitBinaryNode ( plan, Compiler.EmitIdentifierNode(plan, column.Column.Name), instruction, Compiler.EmitIdentifierNode(plan, Schema.Object.Qualify(column.Column.Name, Keywords.Origin)) ); if (column.Column.IsNilable && column.IncludeNils) { switch (instruction) { case Instructions.Equal: node = Compiler.EmitBinaryNode ( plan, Compiler.EmitBinaryNode ( plan, EmitBrowseNilNode(plan, column.Column, true), Instructions.And, EmitOriginNilNode(plan, column.Column, true) ), Instructions.Or, node ); break; case Instructions.InclusiveGreater: node = Compiler.EmitBinaryNode ( plan, EmitOriginNilNode(plan, column.Column, true), Instructions.Or, node ); break; case Instructions.Greater: node = Compiler.EmitBinaryNode ( plan, Compiler.EmitBinaryNode ( plan, EmitOriginNilNode(plan, column.Column, true), Instructions.And, EmitBrowseNilNode(plan, column.Column, false) ), Instructions.Or, node ); break; case Instructions.InclusiveLess: node = Compiler.EmitBinaryNode ( plan, EmitBrowseNilNode(plan, column.Column, true), Instructions.Or, node ); break; case Instructions.Less: node = Compiler.EmitBinaryNode ( plan, Compiler.EmitBinaryNode ( plan, EmitBrowseNilNode(plan, column.Column, true), Instructions.And, EmitOriginNilNode(plan, column.Column, false) ), Instructions.Or, node ); break; } } return(node); }
/* * for each column in the order descending * if the current order column is also in the origin * [or] * for each column in the origin less than the current order column * [and] * current origin column = current origin value * * [and] * if the current order column is ascending xor the requested set is forward * if requested set is inclusive and current order column is the last origin column * current order column <= current origin value * else * current order column < current origin value * else * if requested set is inclusive and the current order column is the last origin column * current order column >= current origin value * else * current order column > current origin value * * for each column in the order greater than the current order column * if the current order column does not include nulls * and current order column is not null * else * if the current order column does not include nulls * [and] current order column is not null */ protected Expression EmitBrowseColumnExpression(Schema.OrderColumn column, string instruction) { Expression expression = new BinaryExpression ( new IdentifierExpression(column.Column.Name), instruction, new IdentifierExpression(Schema.Object.Qualify(column.Column.Name, Keywords.Origin)) ); if (column.Column.IsNilable && column.IncludeNils) { switch (instruction) { case Instructions.Equal: expression = new BinaryExpression ( new BinaryExpression ( EmitBrowseNilExpression(column.Column, true), Instructions.And, EmitOriginNilExpression(column.Column, true) ), Instructions.Or, expression ); break; case Instructions.InclusiveGreater: expression = new BinaryExpression ( EmitOriginNilExpression(column.Column, true), Instructions.Or, expression ); break; case Instructions.Greater: expression = new BinaryExpression ( new BinaryExpression ( EmitOriginNilExpression(column.Column, true), Instructions.And, EmitBrowseNilExpression(column.Column, false) ), Instructions.Or, expression ); break; case Instructions.InclusiveLess: expression = new BinaryExpression ( EmitBrowseNilExpression(column.Column, true), Instructions.Or, expression ); break; case Instructions.Less: expression = new BinaryExpression ( new BinaryExpression ( EmitBrowseNilExpression(column.Column, true), Instructions.And, EmitOriginNilExpression(column.Column, false) ), Instructions.Or, expression ); break; } } return(expression); }
protected override DevicePlanNode InternalPrepare(Schema.DevicePlan plan, PlanNode planNode) { if (planNode is BaseTableVarNode) { BaseTableVarNode node = (BaseTableVarNode)planNode; PrepareTableNode(plan, node); node.Order = Compiler.OrderFromKey(plan.Plan, Compiler.FindClusteringKey(plan.Plan, node.TableVar)); return(new DevicePlanNode(node)); } else if ((planNode is OrderNode) && (planNode.Nodes[0] is BaseTableVarNode) && (plan.Plan.CursorContext.CursorType != CursorType.Static)) { OrderNode node = (OrderNode)planNode; BaseTableVarNode tableVarNode = (BaseTableVarNode)planNode.Nodes[0]; Schema.Order tableOrder; bool isSupported = false; foreach (Schema.Key key in tableVarNode.TableVar.Keys) { tableOrder = Compiler.OrderFromKey(plan.Plan, key); if (node.RequestedOrder.Equivalent(tableOrder)) { node.PhysicalOrder = tableOrder; node.ScanDirection = ScanDirection.Forward; isSupported = true; break; } else if (node.RequestedOrder.Equivalent(new Schema.Order(tableOrder, true))) { node.PhysicalOrder = tableOrder; node.ScanDirection = ScanDirection.Backward; isSupported = true; break; } } if (!isSupported) { foreach (Schema.Order order in tableVarNode.TableVar.Orders) { if (node.RequestedOrder.Equivalent(order)) { node.PhysicalOrder = order; node.ScanDirection = ScanDirection.Forward; isSupported = true; break; } else if (node.RequestedOrder.Equivalent(new Schema.Order(order, true))) { node.PhysicalOrder = order; node.ScanDirection = ScanDirection.Backward; isSupported = true; break; } } } if (isSupported) { node.Order = new Schema.Order(); node.Order.MergeMetaData(node.RequestedOrder.MetaData); node.Order.IsInherited = false; Schema.OrderColumn orderColumn; Schema.OrderColumn newOrderColumn; for (int index = 0; index < node.PhysicalOrder.Columns.Count; index++) { orderColumn = node.PhysicalOrder.Columns[index]; newOrderColumn = new Schema.OrderColumn ( node.TableVar.Columns[orderColumn.Column], node.ScanDirection == ScanDirection.Forward ? orderColumn.Ascending : !orderColumn.Ascending ); newOrderColumn.Sort = orderColumn.Sort; newOrderColumn.IsDefaultSort = orderColumn.IsDefaultSort; Error.AssertWarn(newOrderColumn.Sort != null, "Sort is null"); node.Order.Columns.Add(newOrderColumn); } if (!node.TableVar.Orders.Contains(node.Order)) { node.TableVar.Orders.Add(node.Order); } PrepareTableNode(plan, node); PrepareTableNode(plan, tableVarNode); return(new DevicePlanNode(node)); } } else if (planNode is CreateTableVarBaseNode) { plan.Plan.CheckRight(GetRight(Schema.RightNames.CreateStore)); return(new DevicePlanNode(planNode)); } else if (planNode is AlterTableNode) { plan.Plan.CheckRight(GetRight(Schema.RightNames.AlterStore)); AlterTableNode alterTableNode = (AlterTableNode)planNode; if (alterTableNode.AlterTableStatement.CreateColumns.Count > 0) { throw new RuntimeException(RuntimeException.Codes.UnimplementedCreateCommand, "Columns in a memory device"); } if (alterTableNode.AlterTableStatement.DropColumns.Count > 0) { throw new RuntimeException(RuntimeException.Codes.UnimplementedDropCommand, "Columns in a memory device"); } return(new DevicePlanNode(planNode)); } else if (planNode is DropTableNode) { plan.Plan.CheckRight(GetRight(Schema.RightNames.DropStore)); return(new DevicePlanNode(planNode)); } plan.IsSupported = false; return(null); }