PostgreSQL Source Code: src/backend/commands/prepare.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

18

19#include <limits.h>

20

39

40

41

42

43

44

45

46

48

54

55

56

57

58void

60 int stmt_location, int stmt_len)

61{

64 Oid *argtypes = NULL;

65 int nargs;

66 List *query_list;

67

68

69

70

71

72 if (stmt->name || stmt->name[0] == '\0')

74 (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),

75 errmsg("invalid statement name: must not be empty")));

76

77

78

79

80

85

86

87

88

89

92

93

95

96 if (nargs)

97 {

98 int i;

100

102 i = 0;

103

104 foreach(l, stmt->argtypes)

105 {

108

109 argtypes[i++] = toid;

110 }

111 }

112

113

114

115

116

117

118

120 &argtypes, &nargs, NULL);

121

122

124 query_list,

125 NULL,

126 argtypes,

127 nargs,

128 NULL,

129 NULL,

131 true);

132

133

134

135

137 plansource,

138 true);

139}

140

141

142

143

144

145

146

147

148

149void

154{

157 List *plan_list;

159 EState *estate = NULL;

161 char *query_string;

162 int eflags;

163 long count;

164

165

167

168

170 elog(ERROR, "EXECUTE does not support variable-result cached plans");

171

172

174 {

175

176

177

178

179

180

184 }

185

186

188

190

191

194

195

198

199

200

201

202

204 NULL,

205 query_string,

207 plan_list,

208 cplan,

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224 if (intoClause)

225 {

227

230 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

231 errmsg("prepared statement is not a SELECT")));

235 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

236 errmsg("prepared statement is not a SELECT")));

237

238

240

241

243 count = 0;

244 else

246 }

247 else

248 {

249

250 eflags = 0;

252 }

253

254

255

256

258

260

262

263 if (estate)

265

266

267}

268

269

270

271

272

273

274

275

276

277

278

279

280

284{

289 List *exprstates;

291 int i;

292

293 if (nparams != num_params)

295 (errcode(ERRCODE_SYNTAX_ERROR),

296 errmsg("wrong number of parameters for prepared statement \"%s\"",

298 errdetail("Expected %d parameters but got %d.",

299 num_params, nparams)));

300

301

302 if (num_params == 0)

303 return NULL;

304

305

306

307

308

310

311 i = 0;

312 foreach(l, params)

313 {

315 Oid expected_type_id = param_types[i];

316 Oid given_type_id;

317

319

320 given_type_id = exprType(expr);

321

323 expected_type_id, -1,

326 -1);

327

328 if (expr == NULL)

330 (errcode(ERRCODE_DATATYPE_MISMATCH),

331 errmsg("parameter $%d of type %s cannot be coerced to the expected type %s",

332 i + 1,

335 errhint("You will need to rewrite or cast the expression."),

337

338

340

342 i++;

343 }

344

345

347

349

350 i = 0;

351 foreach(l, exprstates)

352 {

355

356 prm->ptype = param_types[i];

361

362 i++;

363 }

364

365 return paramLI;

366}

367

368

369

370

371

372static void

374{

376

379

381 32,

382 &hash_ctl,

384}

385

386

387

388

389

390

391

392void

395 bool from_sql)

396{

399 bool found;

400

401

404

405

407 stmt_name,

409 &found);

410

411

412 if (found)

414 (errcode(ERRCODE_DUPLICATE_PSTATEMENT),

415 errmsg("prepared statement \"%s\" already exists",

416 stmt_name)));

417

418

422

423

425}

426

427

428

429

430

431

432

433

436{

438

439

440

441

442

445 stmt_name,

447 NULL);

448 else

449 entry = NULL;

450

451 if (!entry && throwError)

453 (errcode(ERRCODE_UNDEFINED_PSTATEMENT),

454 errmsg("prepared statement \"%s\" does not exist",

455 stmt_name)));

456

457 return entry;

458}

459

460

461

462

463

464

465

468{

469

470

471

472

473 Assert(stmt->plansource->fixed_result);

474 if (stmt->plansource->resultDesc)

476 else

477 return NULL;

478}

479

480

481

482

483

484

485

486

487

488

491{

493

494

496

497

499}

500

501

502

503

504

505void

507{

508 if (stmt->name)

510 else

512}

513

514

515

516

517

518

519void

521{

523

524

526

527 if (entry)

528 {

529

531

532

534 }

535}

536

537

538

539

540void

542{

545

546

548 return;

549

550

553 {

554

556

557

559 }

560}

561

562

563

564

565

566

567

568

569

570

571void

574{

576 const char *query_string;

578 List *plan_list;

581 EState *estate = NULL;

585 bufusage;

589 int query_index = 0;

590

592 {

593

596 "explain analyze planner context",

599 }

600

604

605

607

608

610 elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans");

611

613

614

616 {

618

621

622

623

624

625

626

627

630

632 }

633

634

637

640

642 {

645 }

646

647

649 {

650 memset(&bufusage, 0, sizeof(BufferUsage));

652 }

653

655

656

657 foreach(p, plan_list)

658 {

660

663 into, es, query_string, paramLI, pstate->p_queryEnv,

664 &planduration, (es->buffers ? &bufusage : NULL),

665 es->memory ? &mem_counters : NULL);

666 else

668

669

670

671

672 if (lnext(plan_list, p) != NULL)

674

675 query_index++;

676 }

