Ejemplo n.º 1
0
        // Callback function to evaluate an expression
        public object EvaluateCommon(ExpressionEval expr, FuncTypes functype, object[] values, int haccum, int naccum)
        {
            var        lookup = GetLookup(expr, values);
            TypedValue retval = null;

            switch (functype)
            {
            case FuncTypes.Open:
                retval = expr.EvalOpen(lookup);
                break;

            case FuncTypes.Predicate:
                retval = expr.EvalPred(lookup);
                break;

            case FuncTypes.Aggregate:
            case FuncTypes.Ordered:
                var accblk = GetAccum(haccum, naccum);
                retval        = expr.EvalHasFold(lookup, accblk as AccumulatorBlock);
                accblk.Result = retval;
                PutAccum(haccum, accblk);
                break;
            }
            return(SqlTarget.ToObjectDict[retval.DataType.BaseType](retval));
        }
Ejemplo n.º 2
0
        public override DataTable Restrict(ExpressionEval expr)
        {
            _database.RegisterExpressions(expr);
            var newtable = AddWhere(expr, HasGroupBy);

            Logger.WriteLine(4, "[Res '{0}']", newtable);
            return(newtable);
        }
Ejemplo n.º 3
0
        //--- functions to manipulate queries

        // generate SQL code for restrict
        DataTableSql AddWhere(ExpressionEval expr, bool hasgroupby)
        {
            if (SqlWhereText != null)
            {
                return(DataTableSql.CreateFromSubquery(this).AddWhere(expr, hasgroupby));
            }
            SqlWhereText = (hasgroupby) ? _gen.Having(expr) : _gen.Where(expr);
            return(this);
        }
Ejemplo n.º 4
0
        // Reorder expressions to match heading
        public ExpressionEval[] Reorder(ExpressionEval[] exprs)
        {
            Logger.Assert(exprs.Length == Degree && exprs.All(e => FindIndex(e.Name) >= 0), "reorder mismatch");
            var newexprs = new ExpressionEval[exprs.Length];

            foreach (var e in exprs)
            {
                newexprs[FindIndex(e.Name)] = e;
            }
            return(newexprs);
        }
Ejemplo n.º 5
0
        // Return value of attribute with tuple indexing
        // FIX: needs to get from this row to some other row via parent table to use as lookup
        public TypedValue ValueOffset(ExpressionEval expr, int index, OffsetModes mode)
        {
            var parent = Parent as DataTableLocal;

            Logger.Assert(parent != null);
            var ord   = OrderedIndex.Offset(this, index, mode);
            var value = (ord == -1) ? expr.ReturnType.DefaultValue()
        : expr.EvalOpen(parent.GetRow(ord));

            return(value);
        }
Ejemplo n.º 6
0
        // Restrict -- new table containing rows that pass the test
        public override DataTable Restrict(ExpressionEval expr)
        {
            var newtable = DataTableLocal.Create(Heading);

            foreach (var row in GetRows()) //TODO:Enumerable
            {
                if (expr.EvalPred(row).Value)
                {
                    newtable.AddRow(row);
                }
            }
            Logger.WriteLine(4, "Restrict {0}", newtable);
            return(newtable);
        }
Ejemplo n.º 7
0
        // create a lookup for an expression from a set of values
        LookupHolder GetLookup(ExpressionEval expr, object[] ovalues)
        {
            // build the lookup
            var lookup = new LookupHolder();

            for (int i = 0; i < expr.NumArgs; ++i)
            {
                var datatype = expr.Lookup.Columns[i].DataType;
                var value    = (ovalues[i] == null) ? datatype.DefaultValue()
          : SqlTarget.FromObjectDict[datatype.BaseType](ovalues[i], datatype);
                lookup.LookupDict.Add(expr.Lookup.Columns[i].Name, value);
            }
            return(lookup);
        }
Ejemplo n.º 8
0
 // Execute an update that is a DELETE (no exprs) or UPDATE
 public override DataTable UpdateTransform(ExpressionEval pred, ExpressionEval[] exprs)
 {
     _database.RegisterExpressions(pred);
     _database.RegisterExpressions(exprs);
     if (exprs.Length == 0)
     {
         string sql = _gen.Delete(TableName, pred);
         _database.OpenStatement();
         _database.ExecuteCommand(sql);
         _database.CloseStatement();
     }
     else
     {
         string sql = _gen.Update(TableName, pred, exprs);
         _database.OpenStatement();
         _database.ExecuteCommand(sql);
         _database.CloseStatement();
     }
     return(this);
 }
