PostgreSQL Source Code: src/backend/storage/large_object/inv_api.c File Reference (original) (raw)

Go to the source code of this file.

Functions
static void open_lo_relation (void)
void close_lo_relation (bool isCommit)
static void getdatafield (Form_pg_largeobject tuple, bytea **pdatafield, int *plen, bool *pfreeit)
Oid inv_create (Oid lobjId)
LargeObjectDesc * inv_open (Oid lobjId, int flags, MemoryContext mcxt)
void inv_close (LargeObjectDesc *obj_desc)
int inv_drop (Oid lobjId)
static uint64 inv_getsize (LargeObjectDesc *obj_desc)
int64 inv_seek (LargeObjectDesc *obj_desc, int64 offset, int whence)
int64 inv_tell (LargeObjectDesc *obj_desc)
int inv_read (LargeObjectDesc *obj_desc, char *buf, int nbytes)
int inv_write (LargeObjectDesc *obj_desc, const char *buf, int nbytes)
void inv_truncate (LargeObjectDesc *obj_desc, int64 len)
Variables
bool lo_compat_privileges
static Relation lo_heap_r = NULL
static Relation lo_index_r = NULL

close_lo_relation()

void close_lo_relation ( bool isCommit )

getdatafield()

Definition at line 131 of file inv_api.c.

135{

136 bytea *datafield;

138 bool freeit;

139

140 datafield = &(tuple->data);

141 freeit = false;

143 {

144 datafield = (bytea *)

146 freeit = true;

147 }

152 errmsg("pg_largeobject entry for OID %u, page %d has invalid data field size %d",

153 tuple->loid, tuple->pageno, len)));

154 *pdatafield = datafield;

155 *plen = len;

156 *pfreeit = freeit;

157}

struct varlena * detoast_attr(struct varlena *attr)

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

#define ERRCODE_DATA_CORRUPTED

#define VARATT_IS_EXTENDED(PTR)

References detoast_attr(), ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, len, LOBLKSIZE, VARATT_IS_EXTENDED, VARHDRSZ, and VARSIZE.

Referenced by inv_getsize(), inv_read(), inv_truncate(), and inv_write().

inv_close()

inv_create()

Definition at line 173 of file inv_api.c.

174{

175 Oid lobjId_new;

176

177

178

179

181

182

183

184

185

186

187

188

189

192

193

195

196

197

198

200

201 return lobjId_new;

202}

#define InvokeObjectPostCreateHook(classId, objectId, subId)

Oid LargeObjectCreate(Oid loid)

void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)

void CommandCounterIncrement(void)

References CommandCounterIncrement(), GetUserId(), InvokeObjectPostCreateHook, LargeObjectCreate(), and recordDependencyOnOwner().

Referenced by be_lo_creat(), be_lo_create(), be_lo_from_bytea(), and lo_import_internal().

inv_drop()

int inv_drop ( Oid lobjId )

inv_getsize()

Definition at line 340 of file inv_api.c.

341{

346

348

350

352 Anum_pg_largeobject_loid,

355

357 obj_desc->snapshot, 1, skey);

358

359

360

361

362

363

364

367 {

369 bytea *datafield;

371 bool pfreeit;

372

374 elog(ERROR, "null field found in pg_largeobject");

378 if (pfreeit)

379 pfree(datafield);

380 }

381

383

384 return lastbyte;

385}

SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)

void systable_endscan_ordered(SysScanDesc sysscan)

HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)

#define HeapTupleIsValid(tuple)

static bool HeapTupleHasNulls(const HeapTupleData *tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

static void getdatafield(Form_pg_largeobject tuple, bytea **pdatafield, int *plen, bool *pfreeit)

static void open_lo_relation(void)

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

FormData_pg_largeobject * Form_pg_largeobject

static Datum ObjectIdGetDatum(Oid X)

void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)

#define BTEqualStrategyNumber

References Assert(), BackwardScanDirection, BTEqualStrategyNumber, data, elog, ERROR, getdatafield(), GETSTRUCT(), HeapTupleHasNulls(), HeapTupleIsValid, LargeObjectDesc::id, if(), len, lo_heap_r, lo_index_r, LOBLKSIZE, ObjectIdGetDatum(), open_lo_relation(), pfree(), PointerIsValid, ScanKeyInit(), LargeObjectDesc::snapshot, systable_beginscan_ordered(), systable_endscan_ordered(), and systable_getnext_ordered().

