Пример #1
0
  public Select( G.List<Exp> exps, TableExpression te, Exp where, Exp[] group, OrderByExp[] order, bool [] used, SqlExec x )
  {
    /* There is more work to be done here, for example 2 * SUM(Total) is currently not allowed.
       Also if there is a GROUP BY, SELECT expressions should not be allowed to access fields not in the group list,
       unless thereis an enclosing aggregate function.
       Also maybe common sub-expression analysis, and perhaps constant folding, could be done?
    */ 

    Exps = exps; TE = te; Where = where; Order = order; 

    ColumnCount = exps.Count; 
    var names = new string[ ColumnCount ];
    var types = new DataType[ ColumnCount ];
    for ( int i = 0; i < ColumnCount; i += 1 )
    {
      names[ i ] = exps[ i ].Name;
      types[ i ] = exps[ i ].Type;
    }
    CI = new ColInfo( names, types );

    if ( x.ParseOnly ) return;

    Used = Util.ToList( used );

    if ( group != null )
    {
      // Compute AggSpec and GroupSpec
      var alist = new G.List<AggSpec>();
      for ( int i = 0; i < exps.Count; i += 1 )
      {
        Exp e = exps[ i ];
        AggOp op = e.GetAggOp();
        if ( op != AggOp.None )
        {
          AggSpec a = new AggSpec();
          a.ColIx = i;
          a.Type = e.Type;
          a.Op = op;
          alist.Add( a );
        }
      }
      AggSpec = alist.ToArray();

      var glist = new G.List<GroupSpec>();
      for ( int i=0; i < group.Length; i += 1 )
      {
        GroupSpec g = new GroupSpec();
        g.ColIx = Exps.Count;
        g.Type = group[ i ].Type;
        Exps.Add( group[ i ] );
        glist.Add( g );
      }
      GroupSpec = glist.ToArray();
    }

    if ( Order != null )
    {
      var sortSpec = new SortSpec[ Order.Length ]; 

      for ( int i = 0; i < Order.Length; i += 1 )
      {
        // Quite complicated as ORDER BY can use aliases or expressions.
        Exp e = Order[ i ].E;
        sortSpec[ i ].Desc = Order[ i ].Desc;

        int cix = -1;
        if ( e is ExpName )
        {
          string alias = ((ExpName)e).ColName;   
          for ( int j = 0; j < CI.Count; j += 1 )
          {
            if ( CI.Name[j] == alias )
            {
              e = Exps[ j ];
              cix = j;
              break;
            }
          }
        }
        if ( cix < 0 )
        {
          cix = Exps.Count;
          Exps.Add( e );
          e.Bind( x );   
        }     
        sortSpec[ i ].Type = e.Type;
        sortSpec[ i ].ColIx = cix;       
      }
      SortSpec = sortSpec;
    }

    Dvs = Util.GetDVList( Exps.ToArray() );

    if ( Where != null ) WhereD = Where.GetDB();

    Ids = Where == null ? null : Where.GetIdSet( TE );
    if ( Ids != null ) Ids = new IdCopy( Ids ); // Need to take a copy of the id values if an index is used.
  }
Пример #2
0
  public Select( G.List<Exp> exps, TableExpression te, Exp where, Exp[] group, OrderByExp[] order, bool [] used, SqlExec x )
  {
    Exps = exps; TE = te; Where = where; Order = order; Used = used;

    ColumnCount = exps.Count; 
    var names = new string[ ColumnCount ];
    var types = new DataType[ ColumnCount ];
    for ( int i = 0; i < ColumnCount; i += 1 )
    {
      names[i] = exps[i].Name;
      types[i] = exps[i].Type;
    }
    Cols = new ColInfo( names, types );

    if ( x.ParseOnly ) return;

    if ( group != null )
    {
      // Compute AggSpec and GroupSpec
      var alist = new G.List<AggSpec>();
      for ( int i = 0; i < exps.Count; i += 1 )
      {
        Exp e = exps[i];
        AggOp op = e.GetAggOp();
        if ( op != AggOp.None )
        {
          AggSpec a = new AggSpec();
          a.ColIx = i;
          a.Type = e.Type;
          a.Op = op;
          alist.Add( a );
        }
      }
      AggSpec = alist.ToArray();

      var glist = new G.List<GroupSpec>();
      for ( int i=0; i < group.Length; i += 1 )
      {
        GroupSpec g = new GroupSpec();
        g.ColIx = Exps.Count; // Note: we could look in Exps to see if it is already there rather than adding an extra Exp.
        g.Type = group[ i ].Type;
        Exps.Add( group[ i ] );
        glist.Add( g );
      }
      GroupSpec = glist.ToArray();
    }

    if ( Order != null )
    {
      var sortSpec = new SortSpec[ Order.Length ]; 

      for ( int i = 0; i < Order.Length; i += 1 )
      {
        // Quite complicated as ORDER BY can use aliases or expressions.
        Exp e = Order[i].E;
        sortSpec[ i ].Desc = Order[i].Desc;

        bool found = false;
        if ( e is ExpName )
        {
          string alias = ((ExpName)e).ColName;   
          for ( int j = 0; j < Cols.Count; j += 1 )
          {
            if ( Cols.Names[j] == alias )
            {
              e = Exps[ j ];
              found = true;
              break;
            }
          }
        }
        int cix = Exps.Count;
        Exps.Add( e );    
        if ( !found ) e.Bind( x );    
        sortSpec[ i ].Type = e.Type;
        sortSpec[ i ].ColIx = cix;       
      }
      SortSpec = sortSpec;
    }
  }