// Prepare returns the result types of the given statement. Args may be a // partially populated val args map. Prepare will populate the missing val // args. The column result types are returned (or nil if there are no results). func (e *Executor) Prepare(query string, session *Session, args parser.MapArgs) ( []ResultColumn, *roachpb.Error) { stmt, err := parser.ParseOne(query, parser.Syntax(session.Syntax)) if err != nil { return nil, roachpb.NewError(err) } session.planner.resetForBatch(e) session.planner.evalCtx.Args = args session.planner.evalCtx.PrepareOnly = true // TODO(andrei): does the prepare phase really need a Txn? txn := client.NewTxn(*e.ctx.DB) txn.Proto.Isolation = session.DefaultIsolationLevel session.planner.setTxn(txn) defer session.planner.setTxn(nil) plan, pErr := session.planner.prepare(stmt) if pErr != nil { return nil, pErr } if plan == nil { return nil, nil } cols := plan.Columns() for _, c := range cols { if err := checkResultDatum(c.Typ); err != nil { return nil, roachpb.NewError(err) } } return cols, nil }
// Prepare returns the result types of the given statement. pinfo may // contain partial type information for placeholders. Prepare will // populate the missing types. The column result types are returned (or // nil if there are no results). func (e *Executor) Prepare( query string, session *Session, pinfo parser.PlaceholderTypes, ) ([]ResultColumn, error) { if log.V(2) { log.Infof(session.Ctx(), "preparing: %s", query) } else if traceSQL { log.Tracef(session.Ctx(), "preparing: %s", query) } stmt, err := parser.ParseOne(query, parser.Syntax(session.Syntax)) if err != nil { return nil, err } if err = pinfo.ProcessPlaceholderAnnotations(stmt); err != nil { return nil, err } protoTS, err := isAsOf(&session.planner, stmt, e.ctx.Clock.Now()) if err != nil { return nil, err } session.planner.resetForBatch(e) session.planner.semaCtx.Placeholders.SetTypes(pinfo) session.planner.evalCtx.PrepareOnly = true // Prepare needs a transaction because it needs to retrieve db/table // descriptors for type checking. txn := client.NewTxn(session.Ctx(), *e.ctx.DB) txn.Proto.Isolation = session.DefaultIsolationLevel session.planner.setTxn(txn) defer session.planner.setTxn(nil) if protoTS != nil { session.planner.asOf = true defer func() { session.planner.asOf = false }() setTxnTimestamps(txn, *protoTS) } plan, err := session.planner.prepare(stmt) if err != nil { return nil, err } if plan == nil { return nil, nil } cols := plan.Columns() for _, c := range cols { if err := checkResultDatum(c.Typ); err != nil { return nil, err } } return cols, nil }
// Prepare returns the result types of the given statement. Args may be a // partially populated val args map. Prepare will populate the missing val // args. The column result types are returned (or nil if there are no results). func (e *Executor) Prepare(user string, query string, session *Session, args parser.MapArgs) ( []ResultColumn, *roachpb.Error) { stmt, err := parser.ParseOne(query, parser.Syntax(session.Syntax)) if err != nil { return nil, roachpb.NewError(err) } planMaker := plannerPool.Get().(*planner) defer releasePlanner(planMaker) cfg, cache := e.getSystemConfig() *planMaker = planner{ user: user, evalCtx: parser.EvalContext{ NodeID: e.nodeID, ReCache: e.reCache, GetLocation: session.getLocation, Args: args, PrepareOnly: true, }, leaseMgr: e.ctx.LeaseManager, systemConfig: cfg, databaseCache: cache, session: session, execCtx: &e.ctx, } txn := client.NewTxn(*e.ctx.DB) txn.Proto.Isolation = session.DefaultIsolationLevel planMaker.setTxn(txn) plan, pErr := planMaker.prepare(stmt) if pErr != nil { return nil, pErr } if plan == nil { return nil, nil } cols := plan.Columns() for _, c := range cols { if err := checkResultDatum(c.Typ); err != nil { return nil, roachpb.NewError(err) } } return cols, nil }
// Prepare returns the result types of the given statement. Args may be a // partially populated val args map. Prepare will populate the missing val // args. The column result types are returned (or nil if there are no results). func (e *Executor) Prepare(user string, query string, session *Session, args parser.MapArgs) ( []ResultColumn, *roachpb.Error) { stmt, err := parser.ParseOne(query, parser.Syntax(session.Syntax)) if err != nil { return nil, roachpb.NewError(err) } planMaker := plannerPool.Get().(*planner) defer releasePlanner(planMaker) cfg, cache := e.getSystemConfig() *planMaker = planner{ user: user, evalCtx: parser.EvalContext{ NodeID: e.nodeID, ReCache: e.reCache, GetLocation: session.getLocation, Args: args, }, leaseMgr: e.leaseMgr, systemConfig: cfg, databaseCache: cache, session: session, } timestamp := time.Now() txn := e.newTxn(session) planMaker.setTxn(txn, timestamp) planMaker.evalCtx.StmtTimestamp = parser.DTimestamp{Time: timestamp} plan, pErr := planMaker.prepare(stmt) if pErr != nil { return nil, pErr } if plan == nil { return nil, nil } cols := plan.Columns() for _, c := range cols { if err := checkResultDatum(c.Typ); err != nil { return nil, roachpb.NewError(err) } } return cols, nil }
// Prepare returns the result types of the given statement. pinfo may // contain partial type information for placeholders. Prepare will // populate the missing types. The column result types are returned (or // nil if there are no results). func (e *Executor) Prepare( ctx context.Context, query string, session *Session, pinfo parser.PlaceholderTypes, ) ([]ResultColumn, error) { stmt, err := parser.ParseOne(query, parser.Syntax(session.Syntax)) if err != nil { return nil, err } if err = pinfo.ProcessPlaceholderAnnotations(stmt); err != nil { return nil, err } session.planner.resetForBatch(e) session.planner.semaCtx.Placeholders.SetTypes(pinfo) session.planner.evalCtx.PrepareOnly = true // Prepare needs a transaction because it needs to retrieve db/table // descriptors for type checking. txn := client.NewTxn(ctx, *e.ctx.DB) txn.Proto.Isolation = session.DefaultIsolationLevel session.planner.setTxn(txn) defer session.planner.setTxn(nil) plan, err := session.planner.prepare(stmt) if err != nil { return nil, err } if plan == nil { return nil, nil } cols := plan.Columns() for _, c := range cols { if err := checkResultDatum(c.Typ); err != nil { return nil, err } } return cols, nil }