Referenced by inv_seek().

inv_open()

Definition at line 215 of file inv_api.c.

216{

219 int descflags = 0;

220

221

222

223

224

225

230

231 if (descflags == 0)

233 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

234 errmsg("invalid flags for opening a large object: %d",

235 flags)));

236

237

239 snapshot = NULL;

240 else

242

243

246 (errcode(ERRCODE_UNDEFINED_OBJECT),

247 errmsg("large object %u does not exist", lobjId)));

248

249

251 {

258 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

259 errmsg("permission denied for large object %u",

260 lobjId)));

261 }

263 {

270 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

271 errmsg("permission denied for large object %u",

272 lobjId)));

273 }

274

275

278 retval->id = lobjId;

280 retval->flags = descflags;

281

282

284

285

286

287

288

290

291 return retval;

292}

AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)

#define InvalidSubTransactionId

bool lo_compat_privileges

void * MemoryContextAlloc(MemoryContext context, Size size)

bool LargeObjectExistsWithSnapshot(Oid loid, Snapshot snapshot)

Snapshot GetActiveSnapshot(void)

References ACL_SELECT, ACL_UPDATE, ACLCHECK_OK, ereport, errcode(), errmsg(), ERROR, LargeObjectDesc::flags, GetActiveSnapshot(), GetUserId(), LargeObjectDesc::id, IFS_RDLOCK, IFS_WRLOCK, INV_READ, INV_WRITE, InvalidSubTransactionId, LargeObjectExistsWithSnapshot(), lo_compat_privileges, MemoryContextAlloc(), LargeObjectDesc::offset, pg_largeobject_aclcheck_snapshot(), LargeObjectDesc::snapshot, and LargeObjectDesc::subid.

Referenced by be_lo_export(), be_lo_from_bytea(), be_lo_open(), be_lo_put(), lo_get_fragment_internal(), and lo_import_internal().

inv_read()

Definition at line 450 of file inv_api.c.

451{

452 int nread = 0;

461

464

467 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

468 errmsg("permission denied for large object %u",

469 obj_desc->id)));

470

471 if (nbytes <= 0)

472 return 0;

473

475

477 Anum_pg_largeobject_loid,

480

482 Anum_pg_largeobject_pageno,

485

487 obj_desc->snapshot, 2, skey);

488

490 {

492 bytea *datafield;

493 bool pfreeit;

494

496 elog(ERROR, "null field found in pg_largeobject");

498

499

500

501

502

503

505 if (pageoff > obj_desc->offset)

506 {

507 n = pageoff - obj_desc->offset;

508 n = (n <= (nbytes - nread)) ? n : (nbytes - nread);

510 nread += n;

511 obj_desc->offset += n;

512 }

513

514 if (nread < nbytes)

515 {

517 off = (int) (obj_desc->offset - pageoff);

519

521 if (len > off)

522 {

523 n = len - off;

524 n = (n <= (nbytes - nread)) ? n : (nbytes - nread);

525 memcpy(buf + nread, VARDATA(datafield) + off, n);

526 nread += n;

527 obj_desc->offset += n;

528 }

529 if (pfreeit)

530 pfree(datafield);

531 }

532

533 if (nread >= nbytes)

534 break;

535 }

536

538

539 return nread;

540}

#define MemSet(start, val, len)

static Datum Int32GetDatum(int32 X)

#define BTGreaterEqualStrategyNumber

References Assert(), BTEqualStrategyNumber, BTGreaterEqualStrategyNumber, buf, data, elog, ereport, errcode(), errmsg(), ERROR, LargeObjectDesc::flags, ForwardScanDirection, getdatafield(), GETSTRUCT(), HeapTupleHasNulls(), LargeObjectDesc::id, IFS_RDLOCK, Int32GetDatum(), len, lo_heap_r, lo_index_r, LOBLKSIZE, MemSet, ObjectIdGetDatum(), LargeObjectDesc::offset, open_lo_relation(), pfree(), PointerIsValid, ScanKeyInit(), LargeObjectDesc::snapshot, systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), and VARDATA.

Referenced by be_lo_export(), lo_get_fragment_internal(), and lo_read().

inv_seek()

Definition at line 388 of file inv_api.c.

389{

391

393

394

395

396

397

398

399

400

401

402

403 switch (whence)

404 {

405 case SEEK_SET:

406 newoffset = offset;

407 break;

408 case SEEK_CUR:

409 newoffset = obj_desc->offset + offset;

410 break;

411 case SEEK_END:

412 newoffset = inv_getsize(obj_desc) + offset;

413 break;

414 default:

416 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

417 errmsg("invalid whence setting: %d", whence)));