677

678 if (estate)

680

682}

683

684

685

686

687

688

691{

693

694

695

696

697

699

700

702 {

705

708 {

711 bool nulls[8] = {0};

712

714

720 if (result_desc)

721 {

722 Oid *result_types;

723

725 for (int i = 0; i < result_desc->natts; i++)

726 result_types[i] = TupleDescAttr(result_desc, i)->atttypid;

728 }

729 else

730 {

731

732 nulls[4] = true;

733 }

737

740 }

741 }

742

743 return (Datum) 0;

744}

745

746

747

748

749

750

753{

756 int i;

757

759

760 for (i = 0; i < num_params; i++)

762

765}

ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)

static HTAB * prepared_queries

void DropPreparedStatement(const char *stmt_name, bool showError)

void PrepareQuery(ParseState *pstate, PrepareStmt *stmt, int stmt_location, int stmt_len)

static void InitQueryHashTable(void)

TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt)

Datum pg_prepared_statement(PG_FUNCTION_ARGS)

PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)

void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, ParseState *pstate, ParamListInfo params)

static ParamListInfo EvaluateParams(ParseState *pstate, PreparedStatement *pstmt, List *params, EState *estate)

void StorePreparedStatement(const char *stmt_name, CachedPlanSource *plansource, bool from_sql)

static Datum build_regtype_array(Oid *param_types, int num_params)

void ExecuteQuery(ParseState *pstate, ExecuteStmt *stmt, IntoClause *intoClause, ParamListInfo params, DestReceiver *dest, QueryCompletion *qc)

void DropAllPreparedStatements(void)

List * FetchPreparedStatementTargetList(PreparedStatement *stmt)

void DeallocateQuery(DeallocateStmt *stmt)

static Datum values[MAXATTR]

#define CStringGetTextDatum(s)

int GetIntoRelEFlags(IntoClause *intoClause)

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

void * hash_seq_search(HASH_SEQ_STATUS *status)

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

List * ExecPrepareExprList(List *nodes, EState *estate)

void FreeExecutorState(EState *estate)

EState * CreateExecutorState(void)

#define GetPerTupleExprContext(estate)

static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)

void ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan, CachedPlanSource *plansource, int query_index, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params, QueryEnvironment *queryEnv, const instr_time *planduration, const BufferUsage *bufusage, const MemoryContextCounters *mem_counters)

void ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, ParseState *pstate, ParamListInfo params)

void ExplainSeparatePlans(ExplainState *es)

#define palloc_array(type, count)

char * format_type_be(Oid type_oid)

void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)

Assert(PointerIsAligned(start, uint64))

#define INSTR_TIME_SET_CURRENT(t)

#define INSTR_TIME_SUBTRACT(x, y)

BufferUsage pgBufferUsage

void BufferUsageAccumDiff(BufferUsage *dst, const BufferUsage *add, const BufferUsage *sub)

char * MemoryContextStrdup(MemoryContext context, const char *string)

void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed)

MemoryContext CurrentMemoryContext

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

Oid exprType(const Node *expr)

int exprLocation(const Node *expr)

#define IsA(nodeptr, _type_)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

ParamListInfo makeParamList(int numParams)

Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)

void assign_expr_collations(ParseState *pstate, Node *expr)

Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)

int parser_errposition(ParseState *pstate, int location)

ParseState * make_parsestate(ParseState *parentParseState)

@ EXPR_KIND_EXECUTE_PARAMETER

Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)

#define CURSOR_OPT_PARALLEL_OK

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

static ListCell * lnext(const List *l, const ListCell *c)

void DropCachedPlan(CachedPlanSource *plansource)

void SaveCachedPlan(CachedPlanSource *plansource)

void CompleteCachedPlan(CachedPlanSource *plansource, List *querytree_list, MemoryContext querytree_context, Oid *param_types, int num_params, ParserSetupHook parserSetup, void *parserSetupArg, int cursor_options, bool fixed_result)

CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)

CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)

List * CachedPlanGetTargetList(CachedPlanSource *plansource, QueryEnvironment *queryEnv)

void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)

void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan, CachedPlanSource *plansource)

Portal CreateNewPortal(void)

void PortalDrop(Portal portal, bool isTopCommit)

List * pg_analyze_and_rewrite_varparams(RawStmt *parsetree, const char *query_string, Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv)

#define Int64GetDatumFast(X)

static Datum PointerGetDatum(const void *X)

static Datum BoolGetDatum(bool X)

static Datum ObjectIdGetDatum(Oid X)

void PortalStart(Portal portal, ParamListInfo params, int eflags, Snapshot snapshot)

bool PortalRun(Portal portal, long count, bool isTopLevel, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)

ResourceOwner CurrentResourceOwner

Snapshot GetActiveSnapshot(void)

const char * query_string

ParamListInfo es_param_list_info

ParamExternData params[FLEXIBLE_ARRAY_MEMBER]

QueryEnvironment * p_queryEnv

const char * p_sourcetext

MemoryContext portalContext

char stmt_name[NAMEDATALEN]

CachedPlanSource * plansource

Tuplestorestate * setResult

TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)

CommandTag CreateCommandTag(Node *parsetree)

static Datum TimestampTzGetDatum(TimestampTz X)

TimestampTz GetCurrentStatementStartTimestamp(void)