PostgreSQL Source Code: src/backend/executor/execCurrent.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

14

24

25

28 bool *pending_rescan);

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43bool

46 Oid table_oid,

48{

49 char *cursor_name;

50 char *table_name;

53

54

57 else

59

60

62 if (table_name == NULL)

63 elog(ERROR, "cache lookup failed for relation %u", table_oid);

64

65

69 (errcode(ERRCODE_UNDEFINED_CURSOR),

70 errmsg("cursor \"%s\" does not exist", cursor_name)));

71

72

73

74

75

78 (errcode(ERRCODE_INVALID_CURSOR_STATE),

79 errmsg("cursor \"%s\" is not a SELECT query",

80 cursor_name)));

82 if (queryDesc == NULL || queryDesc->estate == NULL)

84 (errcode(ERRCODE_INVALID_CURSOR_STATE),

85 errmsg("cursor \"%s\" is held from a previous transaction",

86 cursor_name)));

87

88

89

90

91

92

93

94

96 {

99

100

101

102

103

104 erm = NULL;

106 {

108

109 if (thiserm == NULL ||

111 continue;

112

113 if (thiserm->relid == table_oid)

114 {

115 if (erm)

117 (errcode(ERRCODE_INVALID_CURSOR_STATE),

118 errmsg("cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"",

119 cursor_name, table_name)));

120 erm = thiserm;

121 }

122 }

123

124 if (erm == NULL)

126 (errcode(ERRCODE_INVALID_CURSOR_STATE),

127 errmsg("cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"",

128 cursor_name, table_name)));

129

130

131

132

133

136 (errcode(ERRCODE_INVALID_CURSOR_STATE),

137 errmsg("cursor \"%s\" is not positioned on a row",

138 cursor_name)));

139

140

142 {

143 *current_tid = erm->curCtid;

144 return true;

145 }

146

147

148

149

150

151

152 return false;

153 }

154 else

155 {

156

157

158

159

160

162 bool pending_rescan = false;

163

165 &pending_rescan);

166 if (!scanstate)

168 (errcode(ERRCODE_INVALID_CURSOR_STATE),

169 errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",

170 cursor_name, table_name)));

171

172

173

174

175

176

177

178

181 (errcode(ERRCODE_INVALID_CURSOR_STATE),

182 errmsg("cursor \"%s\" is not positioned on a row",

183 cursor_name)));

184

185

186

187

188

189

191 return false;

192

193

194

195

196

197

199 {

200

201

202

203

204

206

208 }

209 else

210 {

211

212

213

214

215

216

218 bool lisnull;

220

221#ifdef USE_ASSERT_CHECKING

224 &lisnull);

225 if (lisnull)

227 (errcode(ERRCODE_INVALID_CURSOR_STATE),

228 errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",

229 cursor_name, table_name)));

231#endif

232

235 &lisnull);

236 if (lisnull)

238 (errcode(ERRCODE_INVALID_CURSOR_STATE),

239 errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"",

240 cursor_name, table_name)));

242

243 *current_tid = *tuple_tid;

244 }

245

247

248 return true;

249 }

250}

251

252

253

254

255

256

257static char *

259{

261

262 if (paramInfo &&

263 paramId > 0 && paramId <= paramInfo->numParams)

264 {

267

268

270 prm = paramInfo->paramFetch(paramInfo, paramId, false, &prmdata);

271 else

272 prm = &paramInfo->params[paramId - 1];

273

275 {

276

277 if (prm->ptype != REFCURSOROID)

279 (errcode(ERRCODE_DATATYPE_MISMATCH),

280 errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",

281 paramId,

284

285

287 }

288 }

289

291 (errcode(ERRCODE_UNDEFINED_OBJECT),

292 errmsg("no value found for parameter %d", paramId)));

293 return NULL;

294}

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

315 bool *pending_rescan)

316{

318

319 if (node == NULL)

320 return NULL;

322 {

323

324

325

326

327

328

329

330

331

332

333 case T_SeqScanState:

334 case T_SampleScanState:

335 case T_IndexScanState:

336 case T_IndexOnlyScanState:

337 case T_BitmapHeapScanState:

338 case T_TidScanState:

339 case T_TidRangeScanState:

340 case T_ForeignScanState:

341 case T_CustomScanState:

342 {

344

347 result = sstate;

348 break;

349 }

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373 case T_AppendState:

374 {

376 int i;

377

379 {

381 table_oid,

382 pending_rescan);

383

384 if (!elem)

385 continue;

386 if (result)

387 return NULL;

388 result = elem;

389 }

390 break;

391 }

392

393

394

395

396

397 case T_ResultState:

398 case T_LimitState:

400 table_oid,

401 pending_rescan);

402 break;

403

404

405

406

407 case T_SubqueryScanState:

409 table_oid,

410 pending_rescan);

411 break;

412

413 default:

414

415 break;

416 }

417

418

419

420

421

422 if (result && node->chgParam != NULL)

423 *pending_rescan = true;

424

425 return result;

426}

#define TextDatumGetCString(d)

#define OidIsValid(objectId)

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

static ScanState * search_plan_tree(PlanState *node, Oid table_oid, bool *pending_rescan)

static char * fetch_cursor_param_value(ExprContext *econtext, int paramId)

bool execCurrentOf(CurrentOfExpr *cexpr, ExprContext *econtext, Oid table_oid, ItemPointer current_tid)

#define outerPlanState(node)

char * format_type_be(Oid type_oid)

Assert(PointerIsAligned(start, uint64))

ItemPointerData * ItemPointer

static bool ItemPointerIsValid(const ItemPointerData *pointer)

char * get_rel_name(Oid relid)

#define IsA(nodeptr, _type_)

#define RowMarkRequiresRowShareLock(marktype)

Portal GetPortalByName(const char *name)

static Oid DatumGetObjectId(Datum X)

static Pointer DatumGetPointer(Datum X)

#define RelationGetRelid(relation)

struct ExecRowMark ** es_rowmarks

Index es_range_table_size

ParamListInfo ecxt_param_list_info

ItemPointerData xs_heaptid

ParamExternData params[FLEXIBLE_ARRAY_MEMBER]

ParamFetchHook paramFetch

Relation ss_currentRelation

TupleTableSlot * ss_ScanTupleSlot

#define TableOidAttributeNumber

#define SelfItemPointerAttributeNumber

static Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)