• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang parser.TypeCheck函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Golang中github.com/cockroachdb/cockroach/sql/parser.TypeCheck函数的典型用法代码示例。如果您正苦于以下问题:Golang TypeCheck函数的具体用法?Golang TypeCheck怎么用?Golang TypeCheck使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了TypeCheck函数的17个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。

示例1: parseAndNormalizeExpr

func parseAndNormalizeExpr(t *testing.T, sql string) (parser.TypedExpr, qvalMap) {
	expr, err := parser.ParseExprTraditional(sql)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}

	// Perform qualified name resolution because {analyze,simplify}Expr want
	// expressions containing qvalues.
	desc := testTableDesc()
	sel := testInitDummySelectNode(desc)
	if err = desc.AllocateIDs(); err != nil {
		t.Fatal(err)
	}
	if expr, err = sel.resolveQNames(expr); err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	typedExpr, err := parser.TypeCheck(expr, nil, parser.NoTypePreference)
	if err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	if typedExpr, err = (parser.EvalContext{}).NormalizeExpr(typedExpr); err != nil {
		t.Fatalf("%s: %v", sql, err)
	}
	return typedExpr, sel.qvals
}
开发者ID:GitGoldie,项目名称:cockroach,代码行数:25,代码来源:analyze_test.go


示例2: Set

// Set sets session variables.
// Privileges: None.
//   Notes: postgres/mysql do not require privileges for session variables (some exceptions).
func (p *planner) Set(n *parser.Set) (planNode, error) {
	if n.Name == nil {
		// A client has sent the reserved internal syntax SET ROW ...
		// Reject it.
		return nil, errors.New("invalid statement: SET ROW")
	}

	// By using QualifiedName.String() here any variables that are keywords will
	// be double quoted.
	name := strings.ToUpper(n.Name.String())
	typedValues := make([]parser.TypedExpr, len(n.Values))
	for i, expr := range n.Values {
		typedValue, err := parser.TypeCheck(expr, nil, parser.TypeString)
		if err != nil {
			return nil, err
		}
		typedValues[i] = typedValue
	}
	switch name {
	case `DATABASE`:
		dbName, err := p.getStringVal(name, typedValues)
		if err != nil {
			return nil, err
		}
		if len(dbName) != 0 {
			// Verify database descriptor exists.
			dbDesc, err := p.getDatabaseDesc(dbName)
			if err != nil {
				return nil, err
			}
			if dbDesc == nil {
				return nil, sqlbase.NewUndefinedDatabaseError(dbName)
			}
		}
		p.session.Database = dbName

	case `SYNTAX`:
		s, err := p.getStringVal(name, typedValues)
		if err != nil {
			return nil, err
		}
		switch sqlbase.NormalizeName(s) {
		case sqlbase.NormalizeName(parser.Modern.String()):
			p.session.Syntax = int32(parser.Modern)
		case sqlbase.NormalizeName(parser.Traditional.String()):
			p.session.Syntax = int32(parser.Traditional)
		default:
			return nil, fmt.Errorf("%s: \"%s\" is not in (%q, %q)", name, s, parser.Modern, parser.Traditional)
		}

	case `EXTRA_FLOAT_DIGITS`:
		// These settings are sent by the JDBC driver but we silently ignore them.

	default:
		return nil, fmt.Errorf("unknown variable: %q", name)
	}
	return &emptyNode{}, nil
}
开发者ID:CubeLite,项目名称:cockroach,代码行数:61,代码来源:set.go


示例3: addRender

func (s *selectNode) addRender(target parser.SelectExpr, desiredType parser.Datum) error {
	// outputName will be empty if the target is not aliased.
	outputName := string(target.As)

	if isStar, cols, typedExprs, err := checkRenderStar(target, &s.table, s.qvals); err != nil {
		s.err = err
		return s.err
	} else if isStar {
		s.columns = append(s.columns, cols...)
		s.render = append(s.render, typedExprs...)
		return nil
	}

	// When generating an output column name it should exactly match the original
	// expression, so determine the output column name before we perform any
	// manipulations to the expression.
	outputName = getRenderColName(target)

	// Resolve qualified names. This has the side-effect of normalizing any
	// qualified name found.
	var resolved parser.Expr
	var err error
	if resolved, s.err = s.resolveQNames(target.Expr); s.err != nil {
		return s.err
	}
	if resolved, s.err = s.planner.expandSubqueries(resolved, 1); s.err != nil {
		return s.err
	}

	typedResolved, err := parser.TypeCheck(resolved, s.planner.evalCtx.Args, desiredType)
	if err != nil {
		s.err = err
		return s.err
	}

	normalized, err := s.planner.parser.NormalizeExpr(s.planner.evalCtx, typedResolved)
	if err != nil {
		s.err = err
		return s.err
	}
	s.render = append(s.render, normalized)

	if target.As == "" {
		switch t := target.Expr.(type) {
		case *parser.QualifiedName:
			// If the expression is a qualified name, use the column name, not the
			// full qualification as the column name to return.
			outputName = t.Column()
		}
	}
	s.columns = append(s.columns, ResultColumn{Name: outputName, Typ: normalized.ReturnType()})
	return nil
}
开发者ID:GitGoldie,项目名称:cockroach,代码行数:53,代码来源:select.go


