@@ -790,3 +790,89 @@ IsReadOnlyIcebergTable(Oid relationId)
790790{
791791 return IsIcebergTable (relationId ) && !IsWritableIcebergTable (relationId );
792792}
793+
794+
795+ /*
796+ * UpdateLastSyncedSnapshotId upserts the last synced snapshot ID for a given relation into the REST catalog sync table.
797+ * This tracks what was last successfully pushed to the REST catalog.
798+ */
799+ void
800+ UpdateLastSyncedSnapshotId (Oid relationId , int64 snapshotId )
801+ {
802+ /* switch to schema owner */
803+ Oid savedUserId = InvalidOid ;
804+ int savedSecurityContext = 0 ;
805+
806+ GetUserIdAndSecContext (& savedUserId , & savedSecurityContext );
807+ SetUserIdAndSecContext (ExtensionOwnerId (PgLakeIceberg ), SECURITY_LOCAL_USERID_CHANGE );
808+
809+ StringInfo query = makeStringInfo ();
810+
811+ appendStringInfo (query ,
812+ "INSERT INTO %s (table_name, last_synced_snapshot_id) "
813+ "VALUES ($1, $2) "
814+ "ON CONFLICT (table_name) "
815+ "DO UPDATE SET last_synced_snapshot_id = EXCLUDED.last_synced_snapshot_id" ,
816+ REST_CATALOG_SYNC_TABLE_QUALIFIED );
817+
818+ DECLARE_SPI_ARGS (2 );
819+ SPI_ARG_VALUE (1 , OIDOID , relationId , false);
820+ SPI_ARG_VALUE (2 , INT8OID , snapshotId , false);
821+
822+ SPI_START ();
823+
824+ bool readOnly = false;
825+
826+ SPI_EXECUTE (query -> data , readOnly );
827+
828+ SPI_END ();
829+
830+ SetUserIdAndSecContext (savedUserId , savedSecurityContext );
831+ }
832+
833+
834+ /*
835+ * GetLastSyncedSnapshotId returns the last synced snapshot id for a given
836+ * relation from the REST catalog sync table. Returns NULL if not found.
837+ */
838+ int64_t
839+ GetLastSyncedSnapshotId (Oid relationId )
840+ {
841+ /* switch to schema owner */
842+ Oid savedUserId = InvalidOid ;
843+ int savedSecurityContext = 0 ;
844+
845+ GetUserIdAndSecContext (& savedUserId , & savedSecurityContext );
846+ SetUserIdAndSecContext (ExtensionOwnerId (PgLakeIceberg ), SECURITY_LOCAL_USERID_CHANGE );
847+
848+ StringInfo query = makeStringInfo ();
849+
850+ appendStringInfo (query ,
851+ "SELECT last_synced_snapshot_id FROM %s "
852+ "WHERE table_name OPERATOR(pg_catalog.=) $1" ,
853+ REST_CATALOG_SYNC_TABLE_QUALIFIED );
854+
855+ DECLARE_SPI_ARGS (1 );
856+ SPI_ARG_VALUE (1 , OIDOID , relationId , false);
857+
858+ SPI_START ();
859+
860+ bool readOnly = true;
861+
862+ SPI_EXECUTE (query -> data , readOnly );
863+
864+ int64_t lastSyncedSnapshotId = -1 ;
865+
866+ if (SPI_processed > 0 )
867+ {
868+ bool isNull = false;
869+
870+ lastSyncedSnapshotId = GET_SPI_VALUE (INT8OID , 0 , 1 , & isNull );
871+ }
872+
873+ SPI_END ();
874+
875+ SetUserIdAndSecContext (savedUserId , savedSecurityContext );
876+
877+ return lastSyncedSnapshotId ;
878+ }
0 commit comments