// processAliasedTable produces a builder subtree for the given AliasedTableExpr. // If the expression is a subquery, then the the route built for it will contain // the entire subquery tree in the from clause, as if it was a table. // The symtab entry for the query will be a tabsym where the columns // will be built from the select expressions of the subquery. // Since the table aliases only contain vindex columns, we'll follow // the same rule: only columns from the subquery that are identified as // vindex columns will be added to the tabsym. // A symtab symbol can only point to a route. This means that we canoot // support complex joins in subqueries yet. func processAliasedTable(tableExpr *sqlparser.AliasedTableExpr, vschema VSchema) (builder, error) { switch expr := tableExpr.Expr.(type) { case *sqlparser.TableName: eroute, table, err := getTablePlan(expr, vschema) if err != nil { return nil, err } alias := sqlparser.SQLName(sqlparser.String(expr)) astName := expr.Name if tableExpr.As != "" { alias = tableExpr.As astName = alias } return newRoute( sqlparser.TableExprs([]sqlparser.TableExpr{tableExpr}), eroute, table, vschema, alias, astName, ), nil case *sqlparser.Subquery: sel, ok := expr.Select.(*sqlparser.Select) if !ok { return nil, errors.New("unsupported: union operator in subqueries") } subplan, err := processSelect(sel, vschema, nil) if err != nil { return nil, err } subroute, ok := subplan.(*route) if !ok { return nil, errors.New("unsupported: complex join in subqueries") } table := &vindexes.Table{ Keyspace: subroute.ERoute.Keyspace, } for _, colsyms := range subroute.Colsyms { if colsyms.Vindex == nil { continue } table.ColVindexes = append(table.ColVindexes, &vindexes.ColVindex{ Col: string(colsyms.Alias), Vindex: colsyms.Vindex, }) } rtb := newRoute( sqlparser.TableExprs([]sqlparser.TableExpr{tableExpr}), subroute.ERoute, table, vschema, tableExpr.As, tableExpr.As, ) subroute.Redirect = rtb return rtb, nil } panic("unreachable") }
// processAliasedTable produces a builder subtree for the given AliasedTableExpr. // If the expression is a subquery, then the the route built for it will contain // the entire subquery tree in the from clause, as if it was a table. // The symtab entry for the query will be a tabsym where the columns // will be built from the select expressions of the subquery. // Since the table aliases only contain vindex columns, we'll follow // the same rule: only columns from the subquery that are identified as // vindex columns will be added to the tabsym. // A symtab symbol can only point to a route. This means that we canoot // support complex joins in subqueries yet. func processAliasedTable(tableExpr *sqlparser.AliasedTableExpr, vschema VSchema) (builder, error) { switch expr := tableExpr.Expr.(type) { case *sqlparser.TableName: eroute, table, err := getTablePlan(expr, vschema) if err != nil { return nil, err } alias := sqlparser.TableIdent(sqlparser.String(expr)) astName := expr.Name if tableExpr.As != "" { alias = tableExpr.As astName = alias } return newRoute( sqlparser.TableExprs([]sqlparser.TableExpr{tableExpr}), eroute, table, vschema, alias, astName, ), nil case *sqlparser.Subquery: sel, ok := expr.Select.(*sqlparser.Select) if !ok { return nil, errors.New("unsupported: union operator in subqueries") } subplan, err := processSelect(sel, vschema, nil) if err != nil { return nil, err } subroute, ok := subplan.(*route) if !ok { return nil, errors.New("unsupported: complex join in subqueries") } table := &vindexes.Table{ Keyspace: subroute.ERoute.Keyspace, } for _, colsyms := range subroute.Colsyms { if colsyms.Vindex == nil { continue } // Check if a colvindex of the same name already exists. // Dups are not allowed in subqueries in this situation. for _, colVindex := range table.ColumnVindexes { if colVindex.Column.Equal(cistring.CIString(colsyms.Alias)) { return nil, fmt.Errorf("duplicate column aliases: %v", colsyms.Alias) } } table.ColumnVindexes = append(table.ColumnVindexes, &vindexes.ColumnVindex{ Column: cistring.CIString(colsyms.Alias), Vindex: colsyms.Vindex, }) } rtb := newRoute( sqlparser.TableExprs([]sqlparser.TableExpr{tableExpr}), subroute.ERoute, table, vschema, tableExpr.As, tableExpr.As, ) subroute.Redirect = rtb return rtb, nil } panic("unreachable") }