예제 #1
0
            void InitFields()
            {
                TableName = DSpace_ExecArgs[0];
                string QlArgsSelectWhat = DSpace_ExecArgs[2];
                string SelectWhat       = QlArgsUnescape(QlArgsSelectWhat);

                if ("*" != SelectWhat && "^" != SelectWhat)
                {
                    awhat = SelectWhat.Split('\0');
                }
                string RowInfo     = Qa.QlArgsUnescape(DSpace_ExecArgs[5]);
                string DisplayInfo = DSpace_ExecArgs[6];

                InitColTypeInfos(RowInfo, DisplayInfo);
                string OutputRowInfo = Qa.QlArgsUnescape(DSpace_ExecArgs[7]);

                InitOutputColTypeInfos(OutputRowInfo, awhat);

                //sOptions = ... already done.

                if (null != awhat)
                {
                    Whats = new List <int>(awhat.Length);
                    for (int iww = 0; iww < awhat.Length; iww++)
                    {
                        int WColIndex = IndexOfCol(awhat[iww]); // -1 for function (scalar or aggregate).
                        Whats.Add(WColIndex);
                    }
                }
            }
예제 #2
0
            public override void OnRemote(IEnumerator <ByteSlice> input, System.IO.Stream output)
            {
                DfsTableFile = DSpace_ExecArgs[0];
                {
                    string RowInfo     = Qa.QlArgsUnescape(DSpace_ExecArgs[1]);
                    string DisplayInfo = DSpace_ExecArgs[2];
                    //InitColInfos(RowInfo, DisplayInfo); // RDBMS_Select.DBCORE
                }
                TableName = DSpace_ExecArgs[3];

                if (0 == string.Compare(DfsTableFile, "qa://Sys.Tables", true))
                {
                    _SysTables(output);
                }
                else if (0 == string.Compare(DfsTableFile, "qa://Sys.TablesXML", true))
                {
                    _SysTablesXML(output);
                }
                else if (0 == string.Compare(DfsTableFile, "qa://Sys.Shell", true))
                {
                    _SysShell(output);
                }
                else if (0 == string.Compare(DfsTableFile, "qa://Sys.Help", true))
                {
                    _SysHelp(output);
                }
                else if (0 == string.Compare(DfsTableFile, "qa://Sys.Indexes", true))
                {
                    _SysIndexes(output);
                }
                else
                {
                    throw new Exception("Unknown system table file: " + DfsTableFile);
                }
            }
예제 #3
0
파일: Types.cs 프로젝트: xwyangjshb/qizmt
        public override string PeekPart()
        {
            string x = str;

            return(Qa.NextPart(ref x));
        }
예제 #4
0
파일: Types.cs 프로젝트: xwyangjshb/qizmt
 public override string NextPart()
 {
     return(Qa.NextPart(ref str));
 }
예제 #5
0
 string QlArgsEscape(string args)
 {
     return(Qa.QlArgsEscape(args));
 }
예제 #6
0
 string QlArgsUnescape(string[] eargs)
 {
     return(Qa.QlArgsUnescape(eargs));
 }
