func columnsFromJoin(from *SqlSource, node expr.Node, cols Columns) Columns {
	if node == nil {
		return cols
	}
	//u.Debugf("columnsFromJoin()  T:%T  node=%q", node, node.String())
	switch nt := node.(type) {
	case *expr.IdentityNode:
		if left, right, ok := nt.LeftRight(); ok {
			//u.Debugf("from.Name:%v AS %v   Joinnode l:%v  r:%v    %#v", from.Name, from.alias, left, right, nt)
			//u.Warnf("check cols against join expr arg: %#v", nt)
			if left == from.alias {
				found := false
				for _, col := range cols {
					colLeft, colRight, _ := col.LeftRight()
					//u.Debugf("left='%s'  colLeft='%s' right='%s'  %#v", left, colLeft, colRight,  col)
					//u.Debugf("col:  From %s AS '%s'   '%s'.'%s'  JoinExpr: '%v'.'%v' col:%#v", from.Name, from.alias, colLeft, colRight, left, right, col)
					if left == colLeft || colRight == right {
						found = true
						//u.Infof("columnsFromJoin from.Name:%v l:%v  r:%v", from.alias, left, right)
					} else {
						//u.Warnf("not? from.Name:%v l:%v  r:%v   col: P:%p %#v", from.alias, left, right, col, col)
					}
				}
				if !found {
					//u.Debugf("columnsFromJoin from.Name:%v l:%v  r:%v", from.alias, left, right)
					newCol := &Column{As: right, SourceField: right, Expr: &expr.IdentityNode{Text: right}}
					newCol.Index = len(cols)
					newCol.ParentIndex = -1 // if -1, we don't need in parent index
					cols = append(cols, newCol)
					//u.Warnf("added col %s idx:%d pidx:%v", right, newCol.Index, newCol.Index)
				}
			}
		}
	case *expr.FuncNode:
		//u.Warnf("columnsFromJoin func node: %s", nt.String())
		for _, arg := range nt.Args {
			cols = columnsFromJoin(from, arg, cols)
		}
	case *expr.BinaryNode:
		switch nt.Operator.T {
		case lex.TokenAnd, lex.TokenLogicAnd, lex.TokenLogicOr:
			cols = columnsFromJoin(from, nt.Args[0], cols)
			cols = columnsFromJoin(from, nt.Args[1], cols)
		case lex.TokenEqual, lex.TokenEqualEqual:
			cols = columnsFromJoin(from, nt.Args[0], cols)
			cols = columnsFromJoin(from, nt.Args[1], cols)
		default:
			u.Warnf("un-implemented op: %v", nt.Operator)
		}
	default:
		u.LogTracef(u.INFO, "whoops")
		u.Warnf("%T node types are not suppored yet for join rewrite %s", node, from.String())
	}
	return cols
}
// We need to find all columns used in the given Node (where/join expression)
//  to ensure we have those columns in projection for sub-queries
We need to find all columns used in the given Node (where/join expression)
to ensure we have those columns in projection for sub-queries
// We need to find all columns used in the given Node ( where / join expression ) // to ensure we have those columns in projection for sub - queries
func columnsFromJoin(from *SqlSource, node expr.Node, cols Columns) Columns {
	if node == nil {
		return cols
	}
	switch nt := node.(type) {
	case *expr.IdentityNode:
		if left, right, ok := nt.LeftRight(); ok {
			if left == from.alias {
				found := false
				for _, col := range cols {
					colLeft, colRight, _ := col.LeftRight()
					if left == colLeft || colRight == right {
						found = true
					} else {
					}
				}
				if !found {
					newCol := &Column{As: right, SourceField: right, Expr: &expr.IdentityNode{Text: right}}
					newCol.Index = len(cols)
					newCol.ParentIndex = -1 
					cols = append(cols, newCol)
				}
			}
		}
	case *expr.FuncNode:
		for _, arg := range nt.Args {
			cols = columnsFromJoin(from, arg, cols)
		}
	case *expr.BinaryNode:
		switch nt.Operator.T {
		case lex.TokenAnd, lex.TokenLogicAnd, lex.TokenLogicOr:
			cols = columnsFromJoin(from, nt.Args[0], cols)
			cols = columnsFromJoin(from, nt.Args[1], cols)
		case lex.TokenEqual, lex.TokenEqualEqual:
			cols = columnsFromJoin(from, nt.Args[0], cols)
			cols = columnsFromJoin(from, nt.Args[1], cols)
		default:
			u.Warnf("un-implemented op: %v", nt.Operator)
		}
	default:
		u.LogTracef(u.INFO, "whoops")
		u.Warnf("%T node types are not suppored yet for join rewrite %s", node, from.String())
	}
	return cols
}
func columnsFromJoin ( from * SqlSource , node expr . Node , cols Columns ) Columns { if node == nil { return cols } switch nt := node . ( type ) { case * expr . IdentityNode : if left , right , ok := nt . LeftRight ( ) ; ok { if left == from . alias { found := false for _ , col := range cols { colLeft , colRight , _ := col . LeftRight ( ) if left == colLeft || colRight == right { found = true } else { } } if ! found { newCol := & Column { As : right , SourceField : right , Expr : & expr . IdentityNode { Text : right } } newCol . Index = len ( cols ) newCol . ParentIndex = - 1 cols = append ( cols , newCol ) } } } case * expr . FuncNode : for _ , arg := range nt . Args { cols = columnsFromJoin ( from , arg , cols ) } case * expr . BinaryNode : switch nt . Operator . T { case lex . TokenAnd , lex . TokenLogicAnd , lex . TokenLogicOr : cols = columnsFromJoin ( from , nt . Args [ 0 ] , cols ) cols = columnsFromJoin ( from , nt . Args [ 1 ] , cols ) case lex . TokenEqual , lex . TokenEqualEqual : cols = columnsFromJoin ( from , nt . Args [ 0 ] , cols ) cols = columnsFromJoin ( from , nt . Args [ 1 ] , cols ) default : u . Warnf ( " " , nt . Operator ) } default : u . LogTracef ( u . INFO , " " ) u . Warnf ( " " , node , from . String ( ) ) } return cols }
We need to find all columns used in the given Node (where/join expression)
to ensure we have those columns in projection for sub-queries
We need to find all columns used in the given Node ( where / join expression ) to ensure we have those columns in projection for sub - queries
//u.Debugf("columnsFromJoin()  T:%T  node=%q", node, node.String()) //u.Debugf("from.Name:%v AS %v   Joinnode l:%v  r:%v    %#v", from.Name, from.alias, left, right, nt) //u.Warnf("check cols against join expr arg: %#v", nt) //u.Debugf("left='%s'  colLeft='%s' right='%s'  %#v", left, colLeft, colRight,  col) //u.Debugf("col:  From %s AS '%s'   '%s'.'%s'  JoinExpr: '%v'.'%v' col:%#v", from.Name, from.alias, colLeft, colRight, left, right, col) //u.Infof("columnsFromJoin from.Name:%v l:%v  r:%v", from.alias, left, right) //u.Warnf("not? from.Name:%v l:%v  r:%v   col: P:%p %#v", from.alias, left, right, col, col) //u.Debugf("columnsFromJoin from.Name:%v l:%v  r:%v", from.alias, left, right) // if -1, we don't need in parent index //u.Warnf("added col %s idx:%d pidx:%v", right, newCol.Index, newCol.Index) //u.Warnf("columnsFromJoin func node: %s", nt.String())