418 newoffset = 0;

419 break;

420 }

421

422

423

424

425

428 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

430 newoffset)));

431

432 obj_desc->offset = newoffset;

433 return newoffset;

434}

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

static uint64 inv_getsize(LargeObjectDesc *obj_desc)

#define MAX_LARGE_OBJECT_SIZE

References Assert(), ereport, errcode(), errmsg(), errmsg_internal(), ERROR, INT64_FORMAT, inv_getsize(), MAX_LARGE_OBJECT_SIZE, LargeObjectDesc::offset, and PointerIsValid.

Referenced by be_lo_lseek(), be_lo_lseek64(), be_lo_put(), and lo_get_fragment_internal().

inv_tell()

inv_truncate()

Definition at line 740 of file inv_api.c.

741{

748 union

749 {

751

753

755 } workbuf;

756 char *workb = VARDATA(&workbuf.hdr);

759 bool nulls[Natts_pg_largeobject];

760 bool replace[Natts_pg_largeobject];

762

764

765

768 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

769 errmsg("permission denied for large object %u",

770 obj_desc->id)));

771

772

773

774

775

778 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

781

783

785

786

787

788

790 Anum_pg_largeobject_loid,

793

795 Anum_pg_largeobject_pageno,

798

800 obj_desc->snapshot, 2, skey);

801

802

803

804

805

806 olddata = NULL;

808 {

810 elog(ERROR, "null field found in pg_largeobject");

812 Assert(olddata->pageno >= pageno);

813 }

814

815

816

817

818

819

820 if (olddata != NULL && olddata->pageno == pageno)

821 {

822

823 bytea *datafield;

824 int pagelen;

825 bool pfreeit;

826

827 getdatafield(olddata, &datafield, &pagelen, &pfreeit);

828 memcpy(workb, VARDATA(datafield), pagelen);

829 if (pfreeit)

830 pfree(datafield);

831

832

833

834

836 if (off > pagelen)

837 MemSet(workb + pagelen, 0, off - pagelen);

838

839

841

842

843

844

846 memset(nulls, false, sizeof(nulls));

847 memset(replace, false, sizeof(replace));

849 replace[Anum_pg_largeobject_data - 1] = true;

851 values, nulls, replace);

853 indstate);

855 }

856 else

857 {

858

859

860

861

862

863 if (olddata != NULL)

864 {

865 Assert(olddata->pageno > pageno);

867 }

868

869

870

871

872

873

875 if (off > 0)

876 MemSet(workb, 0, off);

877

878

880

881

882

883

885 memset(nulls, false, sizeof(nulls));

892 }

893

894

895

896

897

898 if (olddata != NULL)

899 {

901 {

903 }

904 }

905

907

909

910

911

912

913

915}

static Datum values[MAXATTR]

HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)

HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

void heap_freetuple(HeapTuple htup)

void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)

void CatalogCloseIndexes(CatalogIndexState indstate)

CatalogIndexState CatalogOpenIndexes(Relation heapRel)

void CatalogTupleDelete(Relation heapRel, ItemPointer tid)

void CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup, CatalogIndexState indstate)

static Datum PointerGetDatum(const void *X)

#define RelationGetDescr(relation)

#define SET_VARSIZE(PTR, len)

References Assert(), BTEqualStrategyNumber, BTGreaterEqualStrategyNumber, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTupleDelete(), CatalogTupleInsertWithInfo(), CatalogTupleUpdateWithInfo(), CommandCounterIncrement(), data, elog, ereport, errcode(), errmsg(), errmsg_internal(), ERROR, LargeObjectDesc::flags, ForwardScanDirection, getdatafield(), GETSTRUCT(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleHasNulls(), LargeObjectDesc::id, IFS_WRLOCK, Int32GetDatum(), INT64_FORMAT, len, lo_heap_r, lo_index_r, LOBLKSIZE, MAX_LARGE_OBJECT_SIZE, MemSet, ObjectIdGetDatum(), open_lo_relation(), pfree(), PointerGetDatum(), PointerIsValid, RelationData::rd_att, RelationGetDescr, ScanKeyInit(), SET_VARSIZE, LargeObjectDesc::snapshot, systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), HeapTupleData::t_self, values, VARDATA, and VARHDRSZ.

