@@ -167,12 +167,16 @@ Datum cloudsync_db_version (PG_FUNCTION_ARGS) {
167167 UNUSED_PARAMETER (fcinfo );
168168
169169 cloudsync_context * data = get_cloudsync_context ();
170+ int rc = DBRES_OK ;
171+ int64_t version = 0 ;
172+ bool spi_connected = false;
170173
171174 // Connect SPI for database operations
172175 int spi_rc = SPI_connect ();
173176 if (spi_rc != SPI_OK_CONNECT ) {
174177 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
175178 }
179+ spi_connected = true;
176180
177181 PG_TRY ();
178182 {
@@ -182,23 +186,25 @@ Datum cloudsync_db_version (PG_FUNCTION_ARGS) {
182186 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("Unable to retrieve db_version (%s)" , database_errmsg (data ))));
183187 }
184188
185- int64_t version = cloudsync_dbversion (data );
186- SPI_finish ();
187-
188- PG_RETURN_INT64 (version );
189+ version = cloudsync_dbversion (data );
189190 }
190191 PG_CATCH ();
191192 {
192- SPI_finish ();
193+ if ( spi_connected ) SPI_finish ();
193194 PG_RE_THROW ();
194195 }
195196 PG_END_TRY ();
197+
198+ if (spi_connected ) SPI_finish ();
199+ PG_RETURN_INT64 (version );
196200}
197201
198202// cloudsync_db_version_next([merging_version]) - Get next database version
199203PG_FUNCTION_INFO_V1 (cloudsync_db_version_next );
200204Datum cloudsync_db_version_next (PG_FUNCTION_ARGS ) {
201205 cloudsync_context * data = get_cloudsync_context ();
206+ int64_t next_version = 0 ;
207+ bool spi_connected = false;
202208
203209 int64_t merging_version = CLOUDSYNC_VALUE_NOTSET ;
204210 if (PG_NARGS () == 1 && !PG_ARGISNULL (0 )) {
@@ -210,21 +216,22 @@ Datum cloudsync_db_version_next (PG_FUNCTION_ARGS) {
210216 if (spi_rc != SPI_OK_CONNECT ) {
211217 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
212218 }
219+ spi_connected = true;
213220
214221 PG_TRY ();
215222 {
216223 cloudsync_pg_ensure_initialized (data , true);
217- int64_t next_version = cloudsync_dbversion_next (data , merging_version );
218- SPI_finish ();
219-
220- PG_RETURN_INT64 (next_version );
224+ next_version = cloudsync_dbversion_next (data , merging_version );
221225 }
222226 PG_CATCH ();
223227 {
224- SPI_finish ();
228+ if ( spi_connected ) SPI_finish ();
225229 PG_RE_THROW ();
226230 }
227231 PG_END_TRY ();
232+
233+ if (spi_connected ) SPI_finish ();
234+ PG_RETURN_INT64 (next_version );
228235}
229236
230237// MARK: - Table Initialization -
@@ -381,30 +388,33 @@ Datum pg_cloudsync_cleanup (PG_FUNCTION_ARGS) {
381388
382389 const char * table = text_to_cstring (PG_GETARG_TEXT_PP (0 ));
383390 cloudsync_context * data = get_cloudsync_context ();
391+ int rc = DBRES_OK ;
392+ bool spi_connected = false;
384393
385394 int spi_rc = SPI_connect ();
386395 if (spi_rc != SPI_OK_CONNECT ) {
387396 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
388397 }
398+ spi_connected = true;
389399
390400 PG_TRY ();
391401 {
392402 cloudsync_pg_ensure_initialized (data , true);
393- int rc = cloudsync_cleanup (data , table );
394- SPI_finish ();
395-
396- if (rc != DBRES_OK ) {
397- ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("%s" , cloudsync_errmsg (data ))));
398- }
399-
400- PG_RETURN_BOOL (true);
403+ rc = cloudsync_cleanup (data , table );
401404 }
402405 PG_CATCH ();
403406 {
404- SPI_finish ();
407+ if ( spi_connected ) SPI_finish ();
405408 PG_RE_THROW ();
406409 }
407410 PG_END_TRY ();
411+
412+ if (spi_connected ) SPI_finish ();
413+ if (rc != DBRES_OK ) {
414+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("%s" , cloudsync_errmsg (data ))));
415+ }
416+
417+ PG_RETURN_BOOL (true);
408418}
409419
410420// cloudsync_terminate - Terminate CloudSync
@@ -413,25 +423,29 @@ Datum pg_cloudsync_terminate (PG_FUNCTION_ARGS) {
413423 UNUSED_PARAMETER (fcinfo );
414424
415425 cloudsync_context * data = get_cloudsync_context ();
426+ int rc = DBRES_OK ;
427+ bool spi_connected = false;
416428
417429 int spi_rc = SPI_connect ();
418430 if (spi_rc != SPI_OK_CONNECT ) {
419431 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
420432 }
433+ spi_connected = true;
421434
422435 PG_TRY ();
423436 {
424437 cloudsync_pg_ensure_initialized (data , true);
425- int rc = cloudsync_terminate (data );
426- SPI_finish ();
427- PG_RETURN_INT32 (rc );
438+ rc = cloudsync_terminate (data );
428439 }
429440 PG_CATCH ();
430441 {
431- SPI_finish ();
442+ if ( spi_connected ) SPI_finish ();
432443 PG_RE_THROW ();
433444 }
434445 PG_END_TRY ();
446+
447+ if (spi_connected ) SPI_finish ();
448+ PG_RETURN_INT32 (rc );
435449}
436450
437451// MARK: - Settings Functions -
@@ -455,27 +469,30 @@ Datum cloudsync_set (PG_FUNCTION_ARGS) {
455469 }
456470
457471 cloudsync_context * data = get_cloudsync_context ();
472+ bool spi_connected = false;
458473
459474 int spi_rc = SPI_connect ();
460475 if (spi_rc != SPI_OK_CONNECT ) {
461476 ereport (ERROR ,
462477 (errcode (ERRCODE_INTERNAL_ERROR ),
463478 errmsg ("SPI_connect failed: %d" , spi_rc )));
464479 }
480+ spi_connected = true;
465481
466482 PG_TRY ();
467483 {
468484 cloudsync_pg_ensure_initialized (data , true);
469485 dbutils_settings_set_key_value (data , key , value );
470- SPI_finish ();
471- PG_RETURN_BOOL (true);
472486 }
473487 PG_CATCH ();
474488 {
475- SPI_finish ();
489+ if ( spi_connected ) SPI_finish ();
476490 PG_RE_THROW ();
477491 }
478492 PG_END_TRY ();
493+
494+ if (spi_connected ) SPI_finish ();
495+ PG_RETURN_BOOL (true);
479496}
480497
481498// cloudsync_set_table - Set table-level configuration
@@ -496,25 +513,28 @@ Datum cloudsync_set_table (PG_FUNCTION_ARGS) {
496513 }
497514
498515 cloudsync_context * data = get_cloudsync_context ();
516+ bool spi_connected = false;
499517
500518 int spi_rc = SPI_connect ();
501519 if (spi_rc != SPI_OK_CONNECT ) {
502520 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
503521 }
522+ spi_connected = true;
504523
505524 PG_TRY ();
506525 {
507526 cloudsync_pg_ensure_initialized (data , true);
508527 dbutils_table_settings_set_key_value (data , tbl , "*" , key , value );
509- SPI_finish ();
510- PG_RETURN_BOOL (true);
511528 }
512529 PG_CATCH ();
513530 {
514- SPI_finish ();
531+ if ( spi_connected ) SPI_finish ();
515532 PG_RE_THROW ();
516533 }
517534 PG_END_TRY ();
535+
536+ if (spi_connected ) SPI_finish ();
537+ PG_RETURN_BOOL (true);
518538}
519539
520540// cloudsync_set_column - Set column-level configuration
@@ -539,27 +559,30 @@ Datum cloudsync_set_column (PG_FUNCTION_ARGS) {
539559 }
540560
541561 cloudsync_context * data = get_cloudsync_context ();
562+ bool spi_connected = false;
542563
543564 int spi_rc = SPI_connect ();
544565 if (spi_rc != SPI_OK_CONNECT ) {
545566 ereport (ERROR ,
546567 (errcode (ERRCODE_INTERNAL_ERROR ),
547568 errmsg ("SPI_connect failed: %d" , spi_rc )));
548569 }
570+ spi_connected = true;
549571
550572 PG_TRY ();
551573 {
552574 cloudsync_pg_ensure_initialized (data , true);
553575 dbutils_table_settings_set_key_value (data , tbl , col , key , value );
554- SPI_finish ();
555- PG_RETURN_BOOL (true);
556576 }
557577 PG_CATCH ();
558578 {
559- SPI_finish ();
579+ if ( spi_connected ) SPI_finish ();
560580 PG_RE_THROW ();
561581 }
562582 PG_END_TRY ();
583+
584+ if (spi_connected ) SPI_finish ();
585+ PG_RETURN_BOOL (true);
563586}
564587
565588// MARK: - Schema Alteration -
@@ -573,32 +596,34 @@ Datum pg_cloudsync_begin_alter (PG_FUNCTION_ARGS) {
573596
574597 const char * table_name = text_to_cstring (PG_GETARG_TEXT_PP (0 ));
575598 cloudsync_context * data = get_cloudsync_context ();
599+ int rc = DBRES_OK ;
600+ bool spi_connected = false;
576601
577602 int spi_rc = SPI_connect ();
578603 if (spi_rc != SPI_OK_CONNECT ) {
579604 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
580605 }
606+ spi_connected = true;
581607
582608 PG_TRY ();
583609 {
584610 cloudsync_pg_ensure_initialized (data , true);
585- int rc = cloudsync_begin_alter (data , table_name );
586- SPI_finish ();
587-
588- if (rc != DBRES_OK ) {
589- ereport (ERROR ,
590- (errcode (ERRCODE_INTERNAL_ERROR ),
591- errmsg ("%s" , cloudsync_errmsg (data ))));
592- }
593-
594- PG_RETURN_BOOL (true);
611+ rc = cloudsync_begin_alter (data , table_name );
595612 }
596613 PG_CATCH ();
597614 {
598- SPI_finish ();
615+ if ( spi_connected ) SPI_finish ();
599616 PG_RE_THROW ();
600617 }
601618 PG_END_TRY ();
619+
620+ if (spi_connected ) SPI_finish ();
621+ if (rc != DBRES_OK ) {
622+ ereport (ERROR ,
623+ (errcode (ERRCODE_INTERNAL_ERROR ),
624+ errmsg ("%s" , cloudsync_errmsg (data ))));
625+ }
626+ PG_RETURN_BOOL (true);
602627}
603628
604629// cloudsync_commit_alter - Commit schema alteration
@@ -610,30 +635,32 @@ Datum pg_cloudsync_commit_alter (PG_FUNCTION_ARGS) {
610635
611636 const char * table_name = text_to_cstring (PG_GETARG_TEXT_PP (0 ));
612637 cloudsync_context * data = get_cloudsync_context ();
638+ int rc = DBRES_OK ;
639+ bool spi_connected = false;
613640
614641 int spi_rc = SPI_connect ();
615642 if (spi_rc != SPI_OK_CONNECT ) {
616643 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
617644 }
645+ spi_connected = true;
618646
619647 PG_TRY ();
620648 {
621649 cloudsync_pg_ensure_initialized (data , true);
622- int rc = cloudsync_commit_alter (data , table_name );
623- SPI_finish ();
624-
625- if (rc != DBRES_OK ) {
626- ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("%s" , cloudsync_errmsg (data ))));
627- }
628-
629- PG_RETURN_BOOL (true);
650+ rc = cloudsync_commit_alter (data , table_name );
630651 }
631652 PG_CATCH ();
632653 {
633- SPI_finish ();
654+ if ( spi_connected ) SPI_finish ();
634655 PG_RE_THROW ();
635656 }
636657 PG_END_TRY ();
658+
659+ if (spi_connected ) SPI_finish ();
660+ if (rc != DBRES_OK ) {
661+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("%s" , cloudsync_errmsg (data ))));
662+ }
663+ PG_RETURN_BOOL (true);
637664}
638665
639666// MARK: - Payload Functions -
@@ -731,31 +758,33 @@ Datum cloudsync_payload_decode (PG_FUNCTION_ARGS) {
731758
732759 const char * payload = VARDATA (payload_data );
733760 cloudsync_context * data = get_cloudsync_context ();
761+ int rc = DBRES_OK ;
762+ int nrows = 0 ;
763+ bool spi_connected = false;
734764
735765 int spi_rc = SPI_connect ();
736766 if (spi_rc != SPI_OK_CONNECT ) {
737767 ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("SPI_connect failed: %d" , spi_rc )));
738768 }
769+ spi_connected = true;
739770
740771 PG_TRY ();
741772 {
742773 cloudsync_pg_ensure_initialized (data , true);
743- int nrows = 0 ;
744- int rc = cloudsync_payload_apply (data , payload , blen , & nrows );
745- SPI_finish ();
746-
747- if (rc != DBRES_OK ) {
748- ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("%s" , cloudsync_errmsg (data ))));
749- }
750-
751- PG_RETURN_INT32 (nrows );
774+ rc = cloudsync_payload_apply (data , payload , blen , & nrows );
752775 }
753776 PG_CATCH ();
754777 {
755- SPI_finish ();
778+ if ( spi_connected ) SPI_finish ();
756779 PG_RE_THROW ();
757780 }
758781 PG_END_TRY ();
782+
783+ if (spi_connected ) SPI_finish ();
784+ if (rc != DBRES_OK ) {
785+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ), errmsg ("%s" , cloudsync_errmsg (data ))));
786+ }
787+ PG_RETURN_INT32 (nrows );
759788}
760789
761790// Alias for payload_decode
0 commit comments