예제 #7
0
            void InitFields()
            {
                orderbuf      = new List <byte>(DSpace_KeyLength);
                defkey        = DSpace_ProcessID;
                TableName     = DSpace_ExecArgs[0];
                DfsOutputName = DSpace_ExecArgs[1];
                string QlArgsSelectWhat = DSpace_ExecArgs[2];

                SelectWhat = QlArgsUnescape(QlArgsSelectWhat);
                TopCount   = long.Parse(DSpace_ExecArgs[3]);
                string QlArgsOps = DSpace_ExecArgs[4]; // Still encoded with QlArgsEscape.

                Ops = QlArgsUnescape(QlArgsOps);
                if ("*" == Ops)
                {
                    aOps = new string[] { };
                }
                else
                {
                    aOps = Ops.Split('\0');
                }
                string RowInfo     = Qa.QlArgsUnescape(DSpace_ExecArgs[5]);
                string DisplayInfo = DSpace_ExecArgs[6];

                InitColTypeInfos(RowInfo, DisplayInfo);
                string OutputRowInfo = Qa.QlArgsUnescape(DSpace_ExecArgs[7]);

                InitOutputColTypeInfos(OutputRowInfo);
                sOptions = (DSpace_ExecArgs.Length > 8) ? DSpace_ExecArgs[8] : "-";

                WhatFunctions = -1 != sOptions.IndexOf("SFUNC");
                GroupBy       = -1 != sOptions.IndexOf("GBY");

                if ("*" != SelectWhat && "^" != SelectWhat)
                {
                    awhat = SelectWhat.Split('\0');
                    Whats = new List <int>(awhat.Length);
                    for (int iww = 0; iww < awhat.Length; iww++)
                    {
                        int WColIndex = IndexOfCol(awhat[iww]); // -1 for function (scalar or aggregate).
                        Whats.Add(WColIndex);
                    }
                }

                {
                    int iop = 0;
                    while (iop < aOps.Length)
                    {
                        string op;
                        op = (iop < aOps.Length) ? aOps[iop++] : "";
                        if (0 == string.Compare(op, "WHERE", true))
                        {
                            if (DeleteFromFilter)
                            {
                                throw new Exception("WHERE specified multiple times");
                            }
                            //DSpace_Log("DEBUG:  WHERE");
                            if (null != filter)
                            {
                                throw new Exception("WHERE specified multiple times");
                            }
                            SelectWhereClause swc = new SelectWhereClause(cols, aOps, iop);
                            filter = swc;
                            swc.Parse();
                            iop = swc.CurrentPosition;
                        }
                        else if (0 == string.Compare(op, "SET", true))
                        {
                            if (null != Updates)
                            {
                                if (DeleteFromFilter)
                                {
                                    throw new Exception("Cannot SET in DELETE");
                                }
                                throw new Exception("SET specified multiple times");
                            }
                            Updates = new List <UpdateField>();
                            StringArrayPartReader upr = new StringArrayPartReader(aOps, iop);
                            for (op = upr.NextPart(); ; op = upr.NextPart())
                            {
                                int FieldIndex = IndexOfCol_ensure(op);
                                if ("=" != upr.NextPart())
                                {
                                    throw new Exception("Expected = after SET field");
                                }
                                if (0 == upr.PeekPart().Length)
                                {
                                    throw new Exception("Expected vaule after SET <field> =");
                                }
                                // Types.ReadNextBasicExpression, etc
                                ByteSlice   bsval = _ReadNextLiteral(upr, cols[FieldIndex]);
                                UpdateField uf;
                                uf.FieldIndex = FieldIndex;
                                uf.NewValue   = bsval;
                                Updates.Add(uf);
                                if ("," != upr.PeekPart())
                                {
                                    break;
                                }
                                upr.NextPart(); // Eat the ",".
                            }
                            if (0 == Updates.Count)
                            {
                                throw new Exception("SET update expression expected");
                            }
                            iop = upr.CurrentPosition;
                        }
                        else if (0 == string.Compare(op, "D.WHERE", true))
                        {
                            if (null != Updates)
                            {
                                throw new Exception("Cannot SET in DELETE");
                            }
                            DeleteFromFilter = true;
                            if (null != filter)
                            {
                                throw new Exception("WHERE specified multiple times");
                            }
                            SelectWhereClause swc = new SelectWhereClause(cols, aOps, iop);
                            filter = swc;
                            swc.Parse();
                            iop = swc.CurrentPosition;
                        }
                        else if (0 == string.Compare(op, "ORDER", true))
                        {
                            //DSpace_Log("DEBUG:  ORDER");
                            op = (iop < aOps.Length) ? aOps[iop++] : "";
                            if (0 == string.Compare(op, "BY", true))
                            {
                                List <GetKeyPart> xorder = new List <GetKeyPart>();
                                for (; ;)
                                {
                                    op = (iop < aOps.Length) ? aOps[iop++] : "";
                                    if (0 == op.Length || ";" == op)
                                    {
                                        throw new Exception("Expected fields for ORDER BY");
                                    }
                                    int ColIndex = IndexOfCol_ensure(op);
                                    //if (-1 != ColIndex)
                                    {
                                        xorder.Add(
                                            delegate(ByteSlice row, List <byte> AppendKeyPart)
                                        {
                                            GetKeyPartForColumn(row, ColIndex, AppendKeyPart);
                                        });
                                    }
                                    op = (iop < aOps.Length) ? aOps[iop++] : "";
                                    if ("," != op)
                                    {
                                        if (0 == op.Length || ";" == op)
                                        {
                                            break;
                                        }
                                        //throw new Exception("Unexpected after ORDER BY ...: " + op);
                                        iop--;
                                        break;
                                    }
                                }
                                if (0 == xorder.Count)
                                {
                                    throw new Exception("Must be at least one column to ORDER BY");
                                }
                                if (GroupBy)
                                {
                                    // GROUP BY happens at earlier phase than ORDER BY,
                                    // so if GROUP BY, ignore ORDER BY and use GROUP BY.
                                    // KeyOn will be set to the GroupBy stuff.
                                    throw new Exception("Unexpected use of ORDER BY with GROUP BY");
                                }
                                else
                                {
                                    KeyOn = xorder;
                                }
                            }
                            else
                            {
                                throw new Exception("Expected BY after ORDER, not " + op);
                            }
                        }
                        else if (0 == string.Compare(op, "GROUP", true))
                        {
                            //DSpace_Log("DEBUG:  GROUP");
                            op = (iop < aOps.Length) ? aOps[iop++] : "";
                            if (0 == string.Compare(op, "BY", true))
                            {
                                if (!GroupBy)
                                {
                                    throw new Exception("Unexpected use of GROUP BY");
                                }
                                List <GetKeyPart> xGROUP = new List <GetKeyPart>();
                                for (; ;)
                                {
                                    op = (iop < aOps.Length) ? aOps[iop++] : "";
                                    if (0 == op.Length || ";" == op)
                                    {
                                        throw new Exception("Expected fields for GROUP BY");
                                    }
                                    int ColIndex = IndexOfCol(op);
                                    if (-1 != ColIndex)
                                    {
                                        xGROUP.Add(
                                            delegate(ByteSlice row, List <byte> AppendKeyPart)
                                        {
                                            GetKeyPartForColumn(row, ColIndex, AppendKeyPart);
                                        });
                                    }
                                    else
                                    {
                                        string sgroup;
                                        {
                                            StringBuilder sbgroup = new StringBuilder();
                                            sbgroup.Append(op);
                                            int nparens = 0;
                                            for (; ;)
                                            {
                                                op = (iop < aOps.Length) ? aOps[iop++] : "";
                                                if (0 == op.Length)
                                                {
                                                    if (0 != nparens)
                                                    {
                                                        throw new Exception("Expected ) in GROUP BY");
                                                    }
                                                    break;
                                                }
                                                sbgroup.Append(' ');
                                                sbgroup.Append(op);
                                                if ("(" == op)
                                                {
                                                    nparens++;
                                                }
                                                else if (")" == op)
                                                {
                                                    if (nparens > 0)
                                                    {
                                                        nparens--;
                                                    }
                                                    if (0 == nparens)
                                                    {
                                                        break;
                                                    }
                                                }
                                            }
                                            sgroup = sbgroup.ToString();
                                        }

                                        if (null == ftools)
                                        {
                                            ftools = new DbFunctionTools();
                                        }
                                        SelectClause     selgroup = new SelectClause(ftools, cols);
                                        List <ByteSlice> lrows    = new List <ByteSlice>(1);
                                        int rnbytes = -1;

                                        xGROUP.Add(
                                            delegate(ByteSlice row, List <byte> AppendKeyPart)
                                        {
                                            lrows.Clear();
                                            lrows.Add(row);
                                            List <DbValue> lr = selgroup.ProcessSelectPart(sgroup, lrows);
                                            sgroup            = null;
                                            if (lr.Count == 1)
                                            {
                                                DbType rtype;
                                                ByteSlice r = lr[0].Eval(out rtype);
                                                if (-1 == rnbytes)
                                                {
                                                    rnbytes = r.Length;
                                                }
                                                else
                                                {
                                                    if (rnbytes != r.Length)
                                                    {
                                                        throw new Exception("GROUP BY evaluation not returning consistent byte count");
                                                    }
                                                }
                                                if (rtype.ID == DbTypeID.CHARS)
                                                {
                                                    CellStringToCaseInsensitiveAppend(r, AppendKeyPart);
                                                }
                                                else
                                                {
                                                    r.AppendTo(AppendKeyPart);
                                                }
                                            }
                                            else
                                            {
                                                throw new Exception("Invalid number of results for GROUP BY evaluation");
                                            }
                                        });
                                    }
                                    op = (iop < aOps.Length) ? aOps[iop++] : "";
                                    if ("," != op)
                                    {
                                        if (0 == op.Length || ";" == op)
                                        {
                                            break;
                                        }
                                        //throw new Exception("Unexpected after GROUP BY ...: " + op);
                                        iop--;
                                        break;
                                    }
                                }
                                if (0 == xGROUP.Count)
                                {
                                    throw new Exception("Must be at least one column to GROUP BY");
                                }
                                KeyOn = xGROUP;
                            }
                            else
                            {
                                throw new Exception("Expected BY after GROUP, not " + op);
                            }
                        }
                        else
                        {
                            throw new Exception("Unexpected operation " + op);
                        }
                    }
                }

                ValidateSettings();
            }
