// 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)); }
///------------------------------------------------------------------- /// /// Catalog info /// // Construct and return a heading for a database table // return null if not found or error // TODO: public DataHeading GetTableHeading(string table) { Tuple <string, SqlCommonType>[] columns; // optional sql var sql = SqlGen.GetColumns(table); var optsql = sql.Length > 0; Logger.WriteLine(3, "GetTableHeading {0}", optsql ? sql : table); if (optsql) { Logger.WriteLine(2, ">>>(th){0}", sql); } Logger.Assert(_database != null, "gth"); var ok = _database.GetTableColumns(optsql ? sql : table, out columns); if (!ok || columns.Length == 0) { return(null); } var cols = columns.Select(c => DataColumn.Create(c.Item1, FromSqlCommon[c.Item2])); return(DataHeading.Create(cols)); // ignore column order }
//--- factories DataTableSql() { _database = SqlTarget.Current; _gen = SqlTarget.Current.SqlGen; }