Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
// 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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
// 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
}
Пример #9
0
// 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
}