Ejemplo n.º 9
0
        // Register an expression that will be used in a query
        // An expression is the RHS of an attribute assignment (not just a function)
        // Can only be Rename, Project, Open, Aggregate: only last two needed
        public bool RegisterExpression(ExpressionEval expr, int naccum)
        {
            if (!(expr.IsOpen || expr.HasFold))
            {
                return(true);
            }

            // Check whether new registration or update (to new evaluator)
            // TODO: check it's the same expr
            var updating = ExprDict.ContainsKey(expr.Serial);
            var name     = SqlGen.FuncName(expr);

            ExprDict[expr.Serial] = expr;
            Logger.WriteLine(3, $"Register {name} upd={updating} nacc={naccum} expr={expr}");
            if (updating)
            {
                return(true);
            }

            // notify database, set up callbacks
            // may require sql to register (PG)
            // FIX: would be better in PostgresDatabase, but does not have access to sql gen (and data types).
            var args = expr.Lookup.Columns.Select(c => ToSqlCommon[c.DataType.BaseType]).ToArray();
            var retn = ToSqlCommon[expr.ReturnType.BaseType];

            if (expr.HasFold)
            {
                // note: type must match low level wrappers
                var stype = DataTypes.Number;
                var init  = NumberValue.Zero;
                var col0  = new DataColumn[] { DataColumn.Create("_state_", stype) };
                OptionalExpressionSql(_sqlgen.CreateFunction(name, col0.Concat(expr.Lookup.Columns).ToArray(), stype));
                OptionalExpressionSql(_sqlgen.CreateFunction(name + "F", col0, expr.ReturnType));
                OptionalExpressionSql(_sqlgen.CreateAggregate(name, expr.Lookup.Columns, stype, init, name, name + "F"));
                return(FunctionCreator.CreateAggFunction(name, expr.Serial, naccum, args, retn));
            }
            // expr.IsOpen
            OptionalExpressionSql(_sqlgen.CreateFunction(name, expr.Lookup.Columns, expr.ReturnType));
            return(FunctionCreator.CreateFunction(name, FuncTypes.Open, expr.Serial, args, retn));
        }
Ejemplo n.º 10
0
        // Recursive expansion
        // Creates new empty table, add seed, join op (only union for now) and expression
        public override DataTable Recurse(int flags, ExpressionEval expr)
        {
            Logger.WriteLine(4, "Recurse {0} {1}", flags, expr);
            Logger.Assert(expr.ReturnType == DataType);

            var newtable = DataTableLocal.Create(Heading);

            foreach (var row in _rows)
            {
                newtable.AddRaw(row);
            }

            // by ordinal, to main position and notice new rows
            for (var ord = 0; ord < newtable._rows.Count; ++ord)
            {
                var newrows = expr.EvalOpen(newtable._rows[ord]).AsTable();
                foreach (var row in newrows.GetRows())
                {
                    newtable.AddRow(row);
                }
            }
            return(newtable);
        }
Ejemplo n.º 11
0
        // Update Transform, handles Delete and Update
        public override DataTable UpdateTransform(ExpressionEval pred, ExpressionEval[] exprs)
        {
            Logger.WriteLine(4, "UpdateTransform {0}", Heading);

            var updating = (exprs.Length > 0); // false means this is just a delete
            var newexprs = (updating) ? Heading.Reorder(exprs) : null;
            // pass 1 - new rows
            var relins = DataTableLocal.Create(Heading);

            for (var ord = 0; ord < _rows.Count;) //TODO:Enumerable
            {
                if (pred.EvalPred(_rows[ord]).Value)
                {
                    if (updating)
                    {
                        //if (exprs.Length > 0)
                        relins.AddRow(_rows[ord].Transform(Heading, newexprs));
                    }
                    // deleting a row will replace row at ord with a different one, not yet tested
                    DeleteRaw(ord);
                }
                else
                {
                    ord++;
                }
            }
            foreach (var row in relins.GetRows())
            {
                AddRaw(row);
            }

            // TODO: update persistence store

            Logger.WriteLine(4, "[UpSelect={0}]", this);
            return(this);
        }
Ejemplo n.º 12
0
 public override DataTable Recurse(int flags, ExpressionEval expr)
 {
     throw ProgramError.Fatal("Sql data", "while not supported");
 }
Ejemplo n.º 13
0
 public abstract DataTable UpdateTransform(ExpressionEval pred, ExpressionEval[] exprs);
Ejemplo n.º 14
0
 public abstract DataTable Recurse(int flags, ExpressionEval expr);
Ejemplo n.º 15
0
 public abstract DataTable Restrict(ExpressionEval expr);
