Beispiel #1
0
// 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
			}
			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")
}
Beispiel #2
0
// FindVindex returns the vindex if one was found for the column.
func (t *tabsym) FindVindex(name sqlparser.ColIdent) vindexes.Vindex {
	for _, colVindex := range t.ColumnVindexes {
		if colVindex.Column.Equal(cistring.CIString(name)) {
			return colVindex.Vindex
		}
	}
	return nil
}
Beispiel #3
0
// isIndexChanging returns true if any of the update
// expressions modify a vindex column.
func isIndexChanging(setClauses sqlparser.UpdateExprs, colVindexes []*vindexes.ColumnVindex) bool {
	for _, assignment := range setClauses {
		for _, vcol := range colVindexes {
			if vcol.Column.Equal(cistring.CIString(assignment.Name)) {
				return true
			}
		}
	}
	return false
}
Beispiel #4
0
func findOrInsertPos(ins *sqlparser.Insert, col cistring.CIString, rowNum int) (row sqlparser.ValTuple, pos int) {
	pos = -1
	for i, column := range ins.Columns {
		if col.Equal(cistring.CIString(column)) {
			pos = i
			break
		}
	}
	if pos == -1 {
		pos = len(ins.Columns)
		ins.Columns = append(ins.Columns, sqlparser.ColIdent(col))
	}
	if pos == -1 || pos >= len(ins.Rows.(sqlparser.Values)[rowNum].(sqlparser.ValTuple)) {
		ins.Rows.(sqlparser.Values)[rowNum] = append(ins.Rows.(sqlparser.Values)[rowNum].(sqlparser.ValTuple), &sqlparser.NullVal{})
	}
	return ins.Rows.(sqlparser.Values)[rowNum].(sqlparser.ValTuple), pos
}
Beispiel #5
0
// EqualString performs a case-insensitive compare with str.
func (node ColIdent) EqualString(str string) bool {
	return cistring.CIString(node).EqualString(str)
}
Beispiel #6
0
// Equal performs a case-insensitive compare.
func (node ColIdent) Equal(in ColIdent) bool {
	return cistring.CIString(node).Equal(cistring.CIString(in))
}
Beispiel #7
0
// Lowered returns a lower-cased column name.
// This function should generally be used only for optimizing
// comparisons.
func (node ColIdent) Lowered() string {
	return cistring.CIString(node).Lowered()
}
Beispiel #8
0
func (node ColIdent) String() string {
	return cistring.CIString(node).String()
}
Beispiel #9
0
// Original returns the case-preserved column name.
func (node ColIdent) Original() string {
	return cistring.CIString(node).Original()
}