public FilterContext(DataFilter owner, Resultset source, Object filterPredicate, QueryContext queryContext, Object[] parameters) : base(owner, source, queryContext, parameters) { _source = source; _compiledBody = new FunctionLink(); List<ColumnBinding> bindings = new List<ColumnBinding>(); ExpressionTransformer transformer = new ExpressionTransformer(bindings); foreach (RowType.TypeInfo ti in source.RowType.Fields) foreach (RowType.TypeInfo nested_ti in ti.NestedType.Fields) if (!nested_ti.IsHidden) { ColumnBinding b = new ColumnBinding(); b.typecode = Type.GetTypeCode(nested_ti.DataType); b.rnum = ti.Ordinal; b.TableName = ti.Name; b.Name = nested_ti.Name; b.fieldType = nested_ti; b.natural = nested_ti.IsNatural; b.container = nested_ti.IsContainer; b.caseSensitive = nested_ti.IsCaseSensitive; b.data = new SymbolLink(nested_ti.DataType); bindings.Add(b); if (nested_ti.IsContainer) transformer.NeedTransform = true; } LispExecutive.Enter(_resolver = new DataResolver(new Binder(bindings))); if (transformer.NeedTransform) _filterPredicate = transformer.Process(filterPredicate); else _filterPredicate = filterPredicate; }
public Binder(RowType.TypeInfo[] fields) { List<ColumnBinding> list = new List<ColumnBinding>(); foreach (RowType.TypeInfo ti in fields) if (ti.NestedType == null) { if (!ti.IsHidden) { ColumnBinding b = new ColumnBinding(); b.Name = ti.Name; b.rnum = ti.Ordinal; b.snum = -1; b.fieldType = ti; b.caseSensitive = ti.IsCaseSensitive; list.Add(b); } } else foreach (RowType.TypeInfo ti_det in ti.NestedType.Fields) { if (!ti.IsHidden) { ColumnBinding b = new ColumnBinding(); b.TableName = ti.Name; b.Name = ti_det.Name; b.rnum = ti.Ordinal; b.snum = ti_det.Ordinal; b.caseSensitive = ti_det.IsCaseSensitive; b.fieldType = ti_det; list.Add(b); } } _columnBinding = list.ToArray(); FlagAmbiguos(); }
public override Resultset Get(QueryContext queryContext, object[] parameters) { // Prepare bindings Resultset source = ChildNodes[0].Get(queryContext, parameters); List<ColumnBinding> bindings = new List<ColumnBinding>(); ExpressionTransformer transformer = new ExpressionTransformer(bindings); foreach (RowType.TypeInfo ti in source.RowType.Fields) foreach (RowType.TypeInfo nested_ti in ti.NestedType.Fields) if (!nested_ti.IsHidden && nested_ti.IsNatural) { ColumnBinding b = new ColumnBinding(); b.typecode = Type.GetTypeCode(nested_ti.DataType); b.rnum = ti.Ordinal; b.TableName = ti.Name; b.Name = nested_ti.Name; b.fieldType = nested_ti; b.natural = nested_ti.IsNatural; b.container = nested_ti.IsContainer; b.caseSensitive = nested_ti.IsCaseSensitive; b.data = new SymbolLink(nested_ti.DataType); bindings.Add(b); if (nested_ti.IsContainer) transformer.NeedTransform = true; } foreach (RowType.TypeInfo ti in source.RowType.Fields) foreach (RowType.TypeInfo nested_ti in ti.NestedType.Fields) if (!nested_ti.IsHidden && !nested_ti.IsNatural) { ColumnBinding b = new ColumnBinding(); b.typecode = Type.GetTypeCode(nested_ti.DataType); b.rnum = ti.Ordinal; b.TableName = ti.Name; b.Name = nested_ti.Name; b.fieldType = nested_ti; b.natural = nested_ti.IsNatural; b.container = nested_ti.IsContainer; b.caseSensitive = nested_ti.IsCaseSensitive; b.data = new SymbolLink(nested_ti.DataType); bindings.Add(b); if (nested_ti.IsContainer) transformer.NeedTransform = true; } // Expand columns. // On this step we transform select table.* and select * to select field1,... List<Column> columns = new List<Column>(); if (_targets == null) // Select fields from all selected tables { foreach (ColumnBinding b in bindings) columns.Add(new Column(ATOM.Create(null, new string[] { b.TableName, b.Name }, false))); } else foreach (Column col in _targets) { if (Lisp.IsFunctor(col.Expr, Table)) // Select fields from specified table { bool found = false; String name = (String)Lisp.Second(col.Expr); var tableBindings = from b in bindings where b.TableName == name select b; foreach (ColumnBinding b in tableBindings) { columns.Add(new Column(ATOM.Create(null, new string[] { b.TableName, b.Name }, false))); found = true; } if (!found) throw new ESQLException(Properties.Resources.InvalidIdentifier, name); } else // Select expression specified if (transformer.NeedTransform) { Column c = new Column(); c.Alias = col.Alias; c.Expr = transformer.Process(col.Expr); columns.Add(c); } else columns.Add(col); } // Create demand context FunctionLink[] compiledBody = new FunctionLink[columns.Count]; SelectorResolver resolver = new SelectorResolver(new Binder(bindings)); SelectorContext context = new SelectorContext(this, _distinct, columns.ToArray(), resolver, source, queryContext, parameters, compiledBody); // Create columns type info and generate unique column names by field name and alias RowType.TypeInfo[] fields = new RowType.TypeInfo[columns.Count]; List<String> fieldNames = new List<string>(); int p = 1; for (int k = 0; k < fields.Length; k++) { String name; RowType.TypeInfo fieldType = null; object expr = columns[k].Expr; compiledBody[k] = new FunctionLink(); Type resType = context.LispExecutive.Compile(null, expr, compiledBody[k]); if (Lisp.IsAtom(expr)) { ColumnBinding b = resolver.GetBinding(expr); if (b != null) fieldType = b.fieldType; } else if (Lisp.IsNode(expr) && expr is String) { fieldType = new RowType.TypeInfo(null, typeof(String), TypeConverter.GetValueSize(expr)); } else if (Lisp.IsFunctor(expr, ID.ParamRef)) { object value = parameters[(int)Lisp.Arg1(expr)]; fieldType = new RowType.TypeInfo(null, value.GetType(), TypeConverter.GetValueSize(value)); } else if (Lisp.IsFunctor(expr, ID.ToString)) { if (Lisp.Length(expr) == 3) fieldType = new RowType.TypeInfo(null, typeof(String), (int)Lisp.Arg2(expr)); else fieldType = new RowType.TypeInfo(null, typeof(String), 0); } else if (Lisp.IsFunctor(expr, ID.ToInt16)) fieldType = new RowType.TypeInfo(null, typeof(Int16), 0); else if (Lisp.IsFunctor(expr, ID.ToInt32)) fieldType = new RowType.TypeInfo(null, typeof(Int32), 0); else if (Lisp.IsFunctor(expr, ID.ToInt64)) fieldType = new RowType.TypeInfo(null, typeof(Int64), 0); else if (Lisp.IsFunctor(expr, ID.ToSingle)) fieldType = new RowType.TypeInfo(null, typeof(Single), 0); else if (Lisp.IsFunctor(expr, ID.ToDouble)) fieldType = new RowType.TypeInfo(null, typeof(Double), 0); else if (Lisp.IsFunctor(expr, ID.ToDecimal)) fieldType = new RowType.TypeInfo(null, typeof(Decimal), 0); else if (Lisp.IsFunctor(expr, ID.ToDateTime)) fieldType = new RowType.TypeInfo(null, typeof(DateTime), 0); else fieldType = new RowType.TypeInfo(null, resType, 0); if (!String.IsNullOrEmpty(columns[k].Alias)) name = columns[k].Alias; else if (fieldType.Name == null) name = String.Format("Expr{0}", p++); else name = fieldType.Name; fields[k] = new RowType.TypeInfo(k, Util.CreateUniqueName(fieldNames, name), fieldType); } ScanDynatableAccessors(ChildNodes[0], resolver); return new Resultset(new RowType(fields), context); }
public Binder(ColumnBinding[] columnBinding) { _columnBinding = columnBinding; FlagAmbiguos(); }