Skip to content

Commit 18d62ef

Browse files
committed
Added support for non explicitly mapped PG type
1 parent 0d9f671 commit 18d62ef

File tree

5 files changed

+28
-12
lines changed

5 files changed

+28
-12
lines changed

src/cloudsync.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
extern "C" {
1818
#endif
1919

20-
#define CLOUDSYNC_VERSION "0.9.94"
20+
#define CLOUDSYNC_VERSION "0.9.95"
2121
#define CLOUDSYNC_MAX_TABLENAME_LEN 512
2222

2323
#define CLOUDSYNC_VALUE_NOTSET -1

src/postgresql/cloudsync_postgresql.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,11 +1665,15 @@ static pgvalue_t *cloudsync_decode_bytea_to_pgvalue (bytea *encoded, Oid target_
16651665
argt[0] = FLOAT8OID;
16661666
argv[0] = Float8GetDatum(dv.dval);
16671667
break;
1668-
case DBTYPE_TEXT:
1668+
case DBTYPE_TEXT: {
16691669
argt[0] = TEXTOID;
1670-
argv[0] = PointerGetDatum(cstring_to_text_with_len(dv.pval ? dv.pval : "", (int)(dv.len)));
1670+
Size tlen = dv.pval ? (Size)dv.len : 0;
1671+
text *t = (text *)palloc(VARHDRSZ + tlen);
1672+
SET_VARSIZE(t, VARHDRSZ + tlen);
1673+
if (tlen > 0) memmove(VARDATA(t), dv.pval, tlen);
1674+
argv[0] = PointerGetDatum(t);
16711675
argv_is_pointer = true;
1672-
break;
1676+
} break;
16731677
case DBTYPE_BLOB: {
16741678
argt[0] = BYTEAOID;
16751679
bytea *ba = (bytea *)palloc(VARHDRSZ + dv.len);

src/postgresql/database_postgresql.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,8 +2199,9 @@ int databasevm_bind_value (dbvm_t *vm, int index, dbvalue_t *value) {
21992199
// Pass-by-reference: need to copy the actual data
22002200
// Handle variable-length types (typlen == -1) and cstrings (typlen == -2)
22012201
if (typlen == -1) {
2202-
// Variable-length type (varlena): use datumCopy with correct size
2203-
Size len = VARSIZE(DatumGetPointer(v->datum));
2202+
// Variable-length type (varlena): use VARSIZE_ANY to handle
2203+
// both short (1-byte) and regular (4-byte) varlena headers
2204+
Size len = VARSIZE_ANY(DatumGetPointer(v->datum));
22042205
dcopy = PointerGetDatum(palloc(len));
22052206
memcpy(DatumGetPointer(dcopy), DatumGetPointer(v->datum), len);
22062207
} else if (typlen == -2) {
@@ -2430,8 +2431,10 @@ const void *database_value_blob (dbvalue_t *value) {
24302431
pgvalue_t *v = (pgvalue_t *)value;
24312432
if (!v || v->isnull) return NULL;
24322433

2433-
// Text types reuse blob accessor (pk encode reads text bytes directly)
2434-
if (pgvalue_is_text_type(v->typeid)) {
2434+
// Text types reuse blob accessor (pk encode reads text bytes directly).
2435+
// Exclude JSONB: its internal format is binary, not text —
2436+
// it must go through OidOutputFunctionCall to get the JSON text.
2437+
if (pgvalue_is_text_type(v->typeid) && v->typeid != JSONBOID) {
24352438
pgvalue_ensure_detoast(v);
24362439
text *txt = (text *)DatumGetPointer(v->datum);
24372440
return VARDATA_ANY(txt);
@@ -2443,6 +2446,11 @@ const void *database_value_blob (dbvalue_t *value) {
24432446
return VARDATA_ANY(ba);
24442447
}
24452448

2449+
// For unmapped types and JSONB (mapped to DBTYPE_TEXT),
2450+
// convert to text representation via the type's output function
2451+
const char *cstr = database_value_text(value);
2452+
if (cstr) return cstr;
2453+
24462454
return NULL;
24472455
}
24482456

@@ -2495,11 +2503,11 @@ const char *database_value_text (dbvalue_t *value) {
24952503
if (!v->cstring && !v->owns_cstring) {
24962504
PG_TRY();
24972505
{
2498-
if (pgvalue_is_text_type(v->typeid)) {
2506+
if (pgvalue_is_text_type(v->typeid) && v->typeid != JSONBOID) {
24992507
pgvalue_ensure_detoast(v);
25002508
v->cstring = text_to_cstring((text *)DatumGetPointer(v->datum));
25012509
} else {
2502-
// Fallback to type output function for non-text types
2510+
// Type output function for JSONB and other non-text types
25032511
Oid outfunc;
25042512
bool isvarlena;
25052513
getTypeOutputInfo(v->typeid, &outfunc, &isvarlena);
@@ -2527,7 +2535,8 @@ int database_value_bytes (dbvalue_t *value) {
25272535
pgvalue_t *v = (pgvalue_t *)value;
25282536
if (!v || v->isnull) return 0;
25292537

2530-
if (pgvalue_is_text_type(v->typeid)) {
2538+
// Exclude JSONB: binary internal format, must use OidOutputFunctionCall
2539+
if (pgvalue_is_text_type(v->typeid) && v->typeid != JSONBOID) {
25312540
pgvalue_ensure_detoast(v);
25322541
text *txt = (text *)DatumGetPointer(v->datum);
25332542
return VARSIZE_ANY_EXHDR(txt);
@@ -2537,6 +2546,9 @@ int database_value_bytes (dbvalue_t *value) {
25372546
bytea *ba = (bytea *)DatumGetPointer(v->datum);
25382547
return VARSIZE_ANY_EXHDR(ba);
25392548
}
2549+
// For unmapped types and JSONB (mapped to DBTYPE_TEXT),
2550+
// ensure the text representation is materialized
2551+
database_value_text(value);
25402552
if (v->cstring) {
25412553
return (int)strlen(v->cstring);
25422554
}

src/sqlite/database_sqlite.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ char *sql_build_insert_missing_pks_query(const char *schema, const char *table_n
253253
// Build pk_decode select list
254254
char *pkdecode = sql_build_pk_decode_selectlist_query(NULL, table_name);
255255
if (!pkdecode) {
256-
pkdecode = cloudsync_memory_strdup("cloudsync_pk_decode(pk, 1) AS rowid");
256+
pkdecode = cloudsync_string_dup("cloudsync_pk_decode(pk, 1) AS rowid");
257257
if (!pkdecode) return NULL;
258258
}
259259

0 commit comments

Comments
 (0)