Ejemplo n.º 16
0
        // Evaluation engine for ByteCode
        TypedValue Run(ByteCode bcode, TypedValue aggregate, AccumulatorBlock accblock)
        {
            TypedValue retval = null;
            var        reader = PersistReader.Create(bcode.bytes);

            while (reader.More)
            {
                var opcode = reader.ReadOpcode();
                switch (opcode)
                {
                // Known literal, do not translate into value
                case Opcodes.LDVALUE:
                    PushStack(reader.ReadValue());
                    break;
                // Known catalog variable, look up value
                //case Opcodes.LDCAT:
                //  var catnam = reader.ReadString();
                //  var catval = CatVars.GetValue(catnam);
                //  Logger.Assert(catval != null, $"{opcode}:{catnam}");
                //  if (catval.DataType is DataTypeCode)
                //    catval = this.Exec((catval as CodeValue).Value.Code);
                //  _stack.Push(catval);
                //  break;

                // Catalog variable, look up value (could be code)
                case Opcodes.LDCAT:
                    var catnam = reader.ReadString();
                    var catval = CatVars.GetValue(catnam);
                    Logger.Assert(catval != null, $"{opcode}:{catnam}");
                    _stack.Push(catval);
                    break;

                // Catalog variable, must be code, evaluate
                case Opcodes.LDCATV:
                    var ctvnam = reader.ReadString();
                    var ctvval = CatVars.GetValue(ctvnam) as CodeValue;
                    Logger.Assert(ctvval != null, $"{opcode}:{ctvnam}");
                    _stack.Push(this.Exec((ctvval as CodeValue).Value.Code));
                    break;

                // Catalog variable, must be code, as code value
                case Opcodes.LDCATR:
                    var ctrnam = reader.ReadString();
                    var ctrval = CatVars.GetValue(ctrnam) as CodeValue;
                    Logger.Assert(ctrval != null, $"{opcode}:{ctrnam}");
                    PushStack(CodeValue.Create(ExpressionEval.Create(this, ctrval.Value)));
                    break;

                // Load value obtained using lookup by name
                case Opcodes.LDFIELD:
                    var fldval = TypedValue.Empty;
                    var fldnam = reader.ReadString();
                    var fldok  = LookupValue(fldnam, ref fldval);
                    Logger.Assert(fldok, $"{opcode}:{fldnam}");
                    PushStack(fldval);
                    break;

                // Load aggregate value or use specified start value if not available
                case Opcodes.LDAGG:
                    var aggval = reader.ReadValue();
                    PushStack(aggregate ?? aggval);
                    break;

                // load accumulator by index, or fixed value if not available
                case Opcodes.LDACC:
                    var accnum = reader.ReadInteger();
                    var accval = reader.ReadValue();
                    PushStack(accblock == null ? accval : accblock[accnum]);
                    break;

                // Load a segment of code for later call, with this evaluator packaged in
                case Opcodes.LDSEG:
                    var segexp = reader.ReadExpr();
                    var segval = CodeValue.Create(ExpressionEval.Create(this, segexp));
                    PushStack(segval);
                    break;

                case Opcodes.LDLOOKUP:
                    var lkpobj = PointerValue.Create(_lookups.Peek() as object);
                    PushStack(lkpobj);
                    break;

                case Opcodes.LDACCBLK:
                    var acbobj = PointerValue.Create(accblock as object);
                    PushStack(acbobj);
                    break;

                case Opcodes.LDCOMP:
                    var cmpudt = _stack.Pop() as UserValue;
                    var cmpval = cmpudt.GetComponentValue(reader.ReadString());
                    PushStack(cmpval);
                    break;

                case Opcodes.LDFIELDT:
                    var fdttup = _stack.Pop() as TupleValue;
                    var fdtval = fdttup.GetFieldValue(reader.ReadString());
                    PushStack(fdtval);
                    break;

                // Call a function, fixed or variable arg count
                case Opcodes.CALL:
                case Opcodes.CALLV:
                case Opcodes.CALLVT:
                    var calname   = reader.ReadString();
                    var calmeth   = typeof(Builtin).GetMethod(calname);
                    var calnargs  = reader.ReadByte();
                    var calnvargs = reader.ReadByte();
                    var calargs   = new object[calnargs];
                    var calargx   = calargs.Length - 1;
                    if (opcode == Opcodes.CALLV)
                    {
                        var vargs = new CodeValue[calnvargs];
                        for (var j = vargs.Length - 1; j >= 0; --j)
                        {
                            vargs[j] = _stack.Pop() as CodeValue;
                        }
                        calargs[calargx--] = vargs;
                    }
                    else if (opcode == Opcodes.CALLVT)
                    {
                        var vargs = new TypedValue[calnvargs];
                        for (var j = vargs.Length - 1; j >= 0; --j)
                        {
                            vargs[j] = _stack.Pop() as TypedValue;
                        }
                        calargs[calargx--] = vargs;
                    }
                    for (; calargx >= 0; --calargx)
                    {
                        calargs[calargx] = _stack.Pop();
                    }
                    var ret = calmeth.Invoke(_builtin, calargs) as TypedValue;
                    _stack.Push(ret);
                    //if (ret.DataType != DataTypes.Void)
                    //  _stack.Push(ret);
                    break;

                case Opcodes.EOS:
                    retval = _stack.Pop();
                    //retval = (_stack.Count > 0) ? _stack.Pop() : VoidValue.Void;
                    break;

                default:
                    throw new NotImplementedException(opcode.ToString());
                }
            }
            if (retval == null)
            {
                retval = _stack.Pop();
            }
            //Logger.Assert(retval != null, "stack");
            return(retval);
        }