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