public ColValue(IValueContext Context, DbColumn col) : base(Context) { this.col = col; }
// _ReadNextLiteral kept for SET static ByteSlice _ReadNextLiteral(PartReader input, DbColumn TypeHint) { string op; op = input.NextPart(); if (op.Length > 0) { if ('\'' == op[0]) { if (op[op.Length - 1] == '\'') { if ("DateTime" == TypeHint.Type.Name) { DateTime dt = DateTime.Parse(op.Substring(1, op.Length - 2)); Int64 x = dt.Ticks; List<byte> buf = new List<byte>(1 + 8); buf.Add(0); Entry.ToBytesAppend64(x, buf); return ByteSlice.Prepare(buf); } else { string str = op.Substring(1, op.Length - 2).Replace("''", "'"); byte[] strbytes = System.Text.Encoding.Unicode.GetBytes(str); //List<byte> buf = new List<byte>(1 + strbytes.Length); List<byte> buf = new List<byte>(TypeHint.Type.Size); buf.Add(0); buf.AddRange(strbytes); // Pad up the end of the char to be the whole column size. while (buf.Count < TypeHint.Type.Size) { buf.Add(0); } return ByteSlice.Prepare(buf); } } else { throw new Exception("Unterminated string: " + op); } } else if (char.IsDigit(op[0])) { return ByteSlice.Prepare(_NumberLiteralToType(op, TypeHint)); } else if ("+" == op || "-" == op) { bool positive = "+" == op; op = input.NextPart(); if (0 == op.Length) { throw new Exception("Expected number after sign"); } return ByteSlice.Prepare(_NumberLiteralToType(positive ? op : ("-" + op), TypeHint)); } else { throw new Exception("Misunderstood value: " + op); } } return ByteSlice.Prepare(new byte[] { 0 }); }
int _IndexOfRowColType(string name) { return(DbColumn.IndexOf(ColumnTypes, name)); }
int IndexOfCol(string name) { return(DbColumn.IndexOf(cols, name)); }
// _ReadNextLiteral kept for _ReadNextLiteral static List<byte> _NumberLiteralToType(string sNum, DbColumn ci) { List<byte> buf; if ("int" == ci.Type.Name) { Int32 x = Int32.Parse(sNum); buf = new List<byte>(1 + 4); buf.Add(0); Entry.ToBytesAppend((Int32)Entry.ToUInt32(x), buf); } else if ("long" == ci.Type.Name) { Int64 x = Int64.Parse(sNum); buf = new List<byte>(1 + 8); buf.Add(0); Entry.ToBytesAppend64((Int64)Entry.ToUInt64(x), buf); } else if ("double" == ci.Type.Name) { double x = double.Parse(sNum); buf = new List<byte>(1 + 9); buf.Add(0); recordset rs = recordset.Prepare(); rs.PutDouble(x); for (int id = 0; id < 9; id++) { buf.Add(0); } rs.GetBytes(buf, 1, 9); } else { // This type isn't comparable with a number! buf = new List<byte>(1); buf.Add(1); // Nullable byte; IsNull=true; } return buf; }
public override void Map(ByteSlice row, MapOutput output) { if (null == TableName) { InitFields(); } // Operate on values! ByteSlice key; bool keep = null == filter || filter.TestRow(row); if (DeleteFromFilter) { keep = !keep; } if (keep) { if (KeyOn != null) { orderbuf.Clear(); for (int iob = 0; iob < KeyOn.Count; iob++) { GetKeyPart gkp = KeyOn[iob]; gkp(row, orderbuf); } #if DEBUG string KeyOnStringValue = "<not evaluated yet>"; if (0 != ((orderbuf.Count - 1) % 2)) { KeyOnStringValue = "<not a string>"; } else { //KeyOnStringValue = System.Text.Encoding.Unicode.GetString(ByteSlice.Prepare(orderbuf, 1, orderbuf.Count - 1).ToBytes()); { System.Text.Encoding ue = new System.Text.UnicodeEncoding(false, false, true); // throwOnInvalidBytes=true try { KeyOnStringValue = ue.GetString(ByteSlice.Prepare(orderbuf, 1, orderbuf.Count - 1).ToBytes()); } catch { KeyOnStringValue = "<not a string>"; } } } #endif while (orderbuf.Count < DSpace_KeyLength) { orderbuf.Add(0); } key = ByteSlice.Prepare(orderbuf); } else // Use default key. { orderbuf.Clear(); Entry.ToBytesAppend(defkey, orderbuf); key = ByteSlice.Prepare(orderbuf); defkey = unchecked (defkey + DSpace_ProcessCount); } if (null != Updates) { updatebuf.Clear(); row.AppendTo(updatebuf); for (int ui = 0; ui < Updates.Count; ui++) { UpdateField uf = Updates[ui]; DbColumn ci = cols[uf.FieldIndex]; for (int i = 0; i < ci.Type.Size; i++) { updatebuf[ci.RowOffset + i] = uf.NewValue[i]; } } row = ByteSlice.Prepare(updatebuf); } } else { if (null == Updates) { if (null != ftools) { ftools.ResetBuffers(); } return; } if (KeyOn != null) { key = row; #if DEBUG throw new Exception("DEBUG: (!keep) && (KeyOn != null)"); #endif } else { // Use default key. orderbuf.Clear(); Entry.ToBytesAppend(defkey, orderbuf); key = ByteSlice.Prepare(orderbuf); defkey = unchecked (defkey + DSpace_ProcessCount); } } // If WhatFunctions, might need all input fields, so keep them here and filter out unwanted stuff in reduce. if (null != Whats && !WhatFunctions) { newfieldsbuf.Clear(); for (int iww = 0; iww < Whats.Count; iww++) { int wi = Whats[iww]; if (-1 == wi) { DbTypeID ltype; if (null == ftools) { ftools = new DbFunctionTools(); } List <byte> lbuf = ftools.AllocBuffer(); ByteSlice cval = Types.LiteralToValueBuffer(awhat[iww], out ltype, lbuf); int Size = cval.Length; #if DEBUG if (Size != OutputColumnSizes[iww]) { throw new Exception("DEBUG: " + awhat[iww] + ": (Size{" + Size + "} != OutputColumnSizes[iww]{" + OutputColumnSizes[iww] + "})"); } #endif cval.AppendTo(newfieldsbuf); } else { DbColumn ci = cols[wi]; int StartOffset = ci.RowOffset; int Size = ci.Type.Size; #if DEBUG if (Size != OutputColumnSizes[iww]) { throw new Exception("DEBUG: (Size != OutputColumnSizes[iww])"); } #endif ByteSlice cval = ByteSlice.Prepare(row, StartOffset, Size); cval.AppendTo(newfieldsbuf); } } row = ByteSlice.Prepare(newfieldsbuf); } output.Add(key, row); if (null != ftools) { ftools.ResetBuffers(); } }
// _ReadNextLiteral kept for SET static ByteSlice _ReadNextLiteral(PartReader input, DbColumn TypeHint) { string op; op = input.NextPart(); if (op.Length > 0) { if ('\'' == op[0]) { if (op[op.Length - 1] == '\'') { if ("DateTime" == TypeHint.Type.Name) { DateTime dt = DateTime.Parse(op.Substring(1, op.Length - 2)); Int64 x = dt.Ticks; List <byte> buf = new List <byte>(1 + 8); buf.Add(0); Entry.ToBytesAppend64(x, buf); return(ByteSlice.Prepare(buf)); } else { string str = op.Substring(1, op.Length - 2).Replace("''", "'"); byte[] strbytes = System.Text.Encoding.Unicode.GetBytes(str); //List<byte> buf = new List<byte>(1 + strbytes.Length); List <byte> buf = new List <byte>(TypeHint.Type.Size); buf.Add(0); buf.AddRange(strbytes); // Pad up the end of the char to be the whole column size. while (buf.Count < TypeHint.Type.Size) { buf.Add(0); } return(ByteSlice.Prepare(buf)); } } else { throw new Exception("Unterminated string: " + op); } } else if (char.IsDigit(op[0])) { return(ByteSlice.Prepare(_NumberLiteralToType(op, TypeHint))); } else if ("+" == op || "-" == op) { bool positive = "+" == op; op = input.NextPart(); if (0 == op.Length) { throw new Exception("Expected number after sign"); } return(ByteSlice.Prepare(_NumberLiteralToType(positive ? op : ("-" + op), TypeHint))); } else { throw new Exception("Misunderstood value: " + op); } } return(ByteSlice.Prepare(new byte[] { 0 })); }
void LogFieldInfo(int fieldindex, DbColumn c, bool ShouldCleanName) { string cstype = QATypeToCSType(c.Type.Name); string name = c.ColumnName; if (ShouldCleanName) { name = CleanColumnName(name); } DSpace_Log(" <field index=\"" + fieldindex.ToString() + "\" name=\"" + name + "\" qatype=\"" + c.Type.Name + "\" cstype=\"" + cstype + "\" frontbytes=\"1\" bytes=\"" + (c.Type.Size - 1).ToString() + "\" backbytes=\"0\" />"); }
CallInfo _GetSelectPartCalls(ref string calls) { CallInfo ci = new CallInfo(); { string colpart = Qa.NextPart(ref calls); if (0 == colpart.Length) { throw new Exception("Expected value"); } if ("-" == colpart || "+" == colpart) { colpart += Qa.NextPart(ref calls); } string s; s = Qa.NextPart(ref calls); if ("(" == s) { List <CallInfoArg> args = new List <CallInfoArg>(4); { string xcalls = calls; if (")" == Qa.NextPart(ref xcalls)) { calls = xcalls; ci.func = colpart; ci.args = args; return(ci); } } for (; ;) { CallInfo nestci = _GetSelectPartCalls(ref calls); CallInfoArg arg = new CallInfoArg(); if (nestci.func == null) { #if DEBUG if (1 != nestci.args.Count) { throw new Exception("DEBUG: (1 != nestci.args.Count)"); } #endif arg = nestci.args[0]; } else { arg.nest = nestci; } args.Add(arg); s = Qa.NextPart(ref calls); if (0 == string.Compare("AS", s, true)) { arg = new CallInfoArg(); { StringBuilder sbas = new StringBuilder(); int asparens = 0; for (; ;) { s = Qa.NextPart(ref calls); if (0 == s.Length || "," == s) { //calls += s; break; } else if ("(" == s) { asparens++; sbas.Append(s); } else if (")" == s) { if (0 == asparens) { //calls += s; break; } asparens--; sbas.Append(s); } else { sbas.Append(s); } } if (0 == sbas.Length) { throw new Exception("Expected type after AS"); } { DbValue iterval = functools.AllocValue(mstring.Prepare("AS " + sbas.ToString())); // Need to copy the value out of the functools memory // so that it survives this map/reduce iteration... DbType xtype; ByteSlice iterbs = iterval.Eval(out xtype); List <byte> newbuf = new List <byte>(iterbs.Length); iterbs.AppendTo(newbuf); arg.value = new ImmediateValue(null, ByteSlice.Prepare(newbuf), xtype); } args.Add(arg); } //s = Qa.NextPart(ref calls); } if (s == ",") { continue; } if (s == ")") { string xnc = calls; s = Qa.NextPart(ref xnc); if (0 == s.Length || "," == s || ")" == s || 0 == string.Compare(s, "AS", true)) { ci.func = colpart; ci.args = args; return(ci); } else { throw new Exception("Unexpected: " + s); } break; } else { if (s.Length != 0) { throw new Exception("Unexpected: " + s); } throw new Exception("Unexpected end of select clause"); } } // Doesn't reach here. } else { //if (0 == s.Length || "," == s || ")" == s) { calls = s + " " + calls; // Undo. //ci.func = null; CallInfoArg arg; arg = new CallInfoArg(); //arg.s = colpart; if (colpart.Length > 0 && (char.IsLetter(colpart[0]) || '_' == colpart[0])) { int icol = DbColumn.IndexOf(cols, colpart); if (-1 == icol) { throw new Exception("No such column named " + colpart); } arg.value = new ColValue(this, cols[icol]); } else { DbTypeID typeid; ByteSlice bs = Types.LiteralToValue(colpart, out typeid); arg.value = new ImmediateValue(null, bs, DbType.Prepare(bs.Length, typeid)); } ci.args = new CallInfoArg[1]; ci.args[0] = arg; return(ci); } /*else * { * throw new Exception("Unexpected: " + s); * }*/ } } }
protected override void Run() { string QlLeftTableName = DSpace_ExecArgs[0]; string LeftTableName = QlArgsUnescape(QlLeftTableName); string stype = DSpace_ExecArgs[1]; string QlRightTableName = DSpace_ExecArgs[2]; string RightTableName = QlArgsUnescape(QlRightTableName); string QlOn = DSpace_ExecArgs[3]; string On = QlArgsUnescape(QlOn); if (-1 != LeftTableName.IndexOf('\0')) { throw new NotSupportedException("Cannot JOIN with multiple left tables: " + LeftTableName); } if (-1 != RightTableName.IndexOf('\0')) { throw new NotSupportedException("Cannot JOIN with multiple right tables: " + RightTableName); } System.Xml.XmlDocument systables; using (GlobalCriticalSection.GetLock()) { systables = LoadSysTables_unlocked(); } System.Xml.XmlElement xeLeftTable = FindTable(systables, LeftTableName); if (null == xeLeftTable) { throw new Exception("Table (left) '" + LeftTableName + "' does not exist"); } string sLeftRowSize = xeLeftTable["size"].InnerText; int LeftRowSize = int.Parse(sLeftRowSize); string LeftDfsTableFilesInput = xeLeftTable["file"].InnerText + "@" + sLeftRowSize; if (LeftDfsTableFilesInput.StartsWith("qa://", true, null)) { throw new Exception("Cannot JOIN with system tables (left)"); } System.Xml.XmlElement xeRightTable = FindTable(systables, RightTableName); if (null == xeRightTable) { throw new Exception("Table (right) '" + RightTableName + "' does not exist"); } string sRightRowSize = xeRightTable["size"].InnerText; int RightRowSize = int.Parse(sRightRowSize); string RightDfsTableFilesInput = xeRightTable["file"].InnerText + "@" + sRightRowSize; if (RightDfsTableFilesInput.StartsWith("qa://", true, null)) { throw new Exception("Cannot JOIN with system tables (right)"); } string DfsTableFilesInput = LeftDfsTableFilesInput + ";" + RightDfsTableFilesInput; string DfsOutputName = "dfs://RDBMS_JoinOn_" + Guid.NewGuid().ToString() + Qa.DFS_TEMP_FILE_MARKER; int DfsOutputRowSize = LeftRowSize + RightRowSize; string LeftRowInfo; string LeftDisplayInfo; // Display List <DbColumn> LeftCols = new List <DbColumn>(); List <string> LeftColsWidths = new List <string>(); { StringBuilder sbRowInfo = new StringBuilder(); StringBuilder sbDisplayInfo = new StringBuilder(); // Display int totsize = 0; string xtablename = xeLeftTable["name"].InnerText; foreach (System.Xml.XmlNode xn in xeLeftTable.SelectNodes("column")) { if (0 != sbRowInfo.Length) { sbRowInfo.Append('\0'); sbDisplayInfo.Append(','); // Display } string stsize = xn["bytes"].InnerText; int tsize = int.Parse(stsize); string RealColName = xn["name"].InnerText; string UserColName = RealColName; string xcolname; if (-1 == UserColName.IndexOf('.')) { xcolname = xtablename + "." + UserColName; } else { xcolname = UserColName; } sbRowInfo.Append(xcolname); // Note: doesn't consider sub-select. sbRowInfo.Append('='); sbRowInfo.Append(stsize); sbDisplayInfo.Append(xn["type"].InnerText); // Display sbDisplayInfo.Append('='); // Display sbDisplayInfo.Append(xn["dw"].InnerText); // Display LeftColsWidths.Add(xn["dw"].InnerText); { DbColumn c; c.Type = DbType.Prepare(xn["type"].InnerText, tsize); c.RowOffset = totsize; c.ColumnName = xcolname; LeftCols.Add(c); } totsize += tsize; } LeftRowInfo = sbRowInfo.ToString(); LeftDisplayInfo = sbDisplayInfo.ToString(); // Display } string RightRowInfo; string RightDisplayInfo; // Display List <DbColumn> RightCols = new List <DbColumn>(); List <string> RightColsWidths = new List <string>(); { StringBuilder sbRowInfo = new StringBuilder(); StringBuilder sbDisplayInfo = new StringBuilder(); // Display int totsize = 0; string xtablename = xeRightTable["name"].InnerText; foreach (System.Xml.XmlNode xn in xeRightTable.SelectNodes("column")) { if (0 != sbRowInfo.Length) { sbRowInfo.Append('\0'); sbDisplayInfo.Append(','); // Display } string stsize = xn["bytes"].InnerText; int tsize = int.Parse(stsize); string RealColName = xn["name"].InnerText; string UserColName = RealColName; string xcolname; if (-1 == UserColName.IndexOf('.')) { xcolname = xtablename + "." + UserColName; } else { xcolname = UserColName; } sbRowInfo.Append(xcolname); // Note: doesn't consider sub-select. sbRowInfo.Append('='); sbRowInfo.Append(stsize); sbDisplayInfo.Append(xn["type"].InnerText); // Display sbDisplayInfo.Append('='); // Display sbDisplayInfo.Append(xn["dw"].InnerText); // Display RightColsWidths.Add(xn["dw"].InnerText); { DbColumn c; c.Type = DbType.Prepare(xn["type"].InnerText, tsize); c.RowOffset = totsize; c.ColumnName = xcolname; RightCols.Add(c); } totsize += tsize; } RightRowInfo = sbRowInfo.ToString(); RightDisplayInfo = sbDisplayInfo.ToString(); // Display } string on1, onop, on2; { string onargs = On; on1 = Qa.NextPart(ref onargs); onop = Qa.NextPart(ref onargs); on2 = Qa.NextPart(ref onargs); if (0 == on1.Length || 0 == onop.Length || 0 == on2.Length || 0 != onargs.Trim().Length) { throw new Exception("Invalid ON expression for JOIN: " + On); } } bool on1left; int on1colindex; { int on1colindexother; on1colindex = DbColumn.IndexOf(LeftCols, on1); on1colindexother = DbColumn.IndexOf(RightCols, on1); if (-1 != on1colindex) { if (-1 != on1colindexother) { throw new Exception("Column name " + on1 + " does not resolve to a single column (in left and right tables)"); } else { on1left = true; } } else { if (-1 != on1colindexother) { on1colindex = on1colindexother; on1left = false; } else { throw new Exception("No such column named " + on1); } } } bool on2left; int on2colindex; { int on2colindexother; on2colindex = DbColumn.IndexOf(LeftCols, on2); on2colindexother = DbColumn.IndexOf(RightCols, on2); if (-1 != on2colindex) { if (-1 != on2colindexother) { throw new Exception("Column name " + on2 + " does not resolve to a single column (in left and right tables)"); } else { on2left = true; } } else { if (-1 != on2colindexother) { on2colindex = on2colindexother; on2left = false; } else { throw new Exception("No such column named " + on2); } } } if ((on1left && on2left) || (!on1left && !on2left)) { string whicht; if (on1left) { whicht = "(left) " + LeftTableName; } else { whicht = "(right) " + RightTableName; } throw new Exception("ON expression is comparing columns from the same table: " + on1 + " and " + on2 + " are both part of " + whicht); } // Order ON columns: if (!on1left) { { string onx = on1; on1 = on2; on2 = onx; } { int onxcolindex = on1colindex; on1colindex = on2colindex; on2colindex = onxcolindex; } { on1left = true; on2left = false; } // Invert the operator.. switch (onop) { case "=": //onop = "="; break; case "!=": //onop = "!="; break; case "<": onop = ">"; break; case "<=": onop = ">="; break; case ">": onop = "<"; break; case ">=": onop = "<="; break; default: throw new Exception("Unhandled ON operation: " + onop); } On = on1 + " " + onop + " " + on2; QlOn = QlArgsEscape(On); } DbColumn on1col; if (on1left) { on1col = LeftCols[on1colindex]; } else { //on1col = RightCols[on1colindex]; throw new Exception("DEBUG: PrepareJoinOn: (!on1left)"); } if (on1col.Type.Size == 0 || on1col.Type.ID == DbTypeID.NULL) { throw new Exception("Invalid column for ON expression: " + on1); } DbColumn on2col; if (on2left) { //on2col = LeftCols[on2colindex]; throw new Exception("DEBUG: PrepareJoinOn: (on2left)"); } else { on2col = RightCols[on2colindex]; } if (on2col.Type.Size == 0 || on2col.Type.ID == DbTypeID.NULL) { throw new Exception("Invalid column for ON expression: " + on2); } int KeyLength = on1col.Type.Size; if (on2col.Type.Size > KeyLength) { KeyLength = on2col.Type.Size; } { MapReduceCall mrc = GetMapReduceCallJoinOn(DfsTableFilesInput); mrc.OverrideOutputMethod = "grouped"; mrc.OverrideInput = DfsTableFilesInput; mrc.OverrideOutput = DfsOutputName + "@" + DfsOutputRowSize; mrc.OverrideKeyLength = KeyLength; if (RDBMS_DBCORE.Qa.FaultTolerantExecution) { mrc.OverrideFaultTolerantExecutionMode = "enabled"; } mrc.Call("\"" + QlLeftTableName + "\" " + stype + " \"" + QlRightTableName + "\" \"" + QlOn + "\" \"" + on1col.RowOffset + "," + on1col.Type.Size + "=" + QlArgsEscape(on1col.Type.Name) + "\" \"" + on2col.RowOffset + "," + on2col.Type.Size + "=" + QlArgsEscape(on2col.Type.Name) + "\" \"" + DfsTableFilesInput + "\""); } { PrepareSelect.queryresults qr = new PrepareSelect.queryresults(); List <DbColumn> AllCols = new List <DbColumn>(LeftCols.Count + RightCols.Count); AllCols.AddRange(LeftCols); AllCols.AddRange(RightCols); qr.SetFields(AllCols); qr.temptable = DfsOutputName; qr.recordsize = LeftRowSize + RightRowSize; string sPartCount = Shell("dspace countparts \"" + DfsOutputName + "\"").Split('\n')[0].Trim(); qr.parts = int.Parse(sPartCount); string sDfsOutputSize = Shell("dspace filesize \"" + DfsOutputName + "\"").Split('\n')[0].Trim(); long DfsOutputSize = long.Parse(sDfsOutputSize); long NumRowsOutput = DfsOutputSize / qr.recordsize; qr.recordcount = NumRowsOutput; DSpace_Log(PrepareSelect.SetQueryResults(qr)); } }