public static void MaterializeView(Parse parse, Table view, Expr where_, int curId) { Context ctx = parse.Ctx; int db = Prepare.SchemaToIndex(ctx, view.Schema); where_ = Expr.Dup(ctx, where_, 0); SrcList from = Parse.SrcListAppend(ctx, null, null, null); if (from != null) { Debug.Assert(from.Srcs == 1); from.Ids[0].Name = view.Name; from.Ids[0].Database = ctx.DBs[db].Name; Debug.Assert(from.Ids[0].On == null); Debug.Assert(from.Ids[0].Using == null); } Select select = Select.New(parse, 0, from, where_, 0, 0, 0, 0, 0, 0); if (select != null) select.SelFlags |= SF.Materialize; SelectDest dest = new SelectDest(); Select.DestInit(dest, SRT.EphemTab, curId); Select.Select(parse, select, dest); Select.Delete(ctx, select); }
static void UpdateVirtualTable(Parse parse, SrcList src, Table table, ExprList changes, Expr rowid, int[] xrefs, Expr where_, int onError) { int i; Context ctx = parse.Ctx; // Database connection VTable vtable = VTable.GetVTable(ctx, table); SelectDest dest = new SelectDest(); // Construct the SELECT statement that will find the new values for all updated rows. ExprList list = ExprList.Append(parse, 0, Expr.Expr(ctx, TK.ID, "_rowid_")); // The result set of the SELECT statement if (rowid != null) { list = ExprList.Append(parse, list, Expr.Dup(ctx, rowid, 0)); } Debug.Assert(table.PKey < 0); for (i = 0; i < table.Cols.length; i++) { Expr expr = (xrefs[i] >= 0 ? Expr.Dup(ctx, changes.Ids[xrefs[i]].Expr, 0) : Expr.Expr(ctx, TK.ID, table.Cols[i].Name)); // Temporary expression list = ExprList.Append(parse, list, expr); } Select select = Select.New(parse, list, src, where_, null, null, null, 0, null, null); // The SELECT statement // Create the ephemeral table into which the update results will be stored. Vdbe v = parse.V; // Virtual machine under construction Debug.Assert(v != null); int ephemTab = parse.Tabs++; // Table holding the result of the SELECT v.AddOp2(OP.OpenEphemeral, ephemTab, table.Cols.length + 1 + (rowid != null ? 1 : 0)); v.ChangeP5(BTREE_UNORDERED); // fill the ephemeral table Select.DestInit(dest, SRT.Table, ephemTab); Select.Select(parse, select, ref dest); // Generate code to scan the ephemeral table and call VUpdate. int regId = ++parse.Mems;// First register in set passed to OP_VUpdate parse.Mems += table.Cols.length + 1; int addr = v.AddOp2(OP.Rewind, ephemTab, 0); // Address of top of loop v.AddOp3(OP.Column, ephemTab, 0, regId); v.AddOp3(OP.Column, ephemTab, (rowid != null ? 1 : 0), regId + 1); for (i = 0; i < table.nCol; i++) { v.AddOp3(OP.Column, ephemTab, i + 1 + (rowid != null ? 1 : 0), regId + 2 + i); } sqlite3VtabMakeWritable(parse, table); v.AddOp4(OP_VUpdate, 0, table.Cols.length + 2, regId, vtable, P4_VTAB); v.ChangeP5((byte)(onError == OE_Default ? OE_Abort : onError)); parse.MayAbort(); v.AddOp2(OP.Next, ephemTab, addr + 1); v.JumpHere(addr); v.AddOp2(OP.Close, ephemTab, 0); // Cleanup Select.Delete(ctx, ref select); }
public override string Query() { if (Select.SelectedMembers.Count == 0) { Select.Select("objectrepresentation"); } return(string.Concat( "(string_to_array(", Path.LastPropertyName.ToLower(), ", ',')) && ARRAY (", Select.Query(), ")")); }
public string GetQuery() { string result = ""; result = "select"; result += string.Join(",\n", Select.Select(x => x.GetQuery())); result += $"\nfrom " + string.Join(",\n", From.Select(x => x.GetFrom())); result += string.Join(",\n", From.Select(x => $"{x.Name} as [{x.Alias}]")); if (Where != null) { result += $"\n{Where.GetQuery()};"; } return(result); }
/// <summary> /// Prepares the join tree /// </summary> private JoinTree PrepareJoin() { // construct the join tree var allPaths = new List <string[]>(); if (Select != null) { allPaths.AddRange(Select.Select(e => e.Path)); } if (Filter != null) { allPaths.AddRange(Filter.Select(e => e.Path)); } // This will represent the mapping from paths to symbols var joinTree = JoinTree.Make(ResultType, allPaths); return(joinTree); }
/// <summary> /// Create the <see cref="JoinTrie"/> from the paths in all the arguments /// </summary> private JoinTrie PrepareJoin(ArraySegment <string>?pathToCollection = null) { // construct the join tree var allPaths = new List <string[]>(); if (Select != null) { allPaths.AddRange(Select.Select(e => e.Path)); } if (Expand != null) { allPaths.AddRange(Expand.Select(e => e.Path)); } if (Filter != null) { allPaths.AddRange(Filter.ColumnAccesses().Select(e => e.Path)); } if (OrderBy != null) { allPaths.AddRange(OrderBy.ColumnAccesses().Select(e => e.Path)); } if (pathToCollection != null) { var pathToCollectionEntity = new ArraySegment <string>( pathToCollection.Value.Array, pathToCollection.Value.Offset, pathToCollection.Value.Count - 1); allPaths.Add(pathToCollectionEntity.ToArray()); } // This will represent the mapping from paths to symbols return(JoinTrie.Make(ResultDescriptor, allPaths)); }
IList <object> IInternalResourceParameter <T> .ApplySelect(IEnumerable <T> source) { if (Select.Count == 0) { return(source.Select(x => (object)x).ToList()); } var test = Select.Select(x => x.GetPropertyMapping()); object test3(T user, IEnumerable <Func <T, (string, object)> > func) { var t = new ExpandoObject() as IDictionary <string, object>; foreach (var f in func) { var elements = f(user); t.Add(elements.Item1, elements.Item2); } return((ExpandoObject)t); } return(source.Select(x => test3(x, test)).ToList()); }
/// <summary> /// Prepares the SELECT statement and the column map, using the <see cref="Select"/> argument /// </summary> private SqlSelectClause PrepareSelect(JoinTrie joinTree) { var selects = new HashSet <(string Symbol, string PropName)>(); var columns = new List <(string Symbol, ArraySegment <string> Path, string PropName)>(); void AddSelect(string symbol, ArraySegment <string> path, string propName) { // NULL happens when there is a select that has been segmented from the middle // and the first section of the segment no longer terminates with a simple property // propName = propName ?? "Id"; if (propName == null) { return; } if (selects.Add((symbol, propName))) { columns.Add((symbol, path, propName)); } } // Any path step that is touched by a select (which has a property) ignores the expand, the joinTree below // allows us to efficiently check if any particular step is touched by a select JoinTrie overridingSelectTree = Select == null ? null : JoinTrie.Make(ResultDescriptor, Select.Select(e => e.Path)); // Overriding select paths // Optimization: remember the joins that have been selected and don't select them again var selectedJoins = new HashSet <JoinTrie>(); // For every expanded entity that has not been tainted by a select argument, we add all its properties to the list of selects Expand ??= ExpressionExpand.Empty; foreach (var expand in Expand.Union(ExpressionExpand.RootSingleton)) { string[] path = expand.Path; for (int i = 0; i <= path.Length; i++) { var subpath = new ArraySegment <string>(path, 0, i); var selectMatch = overridingSelectTree?[subpath]; if (selectMatch == null) // This expand is not overridden by a select { var join = joinTree[subpath]; if (join == null) { // Developer mistake throw new InvalidOperationException($"The path '{string.Join('.', subpath)}' was not found in the joinTree"); } else if (selectedJoins.Contains(join)) { continue; } else { selectedJoins.Add(join); } foreach (var prop in join.EntityDescriptor.SimpleProperties) { AddSelect(join.Symbol, subpath, prop.Name); } } } } if (Select != null) { foreach (var select in Select) { // Add the property string[] path = select.Path; { var join = joinTree[path]; var propName = select.Property; // Can be null AddSelect(join.Symbol, path, propName); } // In this loop we ensure all levels to the selected properties // have their Ids and Foreign Keys added to the select collection for (int i = 0; i <= path.Length; i++) { var subpath = new ArraySegment <string>(path, 0, i); var join = joinTree[subpath]; if (join == null) { // Developer mistake throw new InvalidOperationException($"The path '{string.Join('.', subpath)}' was not found in the joinTree"); } else if (selectedJoins.Contains(join)) { // All properties were added earlier in an expand continue; } else { selectedJoins.Add(join); } // The Id is ALWAYS required in every EntityWithKey if (join.EntityDescriptor.HasId) { AddSelect(join.Symbol, subpath, "Id"); } // Add all the foreign keys to the next level down foreach (var nextJoin in join.Values) { AddSelect(join.Symbol, subpath, nextJoin.ForeignKeyName); } } } } // If the foreign key to the principal query is specified, then always include that // otherwise there will be no way to link the collection to the principal query once we load the data if (!string.IsNullOrWhiteSpace(ForeignKeyToPrincipalQuery)) { var path = Array.Empty <string>(); AddSelect(joinTree.Symbol, path, ForeignKeyToPrincipalQuery); } // Deals with trees foreach (var path in PathsToParentEntitiesWithExpandedAncestors) { var join = joinTree[path]; AddSelect(join.Symbol, path, "ParentId"); } if (IsAncestorExpand) { var path = Array.Empty <string>(); AddSelect(joinTree.Symbol, path, "ParentId"); } // Change the hash set to a list so that the order is well defined return(new SqlSelectClause(columns)); }
private void Selected() { Select.Select(); }