예제 #8
0
            public override void Map(ByteSlice row, MapOutput output)
            {
                if (JoinType.X == type)
                {
                    ftools = new DbFunctionTools();

                    string QlLeftTableName = DSpace_ExecArgs[0];
                    LeftTableName = Qa.QlArgsUnescape(QlLeftTableName);
                    string stype            = DSpace_ExecArgs[1];
                    string QlRightTableName = DSpace_ExecArgs[2];
                    RightTableName = Qa.QlArgsUnescape(QlRightTableName);
                    string QlOn = DSpace_ExecArgs[3];
                    On = Qa.QlArgsUnescape(QlOn);
                    {
                        string LeftColInfo = Qa.QlArgsUnescape(DSpace_ExecArgs[4]);
                        int    ileq        = LeftColInfo.LastIndexOf('=');
                        string sLeftType   = LeftColInfo.Substring(ileq + 1);
                        LeftType = DbType.Prepare(sLeftType);
                        LeftConv = NeedConv(LeftType, RightType);
                        string[] st = LeftColInfo.Substring(0, ileq).Split(',');
                        LeftOffset = int.Parse(st[0]);
                        LeftSize   = int.Parse(st[1]);
                    }
                    {
                        string RightColInfo = Qa.QlArgsUnescape(DSpace_ExecArgs[5]);
                        int    ileq         = RightColInfo.LastIndexOf('=');
                        string sRightType   = RightColInfo.Substring(ileq + 1);
                        RightType = DbType.Prepare(sRightType);
                        RightConv = NeedConv(RightType, LeftType);
                        string[] st = RightColInfo.Substring(0, ileq).Split(',');
                        RightOffset = int.Parse(st[0]);
                        RightSize   = int.Parse(st[1]);
                    }
                    if (0 == string.Compare("INNER", stype, true))
                    {
                        type = JoinType.INNER_JOIN;
                    }
                    else if (0 == string.Compare("LEFT_OUTER", stype, true))
                    {
                        type = JoinType.LEFT_OUTER_JOIN;
                    }
                    else if (0 == string.Compare("RIGHT_OUTER", stype, true))
                    {
                        type = JoinType.RIGHT_OUTER_JOIN;
                    }
                    else
                    {
                        throw new NotSupportedException("DEBUG:  JOIN type not supported: " + stype);
                    }

                    string DfsTableFilesInput = DSpace_ExecArgs[6];

                    /*
                     * TableFileNames = DfsTableFilesInput.Split(';');
                     * if (2 != TableFileNames.Length)
                     * {
                     *  throw new Exception("DEBUG:  Invalid number of tables");
                     * }
                     * for (int it = 0; it < TableFileNames.Length; it++)
                     * {
                     *  if (TableFileNames[it].StartsWith("dfs://", StringComparison.OrdinalIgnoreCase))
                     *  {
                     *      TableFileNames[it] = TableFileNames[it].Substring(6);
                     *  }
                     *  int iat = TableFileNames[it].IndexOf('@');
                     *  if (-1 != iat)
                     *  {
                     *      TableFileNames[it] = TableFileNames[it].Substring(0, iat);
                     *  }
                     * }
                     * */
                }

                int tableid = GetTableID(row);

                ByteSlice key;

                if (0 == tableid)
                {
                    key = ByteSlice.Prepare(row, LeftOffset, LeftSize);
                    if (null != LeftConv)
                    {
                        key = LeftConv(key, DSpace_KeyLength, ftools);
                    }
                }
                else if (1 == tableid)
                {
                    key = ByteSlice.Prepare(row, RightOffset, RightSize);
                    if (null != RightConv)
                    {
                        key = RightConv(key, DSpace_KeyLength, ftools);
                    }
                }
                else
                {
                    throw new Exception("Map: Unexpected TableID: " + tableid);
                }

                List <byte> valuebuf = ftools.AllocBuffer(1 + 4 + row.Length);

                {
                    DbValue tableiddbvalue = ftools.AllocValue(tableid);
                    tableiddbvalue.Eval().AppendTo(valuebuf);
                }
                row.AppendTo(valuebuf);

                output.Add(key, ByteSlice.Prepare(valuebuf));

                ftools.ResetBuffers();
            }