示例4: SanitizeVarFreeExpr

// SanitizeVarFreeExpr verifies a default expression is valid, has the
// correct type and contains no variable expressions.
func SanitizeVarFreeExpr(expr parser.Expr, expectedType parser.Datum, context string) error {
	if parser.ContainsVars(expr) {
		return exprContainsVarsError(context, expr)
	}
	typedExpr, err := parser.TypeCheck(expr, nil, expectedType)
	if err != nil {
		return err
	}
	if defaultType := typedExpr.ReturnType(); !expectedType.TypeEqual(defaultType) {
		return incompatibleExprTypeError(context, expectedType, defaultType)
	}
	return nil
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:15,代码来源:table.go


示例5: SanitizeDefaultExpr

// SanitizeDefaultExpr verifies a default expression is valid and has the
// correct type.
func SanitizeDefaultExpr(expr parser.Expr, colDatumType parser.Datum) error {
	typedExpr, err := parser.TypeCheck(expr, nil, colDatumType)
	if err != nil {
		return err
	}
	if defaultType := typedExpr.ReturnType(); !colDatumType.TypeEqual(defaultType) {
		return incompatibleColumnDefaultTypeError(colDatumType, defaultType)
	}
	if parser.ContainsVars(typedExpr) {
		return defaultContainsPlaceholdersError(typedExpr)
	}
	return nil
}
开发者ID:GitGoldie,项目名称:cockroach,代码行数:15,代码来源:table.go


示例6: SetTimeZone

func (p *planner) SetTimeZone(n *parser.SetTimeZone) (planNode, error) {
	typedValue, err := parser.TypeCheck(n.Value, nil, parser.TypeInt)
	if err != nil {
		return nil, err
	}
	d, err := typedValue.Eval(&p.evalCtx)
	if err != nil {
		return nil, err
	}
	var offset int64
	switch v := d.(type) {
	case *parser.DString:
		location := string(*v)
		if location == "DEFAULT" || location == "LOCAL" {
			location = "UTC"
		}
		loc, err := time.LoadLocation(location)
		if err != nil {
			return nil, fmt.Errorf("cannot find time zone %q: %v", location, err)
		}
		p.session.Location = loc

	case *parser.DInterval:
		offset, _, _, err = v.Duration.Div(time.Second.Nanoseconds()).Encode()
		if err != nil {
			return nil, err
		}

	case *parser.DInt:
		offset = int64(*v) * 60 * 60

	case *parser.DFloat:
		offset = int64(float64(*v) * 60.0 * 60.0)

	case *parser.DDecimal:
		sixty := inf.NewDec(60, 0)
		sixty.Mul(sixty, sixty).Mul(sixty, &v.Dec)
		sixty.Round(sixty, 0, inf.RoundDown)
		var ok bool
		if offset, ok = sixty.Unscaled(); !ok {
			return nil, fmt.Errorf("time zone value %s would overflow an int64", sixty)
		}

	default:
		return nil, fmt.Errorf("bad time zone value: %v", n.Value)
	}
	if offset != 0 {
		p.session.Location = time.FixedZone("", int(offset))
	}
	return &emptyNode{}, nil
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:51,代码来源:set.go


示例7: makeDefaultExprs

func makeDefaultExprs(
	cols []sqlbase.ColumnDescriptor, parse *parser.Parser, evalCtx *parser.EvalContext,
) ([]parser.TypedExpr, error) {
	// Check to see if any of the columns have DEFAULT expressions. If there
	// are no DEFAULT expressions, we don't bother with constructing the
	// defaults map as the defaults are all NULL.
	haveDefaults := false
	for _, col := range cols {
		if col.DefaultExpr != nil {
			haveDefaults = true
			break
		}
	}
	if !haveDefaults {
		return nil, nil
	}

	// Build the default expressions map from the parsed SELECT statement.
	defaultExprs := make([]parser.TypedExpr, 0, len(cols))
	exprStrings := make([]string, 0, len(cols))
	for _, col := range cols {
		if col.DefaultExpr != nil {
			exprStrings = append(exprStrings, *col.DefaultExpr)
		}
	}
	exprs, err := parser.ParseExprsTraditional(exprStrings)
	if err != nil {
		return nil, err
	}

	defExprIdx := 0
	for _, col := range cols {
		if col.DefaultExpr == nil {
			defaultExprs = append(defaultExprs, parser.DNull)
			continue
		}
		expr := exprs[defExprIdx]
		typedExpr, err := parser.TypeCheck(expr, nil, col.Type.ToDatumType())
		if err != nil {
			return nil, err
		}
		if typedExpr, err = parse.NormalizeExpr(evalCtx, typedExpr); err != nil {
			return nil, err
		}
		defaultExprs = append(defaultExprs, typedExpr)
		defExprIdx++
	}
	return defaultExprs, nil
}
开发者ID:yangxuanjia,项目名称:cockroach,代码行数:49,代码来源:insert.go


示例8: analyzeExpr

// analyzeExpr performs semantic analysis of an axpression, including:
// - replacing sub-queries by a sql.subquery node;
// - resolving qnames (optional);
// - type checking (with optional type enforcement);
// - normalization.
// The parameters tables and qvals, if both are non-nil, indicate
// qname resolution should be performed. The qvals map will be filled
// as a result.
func (p *planner) analyzeExpr(
	raw parser.Expr,
	/* arguments for qname resolution */
	tables []*tableInfo,
	qvals qvalMap,
	/* arguments for type checking */
	expectedType parser.Datum,
	requireType bool,
	typingContext string,
) (parser.TypedExpr, error) {
	// Replace the sub-queries.
	// In all contexts that analyze a single expression, a single value
	// is expected. Tell this to replaceSubqueries.  (See UPDATE for a
	// counter-example; cases where a subquery is an operand of a
	// comparison are handled specially in the subqueryVisitor already.)
	replaced, err := p.replaceSubqueries(raw, 1 /* one value expected */)
	if err != nil {
		return nil, err
	}

	// Perform optional qname resolution.
	var resolved parser.Expr
	if tables == nil || qvals == nil {
		resolved = replaced
	} else {
		resolved, err = resolveQNames(replaced, tables, qvals, &p.qnameVisitor)
		if err != nil {
			return nil, err
		}
	}

	// Type check.
	var typedExpr parser.TypedExpr
	if requireType {
		typedExpr, err = parser.TypeCheckAndRequire(resolved, &p.semaCtx,
			expectedType, typingContext)
	} else {
		typedExpr, err = parser.TypeCheck(resolved, &p.semaCtx, expectedType)
	}
	if err != nil {
		return nil, err
	}

	// Normalize.
	return p.parser.NormalizeExpr(&p.evalCtx, typedExpr)
}
开发者ID:mjibson,项目名称:cockroach,代码行数:54,代码来源:analyze.go


示例9: TypeCheck

// TypeCheck ensures that the expressions mentioned in the
// returningHelper have the right type.
// TODO(knz): this both annotates the type of placeholders
// (a task for prepare) and controls that provided values
// for placeholders match their context (a task for exec). This
// ought to be split into two phases.
func (rh *returningHelper) TypeCheck() error {
	for i, expr := range rh.untypedExprs {
		desired := parser.NoTypePreference
		if len(rh.desiredTypes) > i {
			desired = rh.desiredTypes[i]
		}
		typedExpr, err := parser.TypeCheck(expr, rh.p.evalCtx.Args, desired)
		if err != nil {
			return err
		}
		typedExpr, err = rh.p.parser.NormalizeExpr(rh.p.evalCtx, typedExpr)
		if err != nil {
			return err
		}
		rh.exprs[i] = typedExpr
		rh.columns[i].Typ = typedExpr.ReturnType()
	}
	return nil
}
开发者ID:GitGoldie,项目名称:cockroach,代码行数:25,代码来源:returning.go


示例10: processExpression

// processExpression parses the string expression inside an Expression,
// interpreting $0, $1, etc as indexed variables.
func processExpression(exprSpec Expression, h *parser.IndexedVarHelper) (parser.TypedExpr, error) {
	expr, err := parser.ParseExprTraditional(exprSpec.Expr)
	if err != nil {
		return nil, err
	}

	// Convert ValArgs to IndexedVars
	v := valArgsConvert{h: h, err: nil}
	expr, _ = parser.WalkExpr(&v, expr)
	if v.err != nil {
		return nil, v.err
	}

	// Convert to a fully typed expression.
	typedExpr, err := parser.TypeCheck(expr, nil, nil)
	if err != nil {
		return nil, err
	}

	return typedExpr, nil
}
开发者ID:GitGoldie,项目名称:cockroach,代码行数:23,代码来源:dist_sql_expr.go


示例11: TypeCheck

// TypeCheck ensures that the expressions mentioned in the
// returningHelper have the right type.
func (rh *returningHelper) TypeCheck() error {
	for i, expr := range rh.untypedExprs {
		baseExpr, bErr := rh.p.replaceSubqueries(expr, 1)
		if bErr != nil {
			return bErr
		}

		desired := parser.NoTypePreference
		if len(rh.desiredTypes) > i {
			desired = rh.desiredTypes[i]
		}
		typedExpr, err := parser.TypeCheck(baseExpr, &rh.p.semaCtx, desired)
		if err != nil {
			return err
		}
		typedExpr, err = rh.p.parser.NormalizeExpr(rh.p.evalCtx, typedExpr)
		if err != nil {
			return err
		}
		rh.exprs[i] = typedExpr
		rh.columns[i].Typ = typedExpr.ReturnType()
	}
	return nil
}
开发者ID:JKhawaja,项目名称:cockroach,代码行数:26,代码来源:returning.go


示例12: init

func (c *checkHelper) init(p *planner, tableDesc *sqlbase.TableDescriptor) error {
	if len(tableDesc.Checks) == 0 {
		return nil
	}

	c.qvals = make(qvalMap)
	c.cols = tableDesc.Columns
	table := tableInfo{
		columns: makeResultColumns(tableDesc.Columns),
	}

	c.exprs = make([]parser.TypedExpr, len(tableDesc.Checks))
	for i, check := range tableDesc.Checks {
		raw, err := parser.ParseExprTraditional(check.Expr)
		if err != nil {
			return err
		}
		replaced, err := p.replaceSubqueries(raw, 1)
		if err != nil {
			return nil
		}
		resolved, err := resolveQNames(replaced, []*tableInfo{&table}, c.qvals, &p.qnameVisitor)
		if err != nil {
			return err
		}
		typedExpr, err := parser.TypeCheck(resolved, nil, parser.TypeBool)
		if err != nil {
			return err
		}
		if typedExpr, err = p.parser.NormalizeExpr(p.evalCtx, typedExpr); err != nil {
			return err
		}
		c.exprs[i] = typedExpr
	}
	return nil
}
开发者ID:JKhawaja,项目名称:cockroach,代码行数:36,代码来源:check.go


示例13: Insert

// Insert inserts rows into the database.
// Privileges: INSERT on table. Also requires UPDATE on "ON DUPLICATE KEY UPDATE".
//   Notes: postgres requires INSERT. No "on duplicate key update" option.
//          mysql requires INSERT. Also requires UPDATE on "ON DUPLICATE KEY UPDATE".
func (p *planner) Insert(
	n *parser.Insert, desiredTypes []parser.Datum, autoCommit bool,
) (planNode, error) {
	en, err := p.makeEditNode(n.Table, n.Returning, desiredTypes, autoCommit, privilege.INSERT)
	if err != nil {
		return nil, err
	}
	if n.OnConflict != nil {
		if err := p.checkPrivilege(en.tableDesc, privilege.UPDATE); err != nil {
			return nil, err
		}
		// TODO(dan): Support RETURNING in UPSERTs.
		if n.Returning != nil {
			return nil, fmt.Errorf("RETURNING is not supported with UPSERT")
		}
	}

	var cols []sqlbase.ColumnDescriptor
	// Determine which columns we're inserting into.
	if n.DefaultValues() {
		cols = en.tableDesc.Columns
	} else {
		var err error
		if cols, err = p.processColumns(en.tableDesc, n.Columns); err != nil {
			return nil, err
		}
	}
	// Number of columns expecting an input. This doesn't include the
	// columns receiving a default value.
	numInputColumns := len(cols)

	colIDSet := make(map[sqlbase.ColumnID]struct{}, len(cols))
	for _, col := range cols {
		colIDSet[col.ID] = struct{}{}
	}

	// Add the column if it has a DEFAULT expression.
	addIfDefault := func(col sqlbase.ColumnDescriptor) {
		if col.DefaultExpr != nil {
			if _, ok := colIDSet[col.ID]; !ok {
				colIDSet[col.ID] = struct{}{}
				cols = append(cols, col)
			}
		}
	}

	// Add any column that has a DEFAULT expression.
	for _, col := range en.tableDesc.Columns {
		addIfDefault(col)
	}
	// Also add any column in a mutation that is WRITE_ONLY and has
	// a DEFAULT expression.
	for _, m := range en.tableDesc.Mutations {
		if m.State != sqlbase.DescriptorMutation_WRITE_ONLY {
			continue
		}
		if col := m.GetColumn(); col != nil {
			addIfDefault(*col)
		}
	}

	defaultExprs, err := makeDefaultExprs(cols, &p.parser, p.evalCtx)
	if err != nil {
		return nil, err
	}

	// Replace any DEFAULT markers with the corresponding default expressions.
	insertRows, err := p.fillDefaults(defaultExprs, cols, n)
	if err != nil {
		return nil, err
	}

	// Construct the check expressions. The returned slice will be nil if no
	// column in the table has a check expression.
	checkExprs, err := p.makeCheckExprs(cols)
	if err != nil {
		return nil, err
	}

	// Prepare the check expressions.
	var qvals qvalMap
	typedCheckExprs := make([]parser.TypedExpr, 0, len(checkExprs))
	if len(checkExprs) > 0 {
		qvals = make(qvalMap)
		table := tableInfo{
			columns: makeResultColumns(en.tableDesc.Columns),
		}
		for i := range checkExprs {
			expr, err := resolveQNames(checkExprs[i], &table, qvals, &p.qnameVisitor)
			if err != nil {
				return nil, err
			}
			typedExpr, err := parser.TypeCheck(expr, nil, parser.TypeBool)
			if err != nil {
				return nil, err
			}
//.........这里部分代码省略.........
开发者ID:GitGoldie,项目名称:cockroach,代码行数:101,代码来源:insert.go


示例14: Update


//.........这里部分代码省略.........
		// TODO(dan): This could be made tighter, just the rows needed for RETURNING
		// exprs.
		requestedCols = en.tableDesc.Columns
	}

	ru, err := makeRowUpdater(en.tableDesc, updateCols, requestedCols)
	if err != nil {
		return nil, err
	}
	tw := tableUpdater{ru: ru, autoCommit: autoCommit}

	tracing.AnnotateTrace()

	// Generate the list of select targets. We need to select all of the columns
	// plus we select all of the update expressions in case those expressions
	// reference columns (e.g. "UPDATE t SET v = v + 1"). Note that we flatten
	// expressions for tuple assignments just as we flattened the column names
	// above. So "UPDATE t SET (a, b) = (1, 2)" translates into select targets of
	// "*, 1, 2", not "*, (1, 2)".
	targets := sqlbase.ColumnsSelectors(ru.fetchCols)
	i := 0
	// Remember the index where the targets for exprs start.
	exprTargetIdx := len(targets)
	desiredTypesFromSelect := make([]parser.Datum, len(targets), len(targets)+len(exprs))
	for _, expr := range exprs {
		if expr.Tuple {
			switch t := expr.Expr.(type) {
			case (*parser.Tuple):
				for _, e := range t.Exprs {
					typ := updateCols[i].Type.ToDatumType()
					e := fillDefault(e, typ, i, defaultExprs)
					targets = append(targets, parser.SelectExpr{Expr: e})
					desiredTypesFromSelect = append(desiredTypesFromSelect, typ)
					i++
				}
			default:
				return nil, fmt.Errorf("cannot use this expression to assign multiple columns: %s", expr.Expr)
			}
		} else {
			typ := updateCols[i].Type.ToDatumType()
			e := fillDefault(expr.Expr, typ, i, defaultExprs)
			targets = append(targets, parser.SelectExpr{Expr: e})
			desiredTypesFromSelect = append(desiredTypesFromSelect, typ)
			i++
		}
	}

	rows, err := p.SelectClause(&parser.SelectClause{
		Exprs: targets,
		From:  []parser.TableExpr{n.Table},
		Where: n.Where,
	}, nil, nil, desiredTypesFromSelect)
	if err != nil {
		return nil, err
	}

	// ValArgs have their types populated in the above Select if they are part
	// of an expression ("SET a = 2 + $1") in the type check step where those
	// types are inferred. For the simpler case ("SET a = $1"), populate them
	// using checkColumnType. This step also verifies that the expression
	// types match the column types.
	sel := rows.(*selectTopNode).source.(*selectNode)
	for i, target := range sel.render[exprTargetIdx:] {
		// DefaultVal doesn't implement TypeCheck
		if _, ok := target.(parser.DefaultVal); ok {
			continue
		}
		// TODO(nvanbenschoten) isn't this TypeCheck redundant with the call to SelectClause?
		typedTarget, err := parser.TypeCheck(target, &p.semaCtx, updateCols[i].Type.ToDatumType())
		if err != nil {
			return nil, err
		}
		err = sqlbase.CheckColumnType(updateCols[i], typedTarget.ReturnType(), p.semaCtx.Args)
		if err != nil {
			return nil, err
		}
	}

	if err := en.rh.TypeCheck(); err != nil {
		return nil, err
	}

	updateColsIdx := make(map[sqlbase.ColumnID]int, len(ru.updateCols))
	for i, col := range ru.updateCols {
		updateColsIdx[col.ID] = i
	}

	un := &updateNode{
		n:             n,
		editNodeBase:  en,
		updateCols:    ru.updateCols,
		updateColsIdx: updateColsIdx,
		tw:            tw,
	}
	if err := un.checkHelper.init(p, en.tableDesc); err != nil {
		return nil, err
	}
	un.run.initEditNode(rows)
	return un, nil
}
开发者ID:JKhawaja,项目名称:cockroach,代码行数:101,代码来源:update.go


示例15: Insert

// Insert inserts rows into the database.
// Privileges: INSERT on table. Also requires UPDATE on "ON DUPLICATE KEY UPDATE".
//   Notes: postgres requires INSERT. No "on duplicate key update" option.
//          mysql requires INSERT. Also requires UPDATE on "ON DUPLICATE KEY UPDATE".
func (p *planner) Insert(
	n *parser.Insert, desiredTypes []parser.Datum, autoCommit bool,
) (planNode, error) {
	en, err := p.makeEditNode(n.Table, n.Returning, desiredTypes, autoCommit, privilege.INSERT)
	if err != nil {
		return nil, err
	}
	if n.OnConflict != nil {
		if !n.OnConflict.DoNothing {
			if err := p.checkPrivilege(en.tableDesc, privilege.UPDATE); err != nil {
				return nil, err
			}
		}
		// TODO(dan): Support RETURNING in UPSERTs.
		if n.Returning != nil {
			return nil, fmt.Errorf("RETURNING is not supported with UPSERT")
		}
	}

	var cols []sqlbase.ColumnDescriptor
	// Determine which columns we're inserting into.
	if n.DefaultValues() {
		cols = en.tableDesc.Columns
	} else {
		var err error
		if cols, err = p.processColumns(en.tableDesc, n.Columns); err != nil {
			return nil, err
		}
	}
	// Number of columns expecting an input. This doesn't include the
	// columns receiving a default value.
	numInputColumns := len(cols)

	colIDSet := make(map[sqlbase.ColumnID]struct{}, len(cols))
	for _, col := range cols {
		colIDSet[col.ID] = struct{}{}
	}

	// Add the column if it has a DEFAULT expression.
	addIfDefault := func(col sqlbase.ColumnDescriptor) {
		if col.DefaultExpr != nil {
			if _, ok := colIDSet[col.ID]; !ok {
				colIDSet[col.ID] = struct{}{}
				cols = append(cols, col)
			}
		}
	}

	// Add any column that has a DEFAULT expression.
	for _, col := range en.tableDesc.Columns {
		addIfDefault(col)
	}
	// Also add any column in a mutation that is WRITE_ONLY and has
	// a DEFAULT expression.
	for _, m := range en.tableDesc.Mutations {
		if m.State != sqlbase.DescriptorMutation_WRITE_ONLY {
			continue
		}
		if col := m.GetColumn(); col != nil {
			addIfDefault(*col)
		}
	}

	defaultExprs, err := makeDefaultExprs(cols, &p.parser, p.evalCtx)
	if err != nil {
		return nil, err
	}

	// Replace any DEFAULT markers with the corresponding default expressions.
	insertRows, err := p.fillDefaults(defaultExprs, cols, n)
	if err != nil {
		return nil, err
	}

	// Analyze the expressions for column information and typing.
	desiredTypesFromSelect := make([]parser.Datum, len(cols))
	for i, col := range cols {
		desiredTypesFromSelect[i] = col.Type.ToDatumType()
	}
	rows, err := p.newPlan(insertRows, desiredTypesFromSelect, false)
	if err != nil {
		return nil, err
	}

	if expressions := len(rows.Columns()); expressions > numInputColumns {
		return nil, fmt.Errorf("INSERT has more expressions than target columns: %d/%d", expressions, numInputColumns)
	}

	// Type check the tuples, if any, to collect placeholder types.
	if values, ok := n.Rows.Select.(*parser.ValuesClause); ok {
		for _, tuple := range values.Tuples {
			for eIdx, val := range tuple.Exprs {
				if _, ok := val.(parser.DefaultVal); ok {
					continue
				}
				typedExpr, err := parser.TypeCheck(val, &p.semaCtx, desiredTypesFromSelect[eIdx])
//.........这里部分代码省略.........
开发者ID:JKhawaja,项目名称:cockroach,代码行数:101,代码来源:insert.go


示例16: Update


//.........这里部分代码省略.........
	updateCols, err := p.processColumns(en.tableDesc, names)
	if err != nil {
		return nil, err
	}

	defaultExprs, err := makeDefaultExprs(updateCols, &p.parser, p.evalCtx)
	if err != nil {
		return nil, err
	}

	ru, err := makeRowUpdater(en.tableDesc, updateCols)
	if err != nil {
		return nil, err
	}
	// TODO(dan): Use ru.fetchCols to compute the fetch selectors.
	tw := tableUpdater{ru: ru, autoCommit: autoCommit}

	tracing.AnnotateTrace()

	// Generate the list of select targets. We need to select all of the columns
	// plus we select all of the update expressions in case those expressions
	// reference columns (e.g. "UPDATE t SET v = v + 1"). Note that we flatten
	// expressions for tuple assignments just as we flattened the column names
	// above. So "UPDATE t SET (a, b) = (1, 2)" translates into select targets of
	// "*, 1, 2", not "*, (1, 2)".
	// TODO(radu): we only need to select columns necessary to generate primary and
	// secondary indexes keys, and columns needed by returningHelper.
	targets := en.tableDesc.AllColumnsSelector()
	i := 0
	// Remember the index where the targets for exprs start.
	exprTargetIdx := len(targets)
	desiredTypesFromSelect := make([]parser.Datum, len(targets), len(targets)+len(exprs))
	for _, expr := range n.Exprs {
		if expr.Tuple {
			if t, ok := expr.Expr.(*parser.Tuple); ok {
				for _, e := range t.Exprs {
					typ := updateCols[i].Type.ToDatumType()
					e := fillDefault(e, typ, i, defaultExprs)
					targets = append(targets, parser.SelectExpr{Expr: e})
					desiredTypesFromSelect = append(desiredTypesFromSelect, typ)
					i++
				}
			}
		} else {
			typ := updateCols[i].Type.ToDatumType()
			e := fillDefault(expr.Expr, typ, i, defaultExprs)
			targets = append(targets, parser.SelectExpr{Expr: e})
			desiredTypesFromSelect = append(desiredTypesFromSelect, typ)
			i++
		}
	}

	// TODO(knz): Until we split the creation of the node from Start()
	// for the SelectClause too, we cannot cache this. This is because
	// this node's initSelect() method both does type checking and also
	// performs index selection. We cannot perform index selection
	// properly until the placeholder values are known.
	rows, err := p.SelectClause(&parser.SelectClause{
		Exprs: targets,
		From:  []parser.TableExpr{n.Table},
		Where: n.Where,
	}, desiredTypesFromSelect)
	if err != nil {
		return nil, err
	}

	// ValArgs have their types populated in the above Select if they are part
	// of an expression ("SET a = 2 + $1") in the type check step where those
	// types are inferred. For the simpler case ("SET a = $1"), populate them
	// using checkColumnType. This step also verifies that the expression
	// types match the column types.
	for i, target := range rows.(*selectNode).render[exprTargetIdx:] {
		// DefaultVal doesn't implement TypeCheck
		if _, ok := target.(parser.DefaultVal); ok {
			continue
		}
		typedTarget, err := parser.TypeCheck(target, p.evalCtx.Args, updateCols[i].Type.ToDatumType())
		if err != nil {
			return nil, err
		}
		err = sqlbase.CheckColumnType(updateCols[i], typedTarget.ReturnType(), p.evalCtx.Args)
		if err != nil {
			return nil, err
		}
	}

	if err := en.rh.TypeCheck(); err != nil {
		return nil, err
	}

	un := &updateNode{
		n:            n,
		editNodeBase: en,
		desiredTypes: desiredTypesFromSelect,
		defaultExprs: defaultExprs,
		updateCols:   ru.updateCols,
		tw:           tw,
	}
	return un, nil
}
开发者ID:GitGoldie,项目名称:cockroach,代码行数:101,代码来源:update.go


示例17: makeUpsertHelper

func (p *planner) makeUpsertHelper(
	tableDesc *sqlbase.TableDescriptor,
	insertCols []sqlbase.ColumnDescriptor,
	updateCols []sqlbase.ColumnDescriptor,
	updateExprs parser.UpdateExprs,
	upsertConflictIndex *sqlbase.IndexDescriptor,
) (*upsertHelper, error) {
	defaultExprs, err := makeDefaultExprs(updateCols, &p.parser, p.evalCtx)
	if err != nil {
		return nil, err
	}

	untupledExprs := make(parser.Exprs, 0, len(updateExprs))
	i := 0
	for _, updateExpr := range updateExprs {
		if updateExpr.Tuple {
			if t, ok := updateExpr.Expr.(*parser.Tuple); ok {
				for _, e := range t.Exprs {
					typ := updateCols[i].Type.ToDatumType()
					e := fillDefault(e, typ, i, defaultExprs)
					untupledExprs = append(untupledExprs, e)
					i++
				}
			}
		} else {
			typ := updateCols[i].Type.ToDatumType()
			e := fillDefault(updateExpr.Expr, typ, i, defaultExprs)
			untupledExprs = append(untupledExprs, e)
			i++
		}
	}

	allExprsIdentity := true
	for i, expr := range untupledExprs {
		qn, ok := expr.(*parser.QualifiedName)
		if !ok {
			allExprsIdentity = false
			break
		}
		if err := qn.NormalizeColumnName(); err != nil {
			return nil, err
		}
		if qn.Base != upsertExcludedTable || qn.Column() != updateCols[i].Name {
			allExprsIdentity = false
			break
		}
	}

	table := &tableInfo{alias: tableDesc.Name, columns: makeResultColumns(tableDesc.Columns)}
	excludedAliasTable := &tableInfo{
		alias:   upsertExcludedTable,
		columns: makeResultColumns(insertCols),
	}
	tables := []*tableInfo{table, excludedAliasTable}

	var normExprs []parser.TypedExpr
	qvals := make(qvalMap)
	for _, expr := range untupledExprs {
		expandedExpr, err := p.replaceSubqueries(expr, 1)
		if err != nil {
			return nil, err
		}

		resolvedExpr, err := resolveQNames(expandedExpr, tables, qvals, &p.qnameVisitor)
		if err != nil {
			return nil, err
		}

		typedExpr, err := parser.TypeCheck(resolvedExpr, &p.semaCtx, parser.NoTypePreference)
		if err != nil {
			return nil, err
		}

		normExpr, err := p.parser.NormalizeExpr(p.evalCtx, typedExpr)
		if err != nil {
			return nil, err
		}
		normExprs = append(normExprs, normExpr)
	}

	helper := &upsertHelper{
		p:                  p,
		qvals:              qvals,
		evalExprs:          normExprs,
		table:              table,
		excludedAliasTable: excludedAliasTable,
		allExprsIdentity:   allExprsIdentity,
	}
	return helper, nil
}
开发者ID:JKhawaja,项目名称:cockroach,代码行数:90,代码来源:upsert.go



注:本文中的github.com/cockroachdb/cockroach/sql/parser.TypeCheck函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang parser.TypeCheckExpr函数代码示例发布时间:2022-05-23
下一篇:
Golang parser.Syntax函数代码示例发布时间:2022-05-23
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap