PostgreSQL Source Code: src/backend/utils/adt/arraysubs.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

25#include "utils/fmgrprotos.h"

27

28

29

31{

32

36 bool refelembyval;

38

39

40

41

42

43

47

48

49

50

51

52

53

54

55static void

57 List *indirection,

59 bool isSlice,

60 bool isAssignment)

61{

65

66

67

68

69

70

71

72

73

74 foreach(idx, indirection)

75 {

77 Node *subexpr;

78

79 if (isSlice)

80 {

82 {

84

87 INT4OID, -1,

90 -1);

91 if (subexpr == NULL)

93 (errcode(ERRCODE_DATATYPE_MISMATCH),

94 errmsg("array subscript must have type integer"),

96 }

98 {

99

101 -1,

105 false,

106 true);

107 }

108 else

109 {

110

111 subexpr = NULL;

112 }

113 lowerIndexpr = lappend(lowerIndexpr, subexpr);

114 }

115 else

117

118 if (ai->uidx)

119 {

121

124 INT4OID, -1,

127 -1);

128 if (subexpr == NULL)

130 (errcode(ERRCODE_DATATYPE_MISMATCH),

131 errmsg("array subscript must have type integer"),

133 }

134 else

135 {

136

138 subexpr = NULL;

139 }

140 upperIndexpr = lappend(upperIndexpr, subexpr);

141 }

142

143

146

147

150 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

151 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",

153

154

155

156

157

158

159

160

161 if (isSlice)

162 sbsref->refrestype = sbsref->refcontainertype;

163 else

164 sbsref->refrestype = sbsref->refelemtype;

165}

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180static bool

184{

187

188

190 {

192 {

193

195 {

198 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

199 errmsg("array subscript in assignment must not be null")));

201 return false;

202 }

204 }

205 }

206

207

208 for (int i = 0; i < sbsrefstate->numlower; i++)

209 {

211 {

212

214 {

217 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),

218 errmsg("array subscript in assignment must not be null")));

220 return false;

221 }

223 }

224 }

225

226 return true;

227}

228

229

230

231

232

233

234

235

236static void

240{

243

244

246

255}

256

257

258

259

260

261

262

263

264static void

268{

271

272

274

285

286}

287

288

289

290

291

292

293

294static void

298{

302

303

304

305

306

307

309 {

311 return;

312 }

313

314

315

316

317

318

319

321 {

324 }

325

335

336}

337

338

339

340

341

342

343

344static void

348{

352

353

354

355

356

357

359 {

361 return;

362 }

363

364

365

366

367

368

369

371 {

374 }

375

388

389}

390

391

392

393

394

395

396

397

398

399static void

403{

406

408 {

409

411 sbsrefstate->prevnull = true;

412 }

413 else

422}

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439static void

443{

446

448 {

449

451 sbsrefstate->prevnull = true;

452 }

453 else

454 {

465

466 sbsrefstate->prevnull = false;

467 }

468}

469

470

471

472

473static void

477{

478 bool is_slice = (sbsrefstate->numlower != 0);

480

481

482

483

484

485

488 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

489 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",

491

492

493 if (sbsrefstate->numlower != 0 &&

495 elog(ERROR, "upper and lower index lists are not same length");

496

497

498

499

501 sbsrefstate->workspace = workspace;

502

503

504

505

506 workspace->refelemtype = sbsref->refelemtype;

512

513

514

515

517 if (is_slice)

518 {

522 }

523 else

524 {

528 }

529}

530

531

532

533

534

535

536

537

538

541{

545 .fetch_strict = true,

546 .fetch_leakproof = true,

547 .store_leakproof = false

548 };

549

551}

552

553

554

555

556

557

558

559

560

561

562

563

564

565

568{

572 .fetch_strict = true,

573 .fetch_leakproof = true,

574 .store_leakproof = false

575 };

576

578}

579

580

581

582

583

584

587{

589 Node *ret = NULL;

590

592 {

593

594

595

596

597

598

599

602

603 if (refexpr && IsA(refexpr, Param) &&

607 ret = (Node *) refexpr;

608 }

609

611}

Datum idx(PG_FUNCTION_ARGS)

ArrayType * construct_empty_array(Oid elmtype)

Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)

Datum array_get_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

Datum array_set_slice(Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)

static void array_subscript_assign_slice(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

static void array_subscript_fetch_old(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

static void array_subscript_assign(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

static void array_exec_setup(const SubscriptingRef *sbsref, SubscriptingRefState *sbsrefstate, SubscriptExecSteps *methods)

static void array_subscript_fetch(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

Datum array_subscript_handler_support(PG_FUNCTION_ARGS)

static void array_subscript_fetch_old_slice(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

static void array_subscript_fetch_slice(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

Datum array_subscript_handler(PG_FUNCTION_ARGS)

static void array_subscript_transform(SubscriptingRef *sbsref, List *indirection, ParseState *pstate, bool isSlice, bool isAssignment)

Datum raw_array_subscript_handler(PG_FUNCTION_ARGS)

static bool array_subscript_check_subscripts(ExprState *state, ExprEvalStep *op, ExprContext *econtext)

struct ArraySubWorkspace ArraySubWorkspace

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

#define PG_GETARG_POINTER(n)

#define PG_RETURN_POINTER(x)

Assert(PointerIsAligned(start, uint64))

if(TABLE==NULL||TABLE_index==NULL)

List * lappend(List *list, void *datum)

void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)

int16 get_typlen(Oid typid)

Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)

Oid exprType(const Node *expr)

int exprLocation(const Node *expr)

#define IsA(nodeptr, _type_)

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

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

int parser_errposition(ParseState *pstate, int location)

#define lfirst_node(type, lc)

static int list_length(const List *l)

static Datum PointerGetDatum(const void *X)

static Datum Int32GetDatum(int32 X)

static int32 DatumGetInt32(Datum X)

struct SubscriptingRefState * state

struct ExprEvalStep::@55::@83 sbsref_subscript

struct ExprEvalStep::@55::@84 sbsref

union ExprEvalStep::@55 d

ParseExprKind p_expr_kind

ExecEvalSubroutine sbs_fetch_old

ExecEvalBoolSubroutine sbs_check_subscripts

ExecEvalSubroutine sbs_assign

ExecEvalSubroutine sbs_fetch

SubscriptTransform transform