예제 #9
0
            public override void OnRemote(IEnumerator <ByteSlice> input, System.IO.Stream output)
            {
                string TableName     = DSpace_ExecArgs[0];
                string DfsOutputName = DSpace_ExecArgs[1]; // Actually the input of this job.
                string RowInfo       = Qa.QlArgsUnescape(DSpace_ExecArgs[2]);
                string DisplayInfo   = DSpace_ExecArgs[3];
                long   TopCount      = long.Parse(DSpace_ExecArgs[4]);
                string sOptions      = (DSpace_ExecArgs.Length > 5) ? DSpace_ExecArgs[5] : "";
                bool   joined        = -1 != sOptions.IndexOf("JOINED");

                InitColInfos(RowInfo, DisplayInfo);

                StringBuilder sb = new StringBuilder();

                sb.Length = 0;
                bool ShouldCleanName = !joined;

                foreach (ColInfo ci in cols)
                {
                    string name = ci.Name;
                    if (ShouldCleanName)
                    {
                        name = CleanColumnName(ci.Name);
                    }
                    sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", name);
                }
                string hsep = new string('-', sb.Length);

                DSpace_Log(sb.ToString());
                DSpace_Log(hsep);

                for (ByteSlice rowbuf;
                     (TopCount == -1 || TopCount > 0) &&
                     input.MoveNext();
                     )
                {
                    rowbuf = input.Current;

                    sb.Length = 0;
                    foreach (ColInfo ci in cols)
                    {
                        ByteSlice cval = ByteSlice.Prepare(rowbuf, ci.StartOffset, ci.Size);
                        if (0 != cval[0])
                        {
                            sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", "NULL");
                        }
                        else
                        {
                            if (ci.Type.StartsWith("char"))
                            {
                                string charsvalue = System.Text.Encoding.Unicode.GetString(ByteSlice.Prepare(cval, 1, cval.Length - 1).ToBytes());
                                charsvalue = charsvalue.TrimEnd('\0');
                                sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", charsvalue);
                            }
                            else if ("int" == ci.Type)
                            {
                                Int32 x = Entry.BytesToInt(ByteSlice.Prepare(cval, 1, cval.Length - 1).ToBytes());
                                x = Entry.ToInt32((UInt32)x);
                                sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", x);
                            }
                            else if ("long" == ci.Type)
                            {
                                Int64 x = Entry.BytesToLong(ByteSlice.Prepare(cval, 1, cval.Length - 1).ToBytes());
                                x = Entry.ToInt64((UInt64)x);
                                sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", x);
                            }
                            else if ("double" == ci.Type)
                            {
                                recordset rs = recordset.Prepare(ByteSlice.Prepare(cval, 1, cval.Length - 1));
                                double    x  = rs.GetDouble();
                                sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", x);
                            }
                            else if ("DateTime" == ci.Type)
                            {
                                Int64    x  = Entry.BytesToLong(ByteSlice.Prepare(cval, 1, cval.Length - 1).ToBytes());
                                DateTime dt = new DateTime(x);
                                sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ", dt);
                            }
                            else
                            {
                                sb.AppendFormat("{0,-" + ci.DisplayWidth.ToString() + "} ",
                                                "?"); // Not supported yet.
                            }
                        }
                    }
                    DSpace_Log(sb.ToString());
                    if (TopCount != -1)
                    {
                        TopCount--;
                    }
                }

                DSpace_Log(hsep);
            }
예제 #10
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);
                     * }*/
                }
            }
        }
예제 #11
0
            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));
                }
            }