public readonly SDict <long, long> uses; // Item1 is for RIGHT, Item2 for LEFT public SJoin(ReaderBase f) : base(Types.STableExp, _Join(f)) { left = f._Get() as SQuery ?? throw new StrongException("Query expected"); outer = f.GetInt() == 1; joinType = (JoinType)f.GetInt(); right = f._Get() as SQuery ?? throw new StrongException("Query expected"); var n = f.GetInt(); var on = SList <SExpression> .Empty; var us = SDict <long, long> .Empty; var tr = (STransaction)f.db; var lns = SDict <string, long> .Empty; for (var b = left.Display.First(); b != null; b = b.Next()) { lns += (b.Value.Item2.Item2, b.Value.Item2.Item1); } var rns = SDict <string, long> .Empty; for (var b = right.Display.First(); b != null; b = b.Next()) { var nm = b.Value.Item2.Item2; if (joinType == JoinType.Natural && lns.Contains(nm)) { us += (b.Value.Item2.Item1, lns[nm]); } rns += (nm, b.Value.Item2.Item1); } if (joinType.HasFlag(JoinType.Named)) { for (var i = 0; i < n; i++) { var nm = tr.uids[f.GetLong()]; if (!(lns.Contains(nm) && rns.Contains(nm))) { throw new StrongException("name " + nm + " not present in Join"); } us += (rns[nm], lns[nm]); } } else if (!joinType.HasFlag(JoinType.Cross)) { for (var i = 0; i < n; i++) { var e = f._Get() as SExpression ?? throw new StrongException("ON exp expected"); on += e; } } ons = on; uses = us; f.context = this; }
public SJoin(SDatabase db, Reader f) : base(Types.STableExp, _Join(db, f)) { left = f._Get(db) as SQuery ?? throw new Exception("Query expected"); outer = f.GetInt() == 1; joinType = (JoinType)f.GetInt(); right = f._Get(db) as SQuery ?? throw new Exception("Query expected"); var n = f.GetInt(); var on = SList <SExpression> .Empty; var us = SList <string> .Empty; if (joinType.HasFlag(JoinType.Natural)) { for (var lb = left.names.First(); lb != null; lb = lb.Next()) { if (right.names.Contains(lb.Value.Item1)) { us += lb.Value.Item1; } } } else if (joinType.HasFlag(JoinType.Named)) { for (var i = 0; i < n; i++) { us += f.GetString(); } } else if (!joinType.HasFlag(JoinType.Cross)) { for (var i = 0; i < n; i++) { var e = f._Get(db) as SExpression ?? throw new Exception("ON exp expected"); on += e; } } ons = on; uses = us; }