Referenced by lo_truncate_internal().

inv_write()

Definition at line 543 of file inv_api.c.

544{

545 int nwritten = 0;

546 int n;

547 int off;

554 bool neednextpage;

555 bytea *datafield;

556 bool pfreeit;

557 union

558 {

560

562

564 } workbuf;

565 char *workb = VARDATA(&workbuf.hdr);

568 bool nulls[Natts_pg_largeobject];

569 bool replace[Natts_pg_largeobject];

571

574

575

578 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

579 errmsg("permission denied for large object %u",

580 obj_desc->id)));

581

582 if (nbytes <= 0)

583 return 0;

584

585

588 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

589 errmsg("invalid large object write request size: %d",

590 nbytes)));

591

593

595

597 Anum_pg_largeobject_loid,

600

602 Anum_pg_largeobject_pageno,

605

607 obj_desc->snapshot, 2, skey);

608

609 oldtuple = NULL;

610 olddata = NULL;

611 neednextpage = true;

612

613 while (nwritten < nbytes)

614 {

615

616

617

618

619 if (neednextpage)

620 {

622 {

624 elog(ERROR, "null field found in pg_largeobject");

626 Assert(olddata->pageno >= pageno);

627 }

628 neednextpage = false;

629 }

630

631

632

633

634

635 if (olddata != NULL && olddata->pageno == pageno)

636 {

637

638

639

640

641

643 memcpy(workb, VARDATA(datafield), len);

644 if (pfreeit)

645 pfree(datafield);

646

647

648

649

651 if (off > len)

653

654

655

656

658 n = (n <= (nbytes - nwritten)) ? n : (nbytes - nwritten);

659 memcpy(workb + off, buf + nwritten, n);

660 nwritten += n;

661 obj_desc->offset += n;

662 off += n;

663

666

667

668

669

671 memset(nulls, false, sizeof(nulls));

672 memset(replace, false, sizeof(replace));

674 replace[Anum_pg_largeobject_data - 1] = true;

676 values, nulls, replace);

678 indstate);

680

681

682

683

684 oldtuple = NULL;

685 olddata = NULL;

686 neednextpage = true;

687 }

688 else

689 {

690

691

692

693

694

696 if (off > 0)

697 MemSet(workb, 0, off);

698

699

700

701

703 n = (n <= (nbytes - nwritten)) ? n : (nbytes - nwritten);

704 memcpy(workb + off, buf + nwritten, n);

705 nwritten += n;

706 obj_desc->offset += n;

707

708 len = off + n;

710

711

712

713

715 memset(nulls, false, sizeof(nulls));

722 }

723 pageno++;

724 }

725

727

729

730

731

732

733

735

736 return nwritten;

737}

References Assert(), BTEqualStrategyNumber, BTGreaterEqualStrategyNumber, buf, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTupleInsertWithInfo(), CatalogTupleUpdateWithInfo(), CommandCounterIncrement(), data, elog, ereport, errcode(), errmsg(), ERROR, LargeObjectDesc::flags, ForwardScanDirection, getdatafield(), GETSTRUCT(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleHasNulls(), LargeObjectDesc::id, IFS_WRLOCK, Int32GetDatum(), len, lo_heap_r, lo_index_r, LOBLKSIZE, MAX_LARGE_OBJECT_SIZE, MemSet, ObjectIdGetDatum(), LargeObjectDesc::offset, open_lo_relation(), pfree(), PointerGetDatum(), PointerIsValid, RelationData::rd_att, RelationGetDescr, ScanKeyInit(), SET_VARSIZE, LargeObjectDesc::snapshot, systable_beginscan_ordered(), systable_endscan_ordered(), systable_getnext_ordered(), HeapTupleData::t_self, values, VARDATA, and VARHDRSZ.

Referenced by be_lo_from_bytea(), be_lo_put(), lo_import_internal(), and lo_write().

open_lo_relation()

static void open_lo_relation ( void ) static

Definition at line 73 of file inv_api.c.

74{

76

78 return;

79

80

83

84

89

91}

Relation index_open(Oid relationId, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

References CurrentResourceOwner, index_open(), lo_heap_r, lo_index_r, RowExclusiveLock, table_open(), and TopTransactionResourceOwner.

Referenced by inv_getsize(), inv_read(), inv_truncate(), and inv_write().

lo_compat_privileges

bool lo_compat_privileges

lo_heap_r

lo_index_r