func analyzeSelectExprs(exprs sqlparser.SelectExprs, table *schema.Table) (selects []int, err error) { selects = make([]int, 0, len(exprs)) for _, expr := range exprs { switch expr := expr.(type) { case *sqlparser.StarExpr: // Append all columns. for colIndex := range table.Columns { selects = append(selects, colIndex) } case *sqlparser.NonStarExpr: name := sqlparser.GetColName(expr.Expr) if name == "" { // Not a simple column name. return nil, nil } colIndex := table.FindColumn(name) if colIndex == -1 { return nil, fmt.Errorf("column %s not found in table %s", name, table.Name) } selects = append(selects, colIndex) default: panic("unreachable") } } return selects, nil }
func getInsertPKValues(pkColumnNumbers []int, rowList *Node, tableInfo *schema.Table) (pkValues []interface{}) { pkValues = make([]interface{}, len(pkColumnNumbers)) for index, columnNumber := range pkColumnNumbers { if columnNumber == -1 { pkValues[index] = tableInfo.GetPKColumn(index).Default continue } values := make([]interface{}, rowList.Len()) for j := 0; j < rowList.Len(); j++ { if columnNumber >= rowList.At(j).At(0).Len() { // NODE_LIST->'('->NODE_LIST panic(NewParserError("Column count doesn't match value count")) } node := rowList.At(j).At(0).At(columnNumber) // NODE_LIST->'('->NODE_LIST->Value value := node.execAnalyzeValue() if value == nil { log.Warningf("insert is too complex %v", node) return nil } values[j] = asInterface(value) } if len(values) == 1 { pkValues[index] = values[0] } else { pkValues[index] = values } } return pkValues }
func getInsertPKValues(pkColumnNumbers []int, rowList sqlparser.Values, tableInfo *schema.Table) (pkValues []interface{}, err error) { pkValues = make([]interface{}, len(pkColumnNumbers)) for index, columnNumber := range pkColumnNumbers { if columnNumber == -1 { pkValues[index] = tableInfo.GetPKColumn(index).Default continue } values := make([]interface{}, len(rowList)) for j := 0; j < len(rowList); j++ { if _, ok := rowList[j].(*sqlparser.Subquery); ok { return nil, errors.New("row subquery not supported for inserts") } row := rowList[j].(sqlparser.ValTuple) if columnNumber >= len(row) { return nil, errors.New("column count doesn't match value count") } node := row[columnNumber] if !sqlparser.IsNull(node) && !sqlparser.IsValue(node) { return nil, nil } var err error values[j], err = sqlparser.AsInterface(node) if err != nil { return nil, err } } if len(values) == 1 { pkValues[index] = values[0] } else { pkValues[index] = values } } return pkValues, nil }
// addIndexToTable adds an index named 'indexName' to 'table' with the given 'indexCols'. // It uses 12345 as the cardinality. // It returns the new index. func addIndexToTable(table *schema.Table, indexName string, indexCols ...string) *schema.Index { index := table.AddIndex(indexName) for _, indexCol := range indexCols { index.AddColumn(indexCol, 12345) } return index }
func findSplitColumnsInSchema( splitColumnNames []sqlparser.ColIdent, tableSchema *schema.Table, ) ([]*schema.TableColumn, error) { result := make([]*schema.TableColumn, 0, len(splitColumnNames)) for _, splitColumnName := range splitColumnNames { i := tableSchema.FindColumn(splitColumnName.Original()) if i == -1 { return nil, fmt.Errorf("can't find split column: %v", splitColumnName) } result = append(result, &tableSchema.Columns[i]) } return result, nil }
func (node *Node) execAnalyzeSelectExpressions(table *schema.Table) (selects []int) { selects = make([]int, 0, node.Len()) for i := 0; i < node.Len(); i++ { if name := node.At(i).execAnalyzeSelectExpression(); name != "" { if name == "*" { for colIndex := range table.Columns { selects = append(selects, colIndex) } } else if colIndex := table.FindColumn(name); colIndex != -1 { selects = append(selects, colIndex) } else { panic(NewParserError("Column %s not found in table %s", name, table.Name)) } } else { // Complex expression return nil } } return selects }
func execAnalyzeSelectExprs(exprs SelectExprs, table *schema.Table) (selects []int) { selects = make([]int, 0, len(exprs)) for _, expr := range exprs { if name := execAnalyzeSelectExpr(expr); name != "" { if name == "*" { for colIndex := range table.Columns { selects = append(selects, colIndex) } } else if colIndex := table.FindColumn(name); colIndex != -1 { selects = append(selects, colIndex) } else { panic(NewParserError("column %s not found in table %s", name, table.Name)) } } else { // Complex expression return nil } } return selects }
// getSchema returns a fake schema object that can be given to SplitParams func getTestSchema() map[string]*schema.Table { table := schema.Table{ Name: "test_table", } zero, _ := sqltypes.BuildValue(0) table.AddColumn("id", sqltypes.Int64, zero, "") table.AddColumn("int32_col", sqltypes.Int32, zero, "") table.AddColumn("uint32_col", sqltypes.Uint32, zero, "") table.AddColumn("int64_col", sqltypes.Int64, zero, "") table.AddColumn("uint64_col", sqltypes.Uint64, zero, "") table.AddColumn("float32_col", sqltypes.Float32, zero, "") table.AddColumn("float64_col", sqltypes.Float64, zero, "") table.AddColumn("user_id", sqltypes.Int64, zero, "") table.AddColumn("user_id2", sqltypes.Int64, zero, "") table.AddColumn("id2", sqltypes.Int64, zero, "") table.AddColumn("count", sqltypes.Int64, zero, "") table.PKColumns = []int{0, 7} addIndexToTable(&table, "PRIMARY", "id", "user_id") addIndexToTable(&table, "idx_id2", "id2") addIndexToTable(&table, "idx_int64_col", "int64_col") addIndexToTable(&table, "idx_uint64_col", "uint64_col") addIndexToTable(&table, "idx_float64_col", "float64_col") addIndexToTable(&table, "idx_id_user_id", "id", "user_id") addIndexToTable(&table, "idx_id_user_id_user_id_2", "id", "user_id", "user_id2") table.SetMysqlStats( int64Value(1000), /* TableRows */ int64Value(100), /* DataLength */ int64Value(123), /* IndexLength */ int64Value(456), /* DataFree */ ) result := make(map[string]*schema.Table) result["test_table"] = &table tableNoPK := schema.Table{ Name: "test_table_no_pk", } tableNoPK.AddColumn("id", sqltypes.Int64, zero, "") tableNoPK.PKColumns = []int{} result["test_table_no_pk"] = &tableNoPK return result }
// GetSchema returns a fake schema object that can be given to SplitParams func GetSchema() map[string]*schema.Table { table := schema.Table{ Name: "test_table", } zero, _ := sqltypes.BuildValue(0) table.AddColumn("id", sqltypes.Int64, zero, "") table.AddColumn("int32_col", sqltypes.Int32, zero, "") table.AddColumn("uint32_col", sqltypes.Uint32, zero, "") table.AddColumn("int64_col", sqltypes.Int64, zero, "") table.AddColumn("uint64_col", sqltypes.Uint64, zero, "") table.AddColumn("float32_col", sqltypes.Float32, zero, "") table.AddColumn("float64_col", sqltypes.Float64, zero, "") table.AddColumn("user_id", sqltypes.Int64, zero, "") table.AddColumn("user_id2", sqltypes.Int64, zero, "") table.AddColumn("id2", sqltypes.Int64, zero, "") table.AddColumn("count", sqltypes.Int64, zero, "") table.PKColumns = []int{0, 7} addIndexToTable(&table, "PRIMARY", "id", "user_id") addIndexToTable(&table, "idx_id2", "id2") addIndexToTable(&table, "idx_int64_col", "int64_col") addIndexToTable(&table, "idx_uint64_col", "uint64_col") addIndexToTable(&table, "idx_float64_col", "float64_col") addIndexToTable(&table, "idx_id_user_id", "id", "user_id") addIndexToTable(&table, "idx_id_user_id_user_id_2", "id", "user_id", "user_id2") result := make(map[string]*schema.Table) result["test_table"] = &table tableNoPK := schema.Table{ Name: "test_table_no_pk", } tableNoPK.AddColumn("id", sqltypes.Int64, zero, "") tableNoPK.PKColumns = []int{} result["test_table_no_pk"] = &tableNoPK return result }