/// <summary> /// prase the filter collection and get an execution plan. /// </summary> /// <returns></returns> public static ExecutionPlan GetExecutionPlan(Query query) { ExecutionPlan executionplan = new ExecutionPlan(); ITableIndex startindex = null; if (!string.IsNullOrEmpty(query.OrderByFieldName)) { startindex = query.table.Indexs.Find(o => o.FieldName == query.OrderByFieldName); if (startindex == null) { executionplan.RequireOrderBy = true; } } // find other where fields...... if (startindex == null) { startindex = query.table.Indexs.Find(o => o.IsSystem); } if (!string.IsNullOrEmpty(query.OrderByFieldName) && !executionplan.RequireOrderBy) { Range <byte[]> range = getRange(query.OrderByFieldName, query.items); if (range != null) { executionplan.startCollection = startindex.GetCollection(range.lower, range.upper, range.lowerOpen, range.upperOpen, query.Ascending); } else { executionplan.startCollection = startindex.AllItems(query.Ascending); } } else { executionplan.startCollection = startindex.AllItems(query.Ascending); } // check all index fields that has been used in the filter. foreach (var item in query.table.Indexs) { if (item.FieldName != startindex.FieldName) { Range <byte[]> indexrange = getRange(item.FieldName, query.items); if (indexrange != null) { executionplan.indexRanges.Add(item.FieldName, indexrange); } } } // now the left columns.. foreach (var item in query.items) { var column = query.table.ObjectConverter.Fields.Find(o => o.FieldName == item.FieldOrProperty); if (column != null) { ColumnScan colplan = new ColumnScan(); colplan.ColumnName = column.FieldName; colplan.relativeStartPosition = column.RelativePosition; colplan.length = column.Length; colplan.Evaluator = ColumnEvaluator.GetEvaluator(column.ClrType, item.Compare, item.Value, column.Length); executionplan.scanColumns.Add(colplan); } else { throw new Exception("filter field must be column with fixed len"); } } // the left column query. foreach (var item in query.InItems) { var column = query.table.ObjectConverter.Fields.Find(o => o.FieldName == item.Key); if (column != null) { ColumnScan colplan = new ColumnScan(); colplan.ColumnName = column.FieldName; colplan.relativeStartPosition = column.RelativePosition; colplan.length = column.Length; colplan.Evaluator = ColumnInEvaluator.GetInEvaluator(column.ClrType, item.Value, column.Length); executionplan.scanColumns.Add(colplan); } else { throw new Exception("filter field must be a column with fixed length"); } } /// for the methods calls. foreach (var item in query.calls) { MemberExpression memberaccess = null; foreach (var xitem in item.Arguments) { if (xitem.NodeType == ExpressionType.MemberAccess) { memberaccess = xitem as MemberExpression; } } if (memberaccess == null) { throw new Exception("Method call require use one of the Fields or Property as parameters"); } string fieldname = memberaccess.Member.Name; var column = query.table.ObjectConverter.Fields.Find(o => o.FieldName == fieldname); if (column != null) { ColumnScan colplan = new ColumnScan(); colplan.ColumnName = column.FieldName; colplan.relativeStartPosition = column.RelativePosition; colplan.length = column.Length; colplan.Evaluator = ColumnMethodCallEvaluator.GetMethodEvaluator(column.ClrType, column.Length, item); executionplan.scanColumns.Add(colplan); } else { throw new Exception("methed call parameter must be a column, add the field to colomn creating creating the store, otherwise use the fullscan option"); } } return(executionplan); }