PostgreSQL Source Code  git master
hstore_io.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "hstore.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "utils/builtins.h"
#include "utils/json.h"
#include "utils/jsonapi.h"
#include "utils/jsonb.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/typcache.h"
Include dependency graph for hstore_io.c:

Go to the source code of this file.

Data Structures

struct  HSParser
 
struct  ColumnIOData
 
struct  RecordIOData
 

Macros

#define RESIZEPRSBUF
 
#define GV_WAITVAL   0
 
#define GV_INVAL   1
 
#define GV_INESCVAL   2
 
#define GV_WAITESCIN   3
 
#define GV_WAITESCESCIN   4
 
#define WKEY   0
 
#define WVAL   1
 
#define WEQ   2
 
#define WGT   3
 
#define WDEL   4
 

Typedefs

typedef struct ColumnIOData ColumnIOData
 
typedef struct RecordIOData RecordIOData
 

Functions

 HSTORE_POLLUTE (hstore_from_text, tconvert)
 
static bool get_val (HSParser *state, bool ignoreeq, bool *escaped)
 
static void parse_hstore (HSParser *state)
 
static int comparePairs (const void *a, const void *b)
 
int hstoreUniquePairs (Pairs *a, int32 l, int32 *buflen)
 
size_t hstoreCheckKeyLen (size_t len)
 
size_t hstoreCheckValLen (size_t len)
 
HStorehstorePairs (Pairs *pairs, int32 pcount, int32 buflen)
 
 PG_FUNCTION_INFO_V1 (hstore_in)
 
Datum hstore_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_recv)
 
Datum hstore_recv (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_text)
 
Datum hstore_from_text (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_arrays)
 
Datum hstore_from_arrays (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_array)
 
Datum hstore_from_array (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_record)
 
Datum hstore_from_record (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_populate_record)
 
Datum hstore_populate_record (PG_FUNCTION_ARGS)
 
static char * cpw (char *dst, char *src, int len)
 
 PG_FUNCTION_INFO_V1 (hstore_out)
 
Datum hstore_out (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_send)
 
Datum hstore_send (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_json_loose)
 
Datum hstore_to_json_loose (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_json)
 
Datum hstore_to_json (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_jsonb)
 
Datum hstore_to_jsonb (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_jsonb_loose)
 
Datum hstore_to_jsonb_loose (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Macro Definition Documentation

◆ GV_INESCVAL

#define GV_INESCVAL   2

Definition at line 55 of file hstore_io.c.

Referenced by get_val().

◆ GV_INVAL

#define GV_INVAL   1

Definition at line 54 of file hstore_io.c.

Referenced by get_val().

◆ GV_WAITESCESCIN

#define GV_WAITESCESCIN   4

Definition at line 57 of file hstore_io.c.

Referenced by get_val().

◆ GV_WAITESCIN

#define GV_WAITESCIN   3

Definition at line 56 of file hstore_io.c.

Referenced by get_val().

◆ GV_WAITVAL

#define GV_WAITVAL   0

Definition at line 53 of file hstore_io.c.

Referenced by get_val().

◆ RESIZEPRSBUF

#define RESIZEPRSBUF
Value:
do { \
if ( state->cur - state->word + 1 >= state->wordlen ) \
{ \
int32 clen = state->cur - state->word; \
state->wordlen *= 2; \
state->word = (char*)repalloc( (void*)state->word, state->wordlen ); \
state->cur = state->word + clen; \
} \
} while (0)
Definition: regguts.h:298
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069

Definition at line 41 of file hstore_io.c.

Referenced by get_val().

◆ WDEL

#define WDEL   4

Definition at line 178 of file hstore_io.c.

Referenced by parse_hstore().

◆ WEQ

#define WEQ   2

Definition at line 176 of file hstore_io.c.

Referenced by parse_hstore().

◆ WGT

#define WGT   3

Definition at line 177 of file hstore_io.c.

Referenced by parse_hstore().

◆ WKEY

#define WKEY   0

Definition at line 174 of file hstore_io.c.

Referenced by parse_hstore().

◆ WVAL

#define WVAL   1

Definition at line 175 of file hstore_io.c.

Referenced by parse_hstore().

Typedef Documentation

◆ ColumnIOData

typedef struct ColumnIOData ColumnIOData

◆ RecordIOData

typedef struct RecordIOData RecordIOData

Function Documentation

◆ comparePairs()

static int comparePairs ( const void *  a,
const void *  b 
)
static

Definition at line 281 of file hstore_io.c.

References Pairs::key, Pairs::keylen, and Pairs::needfree.

Referenced by hstoreUniquePairs().

282 {
283  const Pairs *pa = a;
284  const Pairs *pb = b;
285 
286  if (pa->keylen == pb->keylen)
287  {
288  int res = memcmp(pa->key, pb->key, pa->keylen);
289 
290  if (res)
291  return res;
292 
293  /* guarantee that needfree will be later */
294  if (pb->needfree == pa->needfree)
295  return 0;
296  else if (pa->needfree)
297  return 1;
298  else
299  return -1;
300  }
301  return (pa->keylen > pb->keylen) ? 1 : -1;
302 }
bool needfree
Definition: hstore.h:168
char * key
Definition: hstore.h:163
size_t keylen
Definition: hstore.h:165
Definition: hstore.h:161

◆ cpw()

static char* cpw ( char *  dst,
char *  src,
int  len 
)
static

Definition at line 1144 of file hstore_io.c.

References hstore_out(), and PG_FUNCTION_INFO_V1().

Referenced by hstore_out().

1145 {
1146  char *ptr = src;
1147 
1148  while (ptr - src < len)
1149  {
1150  if (*ptr == '"' || *ptr == '\\')
1151  *dst++ = '\\';
1152  *dst++ = *ptr++;
1153  }
1154  return dst;
1155 }

◆ get_val()

static bool get_val ( HSParser state,
bool  ignoreeq,
bool escaped 
)
static

Definition at line 60 of file hstore_io.c.

References HSParser::begin, HSParser::cur, elog, ERROR, GV_INESCVAL, GV_INVAL, GV_WAITESCESCIN, GV_WAITESCIN, GV_WAITVAL, palloc(), HSParser::ptr, RESIZEPRSBUF, HSParser::word, and HSParser::wordlen.

Referenced by parse_hstore().

61 {
62  int st = GV_WAITVAL;
63 
64  state->wordlen = 32;
65  state->cur = state->word = palloc(state->wordlen);
66  *escaped = false;
67 
68  while (1)
69  {
70  if (st == GV_WAITVAL)
71  {
72  if (*(state->ptr) == '"')
73  {
74  *escaped = true;
75  st = GV_INESCVAL;
76  }
77  else if (*(state->ptr) == '\0')
78  {
79  return false;
80  }
81  else if (*(state->ptr) == '=' && !ignoreeq)
82  {
83  elog(ERROR, "Syntax error near '%c' at position %d", *(state->ptr), (int32) (state->ptr - state->begin));
84  }
85  else if (*(state->ptr) == '\\')
86  {
87  st = GV_WAITESCIN;
88  }
89  else if (!isspace((unsigned char) *(state->ptr)))
90  {
91  *(state->cur) = *(state->ptr);
92  state->cur++;
93  st = GV_INVAL;
94  }
95  }
96  else if (st == GV_INVAL)
97  {
98  if (*(state->ptr) == '\\')
99  {
100  st = GV_WAITESCIN;
101  }
102  else if (*(state->ptr) == '=' && !ignoreeq)
103  {
104  state->ptr--;
105  return true;
106  }
107  else if (*(state->ptr) == ',' && ignoreeq)
108  {
109  state->ptr--;
110  return true;
111  }
112  else if (isspace((unsigned char) *(state->ptr)))
113  {
114  return true;
115  }
116  else if (*(state->ptr) == '\0')
117  {
118  state->ptr--;
119  return true;
120  }
121  else
122  {
123  RESIZEPRSBUF;
124  *(state->cur) = *(state->ptr);
125  state->cur++;
126  }
127  }
128  else if (st == GV_INESCVAL)
129  {
130  if (*(state->ptr) == '\\')
131  {
132  st = GV_WAITESCESCIN;
133  }
134  else if (*(state->ptr) == '"')
135  {
136  return true;
137  }
138  else if (*(state->ptr) == '\0')
139  {
140  elog(ERROR, "Unexpected end of string");
141  }
142  else
143  {
144  RESIZEPRSBUF;
145  *(state->cur) = *(state->ptr);
146  state->cur++;
147  }
148  }
149  else if (st == GV_WAITESCIN)
150  {
151  if (*(state->ptr) == '\0')
152  elog(ERROR, "Unexpected end of string");
153  RESIZEPRSBUF;
154  *(state->cur) = *(state->ptr);
155  state->cur++;
156  st = GV_INVAL;
157  }
158  else if (st == GV_WAITESCESCIN)
159  {
160  if (*(state->ptr) == '\0')
161  elog(ERROR, "Unexpected end of string");
162  RESIZEPRSBUF;
163  *(state->cur) = *(state->ptr);
164  state->cur++;
165  st = GV_INESCVAL;
166  }
167  else
168  elog(ERROR, "Unknown state %d at position line %d in file '%s'", st, __LINE__, __FILE__);
169 
170  state->ptr++;
171  }
172 }
#define GV_WAITVAL
Definition: hstore_io.c:53
char * word
Definition: hstore_io.c:33
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
char * cur
Definition: hstore_io.c:32
#define GV_INVAL
Definition: hstore_io.c:54
#define GV_INESCVAL
Definition: hstore_io.c:55
#define RESIZEPRSBUF
Definition: hstore_io.c:41
#define GV_WAITESCESCIN
Definition: hstore_io.c:57
char * begin
Definition: hstore_io.c:30
char * ptr
Definition: hstore_io.c:31
void * palloc(Size size)
Definition: mcxt.c:949
int wordlen
Definition: hstore_io.c:34
#define elog(elevel,...)
Definition: elog.h:228
#define GV_WAITESCIN
Definition: hstore_io.c:56

◆ hstore_from_array()

Datum hstore_from_array ( PG_FUNCTION_ARGS  )

Definition at line 650 of file hstore_io.c.

References ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, Assert, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, palloc(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, Pairs::val, Pairs::vallen, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by hstore_from_arrays().

651 {
652  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
653  int ndims = ARR_NDIM(in_array);
654  int count;
655  int32 buflen;
656  HStore *out;
657  Pairs *pairs;
658  Datum *in_datums;
659  bool *in_nulls;
660  int in_count;
661  int i;
662 
663  Assert(ARR_ELEMTYPE(in_array) == TEXTOID);
664 
665  switch (ndims)
666  {
667  case 0:
668  out = hstorePairs(NULL, 0, 0);
669  PG_RETURN_POINTER(out);
670 
671  case 1:
672  if ((ARR_DIMS(in_array)[0]) % 2)
673  ereport(ERROR,
674  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
675  errmsg("array must have even number of elements")));
676  break;
677 
678  case 2:
679  if ((ARR_DIMS(in_array)[1]) != 2)
680  ereport(ERROR,
681  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
682  errmsg("array must have two columns")));
683  break;
684 
685  default:
686  ereport(ERROR,
687  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
688  errmsg("wrong number of array subscripts")));
689  }
690 
691  deconstruct_array(in_array,
692  TEXTOID, -1, false, 'i',
693  &in_datums, &in_nulls, &in_count);
694 
695  count = in_count / 2;
696 
697  /* see discussion in hstoreArrayToPairs() */
698  if (count > MaxAllocSize / sizeof(Pairs))
699  ereport(ERROR,
700  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
701  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
702  count, (int) (MaxAllocSize / sizeof(Pairs)))));
703 
704  pairs = palloc(count * sizeof(Pairs));
705 
706  for (i = 0; i < count; ++i)
707  {
708  if (in_nulls[i * 2])
709  ereport(ERROR,
710  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
711  errmsg("null value not allowed for hstore key")));
712 
713  if (in_nulls[i * 2 + 1])
714  {
715  pairs[i].key = VARDATA(in_datums[i * 2]);
716  pairs[i].val = NULL;
717  pairs[i].keylen =
718  hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
719  pairs[i].vallen = 4;
720  pairs[i].isnull = true;
721  pairs[i].needfree = false;
722  }
723  else
724  {
725  pairs[i].key = VARDATA(in_datums[i * 2]);
726  pairs[i].val = VARDATA(in_datums[i * 2 + 1]);
727  pairs[i].keylen =
728  hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
729  pairs[i].vallen =
730  hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ);
731  pairs[i].isnull = false;
732  pairs[i].needfree = false;
733  }
734  }
735 
736  count = hstoreUniquePairs(pairs, count, &buflen);
737 
738  out = hstorePairs(pairs, count, buflen);
739 
740  PG_RETURN_POINTER(out);
741 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:562
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:369
int errcode(int sqlerrcode)
Definition: elog.c:608
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
signed int int32
Definition: c.h:347
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:282
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:380
#define ereport(elevel, rest)
Definition: elog.h:141
#define MaxAllocSize
Definition: memutils.h:40
uintptr_t Datum
Definition: postgres.h:367
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:311
size_t keylen
Definition: hstore.h:165
#define Assert(condition)
Definition: c.h:739
bool isnull
Definition: hstore.h:167
#define ARR_NDIM(a)
Definition: array.h:278
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:359
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
Definition: hstore.h:161
#define ARR_ELEMTYPE(a)
Definition: array.h:280

◆ hstore_from_arrays()

Datum hstore_from_arrays ( PG_FUNCTION_ARGS  )

Definition at line 530 of file hstore_io.c.

References ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, Assert, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, hstore_from_array(), hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, palloc(), PG_ARGISNULL, PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_NULL, PG_RETURN_POINTER, Pairs::val, Pairs::vallen, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by hstore_from_text().

531 {
532  int32 buflen;
533  HStore *out;
534  Pairs *pairs;
535  Datum *key_datums;
536  bool *key_nulls;
537  int key_count;
538  Datum *value_datums;
539  bool *value_nulls;
540  int value_count;
541  ArrayType *key_array;
542  ArrayType *value_array;
543  int i;
544 
545  if (PG_ARGISNULL(0))
546  PG_RETURN_NULL();
547 
548  key_array = PG_GETARG_ARRAYTYPE_P(0);
549 
550  Assert(ARR_ELEMTYPE(key_array) == TEXTOID);
551 
552  /*
553  * must check >1 rather than != 1 because empty arrays have 0 dimensions,
554  * not 1
555  */
556 
557  if (ARR_NDIM(key_array) > 1)
558  ereport(ERROR,
559  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
560  errmsg("wrong number of array subscripts")));
561 
562  deconstruct_array(key_array,
563  TEXTOID, -1, false, 'i',
564  &key_datums, &key_nulls, &key_count);
565 
566  /* see discussion in hstoreArrayToPairs() */
567  if (key_count > MaxAllocSize / sizeof(Pairs))
568  ereport(ERROR,
569  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
570  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
571  key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
572 
573  /* value_array might be NULL */
574 
575  if (PG_ARGISNULL(1))
576  {
577  value_array = NULL;
578  value_count = key_count;
579  value_datums = NULL;
580  value_nulls = NULL;
581  }
582  else
583  {
584  value_array = PG_GETARG_ARRAYTYPE_P(1);
585 
586  Assert(ARR_ELEMTYPE(value_array) == TEXTOID);
587 
588  if (ARR_NDIM(value_array) > 1)
589  ereport(ERROR,
590  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
591  errmsg("wrong number of array subscripts")));
592 
593  if ((ARR_NDIM(key_array) > 0 || ARR_NDIM(value_array) > 0) &&
594  (ARR_NDIM(key_array) != ARR_NDIM(value_array) ||
595  ARR_DIMS(key_array)[0] != ARR_DIMS(value_array)[0] ||
596  ARR_LBOUND(key_array)[0] != ARR_LBOUND(value_array)[0]))
597  ereport(ERROR,
598  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
599  errmsg("arrays must have same bounds")));
600 
601  deconstruct_array(value_array,
602  TEXTOID, -1, false, 'i',
603  &value_datums, &value_nulls, &value_count);
604 
605  Assert(key_count == value_count);
606  }
607 
608  pairs = palloc(key_count * sizeof(Pairs));
609 
610  for (i = 0; i < key_count; ++i)
611  {
612  if (key_nulls[i])
613  ereport(ERROR,
614  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
615  errmsg("null value not allowed for hstore key")));
616 
617  if (!value_nulls || value_nulls[i])
618  {
619  pairs[i].key = VARDATA(key_datums[i]);
620  pairs[i].val = NULL;
621  pairs[i].keylen =
622  hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
623  pairs[i].vallen = 4;
624  pairs[i].isnull = true;
625  pairs[i].needfree = false;
626  }
627  else
628  {
629  pairs[i].key = VARDATA(key_datums[i]);
630  pairs[i].val = VARDATA(value_datums[i]);
631  pairs[i].keylen =
632  hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
633  pairs[i].vallen =
634  hstoreCheckValLen(VARSIZE(value_datums[i]) - VARHDRSZ);
635  pairs[i].isnull = false;
636  pairs[i].needfree = false;
637  }
638  }
639 
640  key_count = hstoreUniquePairs(pairs, key_count, &buflen);
641 
642  out = hstorePairs(pairs, key_count, buflen);
643 
644  PG_RETURN_POINTER(out);
645 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:562
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:369
int errcode(int sqlerrcode)
Definition: elog.c:608
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
signed int int32
Definition: c.h:347
char * val
Definition: hstore.h:164
#define ARR_LBOUND(a)
Definition: array.h:284
char * key
Definition: hstore.h:163
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:282
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:380
#define ereport(elevel, rest)
Definition: elog.h:141
#define MaxAllocSize
Definition: memutils.h:40
uintptr_t Datum
Definition: postgres.h:367
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:311
size_t keylen
Definition: hstore.h:165
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:739
bool isnull
Definition: hstore.h:167
#define ARR_NDIM(a)
Definition: array.h:278
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:359
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
Definition: hstore.h:161
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ hstore_from_record()

Datum hstore_from_record ( PG_FUNCTION_ARGS  )

Definition at line 768 of file hstore_io.c.

References Assert, ColumnIOData::column_type, RecordIOData::columns, fmgr_info_cxt(), FmgrInfo::fn_mcxt, get_fn_expr_argtype(), getTypeOutputInfo(), heap_deform_tuple(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, hstore_populate_record(), hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, InvalidOid, Pairs::isnull, ItemPointerSetInvalid, Pairs::key, Pairs::keylen, lookup_rowtype_tupdesc_domain(), MaxTupleAttributeNumber, MemoryContextAlloc(), MemSet, NameStr, TupleDescData::natts, RecordIOData::ncolumns, Pairs::needfree, offsetof, OutputFunctionCall(), palloc(), PG_ARGISNULL, PG_FUNCTION_INFO_V1(), PG_GETARG_HEAPTUPLEHEADER, PG_RETURN_POINTER, ColumnIOData::proc, RecordIOData::record_type, RecordIOData::record_typmod, ReleaseTupleDesc, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, TupleDescAttr, ColumnIOData::typiofunc, Pairs::val, Pairs::vallen, value, and values.

769 {
770  HeapTupleHeader rec;
771  int32 buflen;
772  HStore *out;
773  Pairs *pairs;
774  Oid tupType;
775  int32 tupTypmod;
776  TupleDesc tupdesc;
777  HeapTupleData tuple;
778  RecordIOData *my_extra;
779  int ncolumns;
780  int i,
781  j;
782  Datum *values;
783  bool *nulls;
784 
785  if (PG_ARGISNULL(0))
786  {
787  Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
788 
789  /*
790  * We have no tuple to look at, so the only source of type info is the
791  * argtype --- which might be domain over composite, but we don't care
792  * here, since we have no need to be concerned about domain
793  * constraints. The lookup_rowtype_tupdesc_domain call below will
794  * error out if we don't have a known composite type oid here.
795  */
796  tupType = argtype;
797  tupTypmod = -1;
798 
799  rec = NULL;
800  }
801  else
802  {
803  rec = PG_GETARG_HEAPTUPLEHEADER(0);
804 
805  /*
806  * Extract type info from the tuple itself -- this will work even for
807  * anonymous record types.
808  */
809  tupType = HeapTupleHeaderGetTypeId(rec);
810  tupTypmod = HeapTupleHeaderGetTypMod(rec);
811  }
812 
813  tupdesc = lookup_rowtype_tupdesc_domain(tupType, tupTypmod, false);
814  ncolumns = tupdesc->natts;
815 
816  /*
817  * We arrange to look up the needed I/O info just once per series of
818  * calls, assuming the record type doesn't change underneath us.
819  */
820  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
821  if (my_extra == NULL ||
822  my_extra->ncolumns != ncolumns)
823  {
824  fcinfo->flinfo->fn_extra =
825  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
826  offsetof(RecordIOData, columns) +
827  ncolumns * sizeof(ColumnIOData));
828  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
829  my_extra->record_type = InvalidOid;
830  my_extra->record_typmod = 0;
831  }
832 
833  if (my_extra->record_type != tupType ||
834  my_extra->record_typmod != tupTypmod)
835  {
836  MemSet(my_extra, 0,
837  offsetof(RecordIOData, columns) +
838  ncolumns * sizeof(ColumnIOData));
839  my_extra->record_type = tupType;
840  my_extra->record_typmod = tupTypmod;
841  my_extra->ncolumns = ncolumns;
842  }
843 
844  Assert(ncolumns <= MaxTupleAttributeNumber); /* thus, no overflow */
845  pairs = palloc(ncolumns * sizeof(Pairs));
846 
847  if (rec)
848  {
849  /* Build a temporary HeapTuple control structure */
851  ItemPointerSetInvalid(&(tuple.t_self));
852  tuple.t_tableOid = InvalidOid;
853  tuple.t_data = rec;
854 
855  values = (Datum *) palloc(ncolumns * sizeof(Datum));
856  nulls = (bool *) palloc(ncolumns * sizeof(bool));
857 
858  /* Break down the tuple into fields */
859  heap_deform_tuple(&tuple, tupdesc, values, nulls);
860  }
861  else
862  {
863  values = NULL;
864  nulls = NULL;
865  }
866 
867  for (i = 0, j = 0; i < ncolumns; ++i)
868  {
869  ColumnIOData *column_info = &my_extra->columns[i];
870  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
871  Oid column_type = att->atttypid;
872  char *value;
873 
874  /* Ignore dropped columns in datatype */
875  if (att->attisdropped)
876  continue;
877 
878  pairs[j].key = NameStr(att->attname);
879  pairs[j].keylen = hstoreCheckKeyLen(strlen(NameStr(att->attname)));
880 
881  if (!nulls || nulls[i])
882  {
883  pairs[j].val = NULL;
884  pairs[j].vallen = 4;
885  pairs[j].isnull = true;
886  pairs[j].needfree = false;
887  ++j;
888  continue;
889  }
890 
891  /*
892  * Convert the column value to text
893  */
894  if (column_info->column_type != column_type)
895  {
896  bool typIsVarlena;
897 
898  getTypeOutputInfo(column_type,
899  &column_info->typiofunc,
900  &typIsVarlena);
901  fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
902  fcinfo->flinfo->fn_mcxt);
903  column_info->column_type = column_type;
904  }
905 
906  value = OutputFunctionCall(&column_info->proc, values[i]);
907 
908  pairs[j].val = value;
909  pairs[j].vallen = hstoreCheckValLen(strlen(value));
910  pairs[j].isnull = false;
911  pairs[j].needfree = false;
912  ++j;
913  }
914 
915  ncolumns = hstoreUniquePairs(pairs, j, &buflen);
916 
917  out = hstorePairs(pairs, ncolumns, buflen);
918 
919  ReleaseTupleDesc(tupdesc);
920 
921  PG_RETURN_POINTER(out);
922 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
FmgrInfo proc
Definition: hstore_io.c:753
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define MaxTupleAttributeNumber
Definition: htup_details.h:33
Oid record_type
Definition: hstore_io.c:758
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:369
static struct @145 value
#define MemSet(start, val, len)
Definition: c.h:962
size_t vallen
Definition: hstore.h:166
#define PG_GETARG_HEAPTUPLEHEADER(n)
Definition: fmgr.h:306
unsigned int Oid
Definition: postgres_ext.h:31
bool needfree
Definition: hstore.h:168
int32 record_typmod
Definition: hstore_io.c:759
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition: typcache.c:1708
signed int int32
Definition: c.h:347
char * val
Definition: hstore.h:164
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:468
char * key
Definition: hstore.h:163
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1802
ItemPointerData t_self
Definition: htup.h:65
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:380
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
Oid t_tableOid
Definition: htup.h:66
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]
Definition: hstore_io.c:763
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:458
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:311
#define InvalidOid
Definition: postgres_ext.h:36
size_t keylen
Definition: hstore.h:165
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:739
bool isnull
Definition: hstore.h:167
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1249
static Datum values[MAXATTR]
Definition: bootstrap.c:167
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:359
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
void * palloc(Size size)
Definition: mcxt.c:949
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
int i
#define NameStr(name)
Definition: c.h:616
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
Definition: hstore.h:161
#define offsetof(type, field)
Definition: c.h:662
Oid column_type
Definition: hstore_io.c:750
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:452

◆ hstore_from_text()

Datum hstore_from_text ( PG_FUNCTION_ARGS  )

Definition at line 494 of file hstore_io.c.

References hstore_from_arrays(), hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), Pairs::isnull, sort-test::key, Pairs::key, Pairs::keylen, Pairs::needfree, PG_ARGISNULL, PG_FUNCTION_INFO_V1(), PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_POINTER, Pairs::val, val, Pairs::vallen, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by hstore_recv().

495 {
496  text *key;
497  text *val = NULL;
498  Pairs p;
499  HStore *out;
500 
501  if (PG_ARGISNULL(0))
502  PG_RETURN_NULL();
503 
504  p.needfree = false;
505  key = PG_GETARG_TEXT_PP(0);
506  p.key = VARDATA_ANY(key);
508 
509  if (PG_ARGISNULL(1))
510  {
511  p.vallen = 0;
512  p.isnull = true;
513  }
514  else
515  {
516  val = PG_GETARG_TEXT_PP(1);
517  p.val = VARDATA_ANY(val);
519  p.isnull = false;
520  }
521 
522  out = hstorePairs(&p, 1, p.keylen + p.vallen);
523 
524  PG_RETURN_POINTER(out);
525 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:369
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
char * val
Definition: hstore.h:164
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
char * key
Definition: hstore.h:163
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:380
size_t keylen
Definition: hstore.h:165
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
bool isnull
Definition: hstore.h:167
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:359
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:556
Definition: hstore.h:161
long val
Definition: informix.c:664
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ hstore_in()

Datum hstore_in ( PG_FUNCTION_ARGS  )

Definition at line 411 of file hstore_io.c.

References HSParser::begin, hstore_recv(), hstorePairs(), hstoreUniquePairs(), HSParser::pairs, parse_hstore(), HSParser::pcur, PG_FUNCTION_INFO_V1(), PG_GETARG_CSTRING, and PG_RETURN_POINTER.

Referenced by hstorePairs().

412 {
413  HSParser state;
414  int32 buflen;
415  HStore *out;
416 
417  state.begin = PG_GETARG_CSTRING(0);
418 
419  parse_hstore(&state);
420 
421  state.pcur = hstoreUniquePairs(state.pairs, state.pcur, &buflen);
422 
423  out = hstorePairs(state.pairs, state.pcur, buflen);
424 
425  PG_RETURN_POINTER(out);
426 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
signed int int32
Definition: c.h:347
static void parse_hstore(HSParser *state)
Definition: hstore_io.c:182
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:380
int pcur
Definition: hstore_io.c:37
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:311
Definition: regguts.h:298
Pairs * pairs
Definition: hstore_io.c:36
char * begin
Definition: hstore_io.c:30
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272

◆ hstore_out()

Datum hstore_out ( PG_FUNCTION_ARGS  )

Definition at line 1159 of file hstore_io.c.

References ARRPTR, cpw(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_send(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_CSTRING, pstrdup(), and STRPTR.

Referenced by cpw().

1160 {
1161  HStore *in = PG_GETARG_HSTORE_P(0);
1162  int buflen,
1163  i;
1164  int count = HS_COUNT(in);
1165  char *out,
1166  *ptr;
1167  char *base = STRPTR(in);
1168  HEntry *entries = ARRPTR(in);
1169 
1170  if (count == 0)
1172 
1173  buflen = 0;
1174 
1175  /*
1176  * this loop overestimates due to pessimistic assumptions about escaping,
1177  * so very large hstore values can't be output. this could be fixed, but
1178  * many other data types probably have the same issue. This replaced code
1179  * that used the original varlena size for calculations, which was wrong
1180  * in some subtle ways.
1181  */
1182 
1183  for (i = 0; i < count; i++)
1184  {
1185  /* include "" and => and comma-space */
1186  buflen += 6 + 2 * HSTORE_KEYLEN(entries, i);
1187  /* include "" only if nonnull */
1188  buflen += 2 + (HSTORE_VALISNULL(entries, i)
1189  ? 2
1190  : 2 * HSTORE_VALLEN(entries, i));
1191  }
1192 
1193  out = ptr = palloc(buflen);
1194 
1195  for (i = 0; i < count; i++)
1196  {
1197  *ptr++ = '"';
1198  ptr = cpw(ptr, HSTORE_KEY(entries, base, i), HSTORE_KEYLEN(entries, i));
1199  *ptr++ = '"';
1200  *ptr++ = '=';
1201  *ptr++ = '>';
1202  if (HSTORE_VALISNULL(entries, i))
1203  {
1204  *ptr++ = 'N';
1205  *ptr++ = 'U';
1206  *ptr++ = 'L';
1207  *ptr++ = 'L';
1208  }
1209  else
1210  {
1211  *ptr++ = '"';
1212  ptr = cpw(ptr, HSTORE_VAL(entries, base, i), HSTORE_VALLEN(entries, i));
1213  *ptr++ = '"';
1214  }
1215 
1216  if (i + 1 != count)
1217  {
1218  *ptr++ = ',';
1219  *ptr++ = ' ';
1220  }
1221  }
1222  *ptr = '\0';
1223 
1224  PG_RETURN_CSTRING(out);
1225 }
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
static char * cpw(char *dst, char *src, int len)
Definition: hstore_io.c:1144
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24

◆ HSTORE_POLLUTE()

HSTORE_POLLUTE ( hstore_from_text  ,
tconvert   
)

◆ hstore_populate_record()

Datum hstore_populate_record ( PG_FUNCTION_ARGS  )

Definition at line 927 of file hstore_io.c.

References ARRPTR, ColumnIOData::column_type, RecordIOData::columns, domain_check(), RecordIOData::domain_info, ereport, errcode(), errmsg(), ERROR, fmgr_info_cxt(), FmgrInfo::fn_mcxt, get_fn_expr_argtype(), getTypeInputInfo(), heap_deform_tuple(), heap_form_tuple(), HeapTupleGetDatum, HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, HS_COUNT, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreFindKey(), i, idx(), InputFunctionCall(), InvalidOid, ItemPointerSetInvalid, lookup_rowtype_tupdesc_domain(), MemoryContextAlloc(), MemSet, NameStr, TupleDescData::natts, RecordIOData::ncolumns, offsetof, palloc(), PG_ARGISNULL, PG_GETARG_HEAPTUPLEHEADER, PG_GETARG_HSTORE_P, PG_RETURN_DATUM, PG_RETURN_NULL, PG_RETURN_POINTER, ColumnIOData::proc, RecordIOData::record_type, RecordIOData::record_typmod, ReleaseTupleDesc, STRPTR, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, TupleDescData::tdtypeid, TupleDescAttr, type_is_rowtype(), ColumnIOData::typiofunc, ColumnIOData::typioparam, value, and values.

Referenced by hstore_from_record().

928 {
929  Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
930  HStore *hs;
931  HEntry *entries;
932  char *ptr;
933  HeapTupleHeader rec;
934  Oid tupType;
935  int32 tupTypmod;
936  TupleDesc tupdesc;
937  HeapTupleData tuple;
938  HeapTuple rettuple;
939  RecordIOData *my_extra;
940  int ncolumns;
941  int i;
942  Datum *values;
943  bool *nulls;
944 
945  if (!type_is_rowtype(argtype))
946  ereport(ERROR,
947  (errcode(ERRCODE_DATATYPE_MISMATCH),
948  errmsg("first argument must be a rowtype")));
949 
950  if (PG_ARGISNULL(0))
951  {
952  if (PG_ARGISNULL(1))
953  PG_RETURN_NULL();
954 
955  rec = NULL;
956 
957  /*
958  * We have no tuple to look at, so the only source of type info is the
959  * argtype. The lookup_rowtype_tupdesc_domain call below will error
960  * out if we don't have a known composite type oid here.
961  */
962  tupType = argtype;
963  tupTypmod = -1;
964  }
965  else
966  {
967  rec = PG_GETARG_HEAPTUPLEHEADER(0);
968 
969  if (PG_ARGISNULL(1))
970  PG_RETURN_POINTER(rec);
971 
972  /*
973  * Extract type info from the tuple itself -- this will work even for
974  * anonymous record types.
975  */
976  tupType = HeapTupleHeaderGetTypeId(rec);
977  tupTypmod = HeapTupleHeaderGetTypMod(rec);
978  }
979 
980  hs = PG_GETARG_HSTORE_P(1);
981  entries = ARRPTR(hs);
982  ptr = STRPTR(hs);
983 
984  /*
985  * if the input hstore is empty, we can only skip the rest if we were
986  * passed in a non-null record, since otherwise there may be issues with
987  * domain nulls.
988  */
989 
990  if (HS_COUNT(hs) == 0 && rec)
991  PG_RETURN_POINTER(rec);
992 
993  /*
994  * Lookup the input record's tupdesc. For the moment, we don't worry
995  * about whether it is a domain over composite.
996  */
997  tupdesc = lookup_rowtype_tupdesc_domain(tupType, tupTypmod, false);
998  ncolumns = tupdesc->natts;
999 
1000  if (rec)
1001  {
1002  /* Build a temporary HeapTuple control structure */
1003  tuple.t_len = HeapTupleHeaderGetDatumLength(rec);
1004  ItemPointerSetInvalid(&(tuple.t_self));
1005  tuple.t_tableOid = InvalidOid;
1006  tuple.t_data = rec;
1007  }
1008 
1009  /*
1010  * We arrange to look up the needed I/O info just once per series of
1011  * calls, assuming the record type doesn't change underneath us.
1012  */
1013  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
1014  if (my_extra == NULL ||
1015  my_extra->ncolumns != ncolumns)
1016  {
1017  fcinfo->flinfo->fn_extra =
1018  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
1019  offsetof(RecordIOData, columns) +
1020  ncolumns * sizeof(ColumnIOData));
1021  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
1022  my_extra->record_type = InvalidOid;
1023  my_extra->record_typmod = 0;
1024  my_extra->domain_info = NULL;
1025  }
1026 
1027  if (my_extra->record_type != tupType ||
1028  my_extra->record_typmod != tupTypmod)
1029  {
1030  MemSet(my_extra, 0,
1031  offsetof(RecordIOData, columns) +
1032  ncolumns * sizeof(ColumnIOData));
1033  my_extra->record_type = tupType;
1034  my_extra->record_typmod = tupTypmod;
1035  my_extra->ncolumns = ncolumns;
1036  }
1037 
1038  values = (Datum *) palloc(ncolumns * sizeof(Datum));
1039  nulls = (bool *) palloc(ncolumns * sizeof(bool));
1040 
1041  if (rec)
1042  {
1043  /* Break down the tuple into fields */
1044  heap_deform_tuple(&tuple, tupdesc, values, nulls);
1045  }
1046  else
1047  {
1048  for (i = 0; i < ncolumns; ++i)
1049  {
1050  values[i] = (Datum) 0;
1051  nulls[i] = true;
1052  }
1053  }
1054 
1055  for (i = 0; i < ncolumns; ++i)
1056  {
1057  ColumnIOData *column_info = &my_extra->columns[i];
1058  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1059  Oid column_type = att->atttypid;
1060  char *value;
1061  int idx;
1062  int vallen;
1063 
1064  /* Ignore dropped columns in datatype */
1065  if (att->attisdropped)
1066  {
1067  nulls[i] = true;
1068  continue;
1069  }
1070 
1071  idx = hstoreFindKey(hs, 0,
1072  NameStr(att->attname),
1073  strlen(NameStr(att->attname)));
1074 
1075  /*
1076  * we can't just skip here if the key wasn't found since we might have
1077  * a domain to deal with. If we were passed in a non-null record
1078  * datum, we assume that the existing values are valid (if they're
1079  * not, then it's not our fault), but if we were passed in a null,
1080  * then every field which we don't populate needs to be run through
1081  * the input function just in case it's a domain type.
1082  */
1083  if (idx < 0 && rec)
1084  continue;
1085 
1086  /*
1087  * Prepare to convert the column value from text
1088  */
1089  if (column_info->column_type != column_type)
1090  {
1091  getTypeInputInfo(column_type,
1092  &column_info->typiofunc,
1093  &column_info->typioparam);
1094  fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
1095  fcinfo->flinfo->fn_mcxt);
1096  column_info->column_type = column_type;
1097  }
1098 
1099  if (idx < 0 || HSTORE_VALISNULL(entries, idx))
1100  {
1101  /*
1102  * need InputFunctionCall to happen even for nulls, so that domain
1103  * checks are done
1104  */
1105  values[i] = InputFunctionCall(&column_info->proc, NULL,
1106  column_info->typioparam,
1107  att->atttypmod);
1108  nulls[i] = true;
1109  }
1110  else
1111  {
1112  vallen = HSTORE_VALLEN(entries, idx);
1113  value = palloc(1 + vallen);
1114  memcpy(value, HSTORE_VAL(entries, ptr, idx), vallen);
1115  value[vallen] = 0;
1116 
1117  values[i] = InputFunctionCall(&column_info->proc, value,
1118  column_info->typioparam,
1119  att->atttypmod);
1120  nulls[i] = false;
1121  }
1122  }
1123 
1124  rettuple = heap_form_tuple(tupdesc, values, nulls);
1125 
1126  /*
1127  * If the target type is domain over composite, all we know at this point
1128  * is that we've made a valid value of the base composite type. Must
1129  * check domain constraints before deciding we're done.
1130  */
1131  if (argtype != tupdesc->tdtypeid)
1132  domain_check(HeapTupleGetDatum(rettuple), false,
1133  argtype,
1134  &my_extra->domain_info,
1135  fcinfo->flinfo->fn_mcxt);
1136 
1137  ReleaseTupleDesc(tupdesc);
1138 
1140 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
FmgrInfo proc
Definition: hstore_io.c:753
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Oid record_type
Definition: hstore_io.c:758
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
void * domain_info
Definition: hstore_io.c:761
static struct @145 value
int errcode(int sqlerrcode)
Definition: elog.c:608
#define MemSet(start, val, len)
Definition: c.h:962
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define PG_GETARG_HEAPTUPLEHEADER(n)
Definition: fmgr.h:306
unsigned int Oid
Definition: postgres_ext.h:31
int32 record_typmod
Definition: hstore_io.c:759
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition: typcache.c:1708
signed int int32
Definition: c.h:347
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:468
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define ERROR
Definition: elog.h:43
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1802
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
#define HS_COUNT(hsp_)
Definition: hstore.h:61
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
Oid t_tableOid
Definition: htup.h:66
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2433
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2641
#define ereport(elevel, rest)
Definition: elog.h:141
ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]
Definition: hstore_io.c:763
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:458
void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt)
Definition: domains.c:327
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1531
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
Definition: hstore.h:18
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
Oid typioparam
Definition: hstore_io.c:752
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1249
static Datum values[MAXATTR]
Definition: bootstrap.c:167
Oid tdtypeid
Definition: tupdesc.h:82
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:172
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define STRPTR(x)
Definition: hstore.h:76
int i
#define NameStr(name)
Definition: c.h:616
#define ARRPTR(x)
Definition: cube.c:24
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define PG_RETURN_NULL()
Definition: fmgr.h:335
#define offsetof(type, field)
Definition: c.h:662
Oid column_type
Definition: hstore_io.c:750
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:452

◆ hstore_recv()

Datum hstore_recv ( PG_FUNCTION_ARGS  )

Definition at line 431 of file hstore_io.c.

References buf, ereport, errcode(), errmsg(), ERROR, hstore_from_text(), hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_POINTER, PG_RETURN_POINTER, pq_getmsgint(), pq_getmsgtext(), Pairs::val, and Pairs::vallen.

Referenced by hstore_in().

432 {
433  int32 buflen;
434  HStore *out;
435  Pairs *pairs;
436  int32 i;
437  int32 pcount;
439 
440  pcount = pq_getmsgint(buf, 4);
441 
442  if (pcount == 0)
443  {
444  out = hstorePairs(NULL, 0, 0);
445  PG_RETURN_POINTER(out);
446  }
447 
448  if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
449  ereport(ERROR,
450  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
451  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
452  pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
453  pairs = palloc(pcount * sizeof(Pairs));
454 
455  for (i = 0; i < pcount; ++i)
456  {
457  int rawlen = pq_getmsgint(buf, 4);
458  int len;
459 
460  if (rawlen < 0)
461  ereport(ERROR,
462  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
463  errmsg("null value not allowed for hstore key")));
464 
465  pairs[i].key = pq_getmsgtext(buf, rawlen, &len);
466  pairs[i].keylen = hstoreCheckKeyLen(len);
467  pairs[i].needfree = true;
468 
469  rawlen = pq_getmsgint(buf, 4);
470  if (rawlen < 0)
471  {
472  pairs[i].val = NULL;
473  pairs[i].vallen = 0;
474  pairs[i].isnull = true;
475  }
476  else
477  {
478  pairs[i].val = pq_getmsgtext(buf, rawlen, &len);
479  pairs[i].vallen = hstoreCheckValLen(len);
480  pairs[i].isnull = false;
481  }
482  }
483 
484  pcount = hstoreUniquePairs(pairs, pcount, &buflen);
485 
486  out = hstorePairs(pairs, pcount, buflen);
487 
488  PG_RETURN_POINTER(out);
489 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
StringInfoData * StringInfo
Definition: stringinfo.h:44
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:369
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
signed int int32
Definition: c.h:347
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
#define ERROR
Definition: elog.h:43
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:380
static char * buf
Definition: pg_test_fsync.c:67
#define ereport(elevel, rest)
Definition: elog.h:141
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:548
#define MaxAllocSize
Definition: memutils.h:40
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:311
size_t keylen
Definition: hstore.h:165
bool isnull
Definition: hstore.h:167
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:359
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
Definition: hstore.h:161

◆ hstore_send()

Datum hstore_send ( PG_FUNCTION_ARGS  )

Definition at line 1230 of file hstore_io.c.

References ARRPTR, buf, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_to_json_loose(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint32(), pq_sendtext(), and STRPTR.

Referenced by hstore_out().

1231 {
1232  HStore *in = PG_GETARG_HSTORE_P(0);
1233  int i;
1234  int count = HS_COUNT(in);
1235  char *base = STRPTR(in);
1236  HEntry *entries = ARRPTR(in);
1238 
1239  pq_begintypsend(&buf);
1240 
1241  pq_sendint32(&buf, count);
1242 
1243  for (i = 0; i < count; i++)
1244  {
1245  int32 keylen = HSTORE_KEYLEN(entries, i);
1246 
1247  pq_sendint32(&buf, keylen);
1248  pq_sendtext(&buf, HSTORE_KEY(entries, base, i), keylen);
1249  if (HSTORE_VALISNULL(entries, i))
1250  {
1251  pq_sendint32(&buf, -1);
1252  }
1253  else
1254  {
1255  int32 vallen = HSTORE_VALLEN(entries, i);
1256 
1257  pq_sendint32(&buf, vallen);
1258  pq_sendtext(&buf, HSTORE_VAL(entries, base, i), vallen);
1259  }
1260  }
1261 
1263 }
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
signed int int32
Definition: c.h:347
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
static char * buf
Definition: pg_test_fsync.c:67
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24

◆ hstore_to_json()

Datum hstore_to_json ( PG_FUNCTION_ARGS  )

Definition at line 1331 of file hstore_io.c.

References appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoString(), ARRPTR, cstring_to_text(), cstring_to_text_with_len(), StringInfoData::data, escape_json(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_to_jsonb(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_TEXT_P, resetStringInfo(), and STRPTR.

Referenced by hstore_to_json_loose().

1332 {
1333  HStore *in = PG_GETARG_HSTORE_P(0);
1334  int i;
1335  int count = HS_COUNT(in);
1336  char *base = STRPTR(in);
1337  HEntry *entries = ARRPTR(in);
1338  StringInfoData tmp,
1339  dst;
1340 
1341  if (count == 0)
1343 
1344  initStringInfo(&tmp);
1345  initStringInfo(&dst);
1346 
1347  appendStringInfoChar(&dst, '{');
1348 
1349  for (i = 0; i < count; i++)
1350  {
1351  resetStringInfo(&tmp);
1352  appendBinaryStringInfo(&tmp, HSTORE_KEY(entries, base, i),
1353  HSTORE_KEYLEN(entries, i));
1354  escape_json(&dst, tmp.data);
1355  appendStringInfoString(&dst, ": ");
1356  if (HSTORE_VALISNULL(entries, i))
1357  appendStringInfoString(&dst, "null");
1358  else
1359  {
1360  resetStringInfo(&tmp);
1361  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1362  HSTORE_VALLEN(entries, i));
1363  escape_json(&dst, tmp.data);
1364  }
1365 
1366  if (i + 1 != count)
1367  appendStringInfoString(&dst, ", ");
1368  }
1369  appendStringInfoChar(&dst, '}');
1370 
1372 }
Definition: hstore.h:44
void escape_json(StringInfo buf, const char *str)
Definition: json.c:2483
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ hstore_to_json_loose()

Datum hstore_to_json_loose ( PG_FUNCTION_ARGS  )

Definition at line 1276 of file hstore_io.c.

References appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoString(), ARRPTR, cstring_to_text(), cstring_to_text_with_len(), StringInfoData::data, escape_json(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_to_json(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), IsValidJsonNumber(), StringInfoData::len, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_TEXT_P, resetStringInfo(), and STRPTR.

Referenced by hstore_send().

1277 {
1278  HStore *in = PG_GETARG_HSTORE_P(0);
1279  int i;
1280  int count = HS_COUNT(in);
1281  char *base = STRPTR(in);
1282  HEntry *entries = ARRPTR(in);
1283  StringInfoData tmp,
1284  dst;
1285 
1286  if (count == 0)
1288 
1289  initStringInfo(&tmp);
1290  initStringInfo(&dst);
1291 
1292  appendStringInfoChar(&dst, '{');
1293 
1294  for (i = 0; i < count; i++)
1295  {
1296  resetStringInfo(&tmp);
1297  appendBinaryStringInfo(&tmp, HSTORE_KEY(entries, base, i),
1298  HSTORE_KEYLEN(entries, i));
1299  escape_json(&dst, tmp.data);
1300  appendStringInfoString(&dst, ": ");
1301  if (HSTORE_VALISNULL(entries, i))
1302  appendStringInfoString(&dst, "null");
1303  /* guess that values of 't' or 'f' are booleans */
1304  else if (HSTORE_VALLEN(entries, i) == 1 &&
1305  *(HSTORE_VAL(entries, base, i)) == 't')
1306  appendStringInfoString(&dst, "true");
1307  else if (HSTORE_VALLEN(entries, i) == 1 &&
1308  *(HSTORE_VAL(entries, base, i)) == 'f')
1309  appendStringInfoString(&dst, "false");
1310  else
1311  {
1312  resetStringInfo(&tmp);
1313  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1314  HSTORE_VALLEN(entries, i));
1315  if (IsValidJsonNumber(tmp.data, tmp.len))
1316  appendBinaryStringInfo(&dst, tmp.data, tmp.len);
1317  else
1318  escape_json(&dst, tmp.data);
1319  }
1320 
1321  if (i + 1 != count)
1322  appendStringInfoString(&dst, ", ");
1323  }
1324  appendStringInfoChar(&dst, '}');
1325 
1327 }
Definition: hstore.h:44
void escape_json(StringInfo buf, const char *str)
Definition: json.c:2483
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
bool IsValidJsonNumber(const char *str, int len)
Definition: json.c:193
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ hstore_to_jsonb()

Datum hstore_to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1376 of file hstore_io.c.

References ARRPTR, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_to_jsonb_loose(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, jbvNull, jbvString, JsonbValueToJsonb(), sort-test::key, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_POINTER, pushJsonbValue(), STRPTR, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by hstore_to_json().

1377 {
1378  HStore *in = PG_GETARG_HSTORE_P(0);
1379  int i;
1380  int count = HS_COUNT(in);
1381  char *base = STRPTR(in);
1382  HEntry *entries = ARRPTR(in);
1383  JsonbParseState *state = NULL;
1384  JsonbValue *res;
1385 
1386  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1387 
1388  for (i = 0; i < count; i++)
1389  {
1390  JsonbValue key,
1391  val;
1392 
1393  key.type = jbvString;
1394  key.val.string.len = HSTORE_KEYLEN(entries, i);
1395  key.val.string.val = HSTORE_KEY(entries, base, i);
1396 
1397  (void) pushJsonbValue(&state, WJB_KEY, &key);
1398 
1399  if (HSTORE_VALISNULL(entries, i))
1400  {
1401  val.type = jbvNull;
1402  }
1403  else
1404  {
1405  val.type = jbvString;
1406  val.val.string.len = HSTORE_VALLEN(entries, i);
1407  val.val.string.val = HSTORE_VAL(entries, base, i);
1408  }
1409  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1410  }
1411 
1412  res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
1413 
1415 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
char * val
Definition: jsonb.h:272
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
Definition: jsonb.h:236
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
Definition: jsonb.h:23
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
Definition: regguts.h:298
Definition: hstore.h:18
enum jbvType type
Definition: jsonb.h:263
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24
long val
Definition: informix.c:664

◆ hstore_to_jsonb_loose()

Datum hstore_to_jsonb_loose ( PG_FUNCTION_ARGS  )

Definition at line 1419 of file hstore_io.c.

References appendBinaryStringInfo(), ARRPTR, CStringGetDatum, StringInfoData::data, DatumGetNumeric, DirectFunctionCall3, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), Int32GetDatum, InvalidOid, IsValidJsonNumber(), jbvBool, jbvNull, jbvNumeric, jbvString, JsonbValueToJsonb(), sort-test::key, StringInfoData::len, numeric_in(), ObjectIdGetDatum, PG_GETARG_HSTORE_P, PG_RETURN_POINTER, pushJsonbValue(), resetStringInfo(), STRPTR, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by hstore_to_jsonb().

1420 {
1421  HStore *in = PG_GETARG_HSTORE_P(0);
1422  int i;
1423  int count = HS_COUNT(in);
1424  char *base = STRPTR(in);
1425  HEntry *entries = ARRPTR(in);
1426  JsonbParseState *state = NULL;
1427  JsonbValue *res;
1428  StringInfoData tmp;
1429 
1430  initStringInfo(&tmp);
1431 
1432  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1433 
1434  for (i = 0; i < count; i++)
1435  {
1436  JsonbValue key,
1437  val;
1438 
1439  key.type = jbvString;
1440  key.val.string.len = HSTORE_KEYLEN(entries, i);
1441  key.val.string.val = HSTORE_KEY(entries, base, i);
1442 
1443  (void) pushJsonbValue(&state, WJB_KEY, &key);
1444 
1445  if (HSTORE_VALISNULL(entries, i))
1446  {
1447  val.type = jbvNull;
1448  }
1449  /* guess that values of 't' or 'f' are booleans */
1450  else if (HSTORE_VALLEN(entries, i) == 1 &&
1451  *(HSTORE_VAL(entries, base, i)) == 't')
1452  {
1453  val.type = jbvBool;
1454  val.val.boolean = true;
1455  }
1456  else if (HSTORE_VALLEN(entries, i) == 1 &&
1457  *(HSTORE_VAL(entries, base, i)) == 'f')
1458  {
1459  val.type = jbvBool;
1460  val.val.boolean = false;
1461  }
1462  else
1463  {
1464  resetStringInfo(&tmp);
1465  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1466  HSTORE_VALLEN(entries, i));
1467  if (IsValidJsonNumber(tmp.data, tmp.len))
1468  {
1469  Datum numd;
1470 
1471  val.type = jbvNumeric;
1473  CStringGetDatum(tmp.data),
1475  Int32GetDatum(-1));
1476  val.val.numeric = DatumGetNumeric(numd);
1477  }
1478  else
1479  {
1480  val.type = jbvString;
1481  val.val.string.len = HSTORE_VALLEN(entries, i);
1482  val.val.string.val = HSTORE_VAL(entries, base, i);
1483  }
1484  }
1485  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1486  }
1487 
1488  res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
1489 
1491 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
char * val
Definition: jsonb.h:272
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
Definition: jsonb.h:239
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
Definition: jsonb.h:236
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
bool IsValidJsonNumber(const char *str, int len)
Definition: json.c:193
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define CStringGetDatum(X)
Definition: postgres.h:578
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:573
Definition: jsonb.h:23
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:619
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define DatumGetNumeric(X)
Definition: numeric.h:49
Definition: regguts.h:298
Definition: hstore.h:18
enum jbvType type
Definition: jsonb.h:263
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define Int32GetDatum(X)
Definition: postgres.h:479
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
long val
Definition: informix.c:664

◆ hstoreCheckKeyLen()

size_t hstoreCheckKeyLen ( size_t  len)

Definition at line 359 of file hstore_io.c.

References ereport, errcode(), errmsg(), ERROR, and HSTORE_MAX_KEY_LEN.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_from_text(), hstore_recv(), and parse_hstore().

360 {
361  if (len > HSTORE_MAX_KEY_LEN)
362  ereport(ERROR,
363  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
364  errmsg("string too long for hstore key")));
365  return len;
366 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define HSTORE_MAX_KEY_LEN
Definition: hstore.h:41
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ hstoreCheckValLen()

size_t hstoreCheckValLen ( size_t  len)

Definition at line 369 of file hstore_io.c.

References ereport, errcode(), errmsg(), ERROR, and HSTORE_MAX_VALUE_LEN.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_from_text(), hstore_recv(), and parse_hstore().

370 {
371  if (len > HSTORE_MAX_VALUE_LEN)
372  ereport(ERROR,
373  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
374  errmsg("string too long for hstore value")));
375  return len;
376 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define HSTORE_MAX_VALUE_LEN
Definition: hstore.h:42

◆ hstorePairs()

HStore* hstorePairs ( Pairs pairs,
int32  pcount,
int32  buflen 
)

Definition at line 380 of file hstore_io.c.

References ARRPTR, buf, CALCDATASIZE, HS_ADDITEM, HS_FINALIZE, HS_SETCOUNT, hstore_in(), i, palloc(), PG_FUNCTION_INFO_V1(), SET_VARSIZE, and STRPTR.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_from_text(), hstore_in(), and hstore_recv().

381 {
382  HStore *out;
383  HEntry *entry;
384  char *ptr;
385  char *buf;
386  int32 len;
387  int32 i;
388 
389  len = CALCDATASIZE(pcount, buflen);
390  out = palloc(len);
391  SET_VARSIZE(out, len);
392  HS_SETCOUNT(out, pcount);
393 
394  if (pcount == 0)
395  return out;
396 
397  entry = ARRPTR(out);
398  buf = ptr = STRPTR(out);
399 
400  for (i = 0; i < pcount; i++)
401  HS_ADDITEM(entry, buf, ptr, pairs[i]);
402 
403  HS_FINALIZE(out, pcount, buf, ptr);
404 
405  return out;
406 }
Definition: hstore.h:44
signed int int32
Definition: c.h:347
static char * buf
Definition: pg_test_fsync.c:67
#define HS_ADDITEM(dent_, dbuf_, dptr_, pair_)
Definition: hstore.h:112
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
Definition: hstore.h:18
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62

◆ hstoreUniquePairs()

int hstoreUniquePairs ( Pairs a,
int32  l,
int32 buflen 
)

Definition at line 311 of file hstore_io.c.

References comparePairs(), Pairs::isnull, Pairs::key, Pairs::keylen, Pairs::needfree, pfree(), qsort, Pairs::val, and Pairs::vallen.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_in(), and hstore_recv().

312 {
313  Pairs *ptr,
314  *res;
315 
316  *buflen = 0;
317  if (l < 2)
318  {
319  if (l == 1)
320  *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen);
321  return l;
322  }
323 
324  qsort((void *) a, l, sizeof(Pairs), comparePairs);
325 
326  /*
327  * We can't use qunique here because we have some clean-up code to run on
328  * removed elements.
329  */
330  ptr = a + 1;
331  res = a;
332  while (ptr - a < l)
333  {
334  if (ptr->keylen == res->keylen &&
335  memcmp(ptr->key, res->key, res->keylen) == 0)
336  {
337  if (ptr->needfree)
338  {
339  pfree(ptr->key);
340  pfree(ptr->val);
341  }
342  }
343  else
344  {
345  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
346  res++;
347  if (res != ptr)
348  memcpy(res, ptr, sizeof(Pairs));
349  }
350 
351  ptr++;
352  }
353 
354  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
355  return res + 1 - a;
356 }
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
void pfree(void *pointer)
Definition: mcxt.c:1056
static int comparePairs(const void *a, const void *b)
Definition: hstore_io.c:281
size_t keylen
Definition: hstore.h:165
bool isnull
Definition: hstore.h:167
#define qsort(a, b, c, d)
Definition: port.h:488
Definition: hstore.h:161

◆ parse_hstore()

static void parse_hstore ( HSParser state)
static

Definition at line 182 of file hstore_io.c.

References HSParser::begin, HSParser::cur, elog, ERROR, get_val(), hstoreCheckKeyLen(), hstoreCheckValLen(), Pairs::isnull, Pairs::key, Pairs::keylen, Pairs::needfree, HSParser::pairs, palloc(), HSParser::pcur, pg_strcasecmp(), HSParser::plen, HSParser::ptr, repalloc(), Pairs::val, Pairs::vallen, WDEL, WEQ, WGT, WKEY, HSParser::word, and WVAL.

Referenced by hstore_in().

183 {
184  int st = WKEY;
185  bool escaped = false;
186 
187  state->plen = 16;
188  state->pairs = (Pairs *) palloc(sizeof(Pairs) * state->plen);
189  state->pcur = 0;
190  state->ptr = state->begin;
191  state->word = NULL;
192 
193  while (1)
194  {
195  if (st == WKEY)
196  {
197  if (!get_val(state, false, &escaped))
198  return;
199  if (state->pcur >= state->plen)
200  {
201  state->plen *= 2;
202  state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen);
203  }
204  state->pairs[state->pcur].key = state->word;
205  state->pairs[state->pcur].keylen = hstoreCheckKeyLen(state->cur - state->word);
206  state->pairs[state->pcur].val = NULL;
207  state->word = NULL;
208  st = WEQ;
209  }
210  else if (st == WEQ)
211  {
212  if (*(state->ptr) == '=')
213  {
214  st = WGT;
215  }
216  else if (*(state->ptr) == '\0')
217  {
218  elog(ERROR, "Unexpected end of string");
219  }
220  else if (!isspace((unsigned char) *(state->ptr)))
221  {
222  elog(ERROR, "Syntax error near '%c' at position %d", *(state->ptr), (int32) (state->ptr - state->begin));
223  }
224  }
225  else if (st == WGT)
226  {
227  if (*(state->ptr) == '>')
228  {
229  st = WVAL;
230  }
231  else if (*(state->ptr) == '\0')
232  {
233  elog(ERROR, "Unexpected end of string");
234  }
235  else
236  {
237  elog(ERROR, "Syntax error near '%c' at position %d", *(state->ptr), (int32) (state->ptr - state->begin));
238  }
239  }
240  else if (st == WVAL)
241  {
242  if (!get_val(state, true, &escaped))
243  elog(ERROR, "Unexpected end of string");
244  state->pairs[state->pcur].val = state->word;
245  state->pairs[state->pcur].vallen = hstoreCheckValLen(state->cur - state->word);
246  state->pairs[state->pcur].isnull = false;
247  state->pairs[state->pcur].needfree = true;
248  if (state->cur - state->word == 4 && !escaped)
249  {
250  state->word[4] = '\0';
251  if (0 == pg_strcasecmp(state->word, "null"))
252  state->pairs[state->pcur].isnull = true;
253  }
254  state->word = NULL;
255  state->pcur++;
256  st = WDEL;
257  }
258  else if (st == WDEL)
259  {
260  if (*(state->ptr) == ',')
261  {
262  st = WKEY;
263  }
264  else if (*(state->ptr) == '\0')
265  {
266  return;
267  }
268  else if (!isspace((unsigned char) *(state->ptr)))
269  {
270  elog(ERROR, "Syntax error near '%c' at position %d", *(state->ptr), (int32) (state->ptr - state->begin));
271  }
272  }
273  else
274  elog(ERROR, "Unknown state %d at line %d in file '%s'", st, __LINE__, __FILE__);
275 
276  state->ptr++;
277  }
278 }
char * word
Definition: hstore_io.c:33
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:369
#define WGT
Definition: hstore_io.c:177
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
signed int int32
Definition: c.h:347
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
#define ERROR
Definition: elog.h:43
char * cur
Definition: hstore_io.c:32
#define WDEL
Definition: hstore_io.c:178
int pcur
Definition: hstore_io.c:37
#define WVAL
Definition: hstore_io.c:175
size_t keylen
Definition: hstore.h:165
bool isnull
Definition: hstore.h:167
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
Pairs * pairs
Definition: hstore_io.c:36
char * begin
Definition: hstore_io.c:30
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:359
char * ptr
Definition: hstore_io.c:31
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228
#define WEQ
Definition: hstore_io.c:176
#define WKEY
Definition: hstore_io.c:174
int plen
Definition: hstore_io.c:38
static bool get_val(HSParser *state, bool ignoreeq, bool *escaped)
Definition: hstore_io.c:60
Definition: hstore.h:161

◆ PG_FUNCTION_INFO_V1() [1/13]

◆ PG_FUNCTION_INFO_V1() [2/13]

PG_FUNCTION_INFO_V1 ( hstore_recv  )

◆ PG_FUNCTION_INFO_V1() [3/13]

PG_FUNCTION_INFO_V1 ( hstore_from_text  )

◆ PG_FUNCTION_INFO_V1() [4/13]

PG_FUNCTION_INFO_V1 ( hstore_from_arrays  )

◆ PG_FUNCTION_INFO_V1() [5/13]

PG_FUNCTION_INFO_V1 ( hstore_from_array  )

◆ PG_FUNCTION_INFO_V1() [6/13]

PG_FUNCTION_INFO_V1 ( hstore_from_record  )

◆ PG_FUNCTION_INFO_V1() [7/13]

PG_FUNCTION_INFO_V1 ( hstore_populate_record  )

◆ PG_FUNCTION_INFO_V1() [8/13]

PG_FUNCTION_INFO_V1 ( hstore_out  )

◆ PG_FUNCTION_INFO_V1() [9/13]

PG_FUNCTION_INFO_V1 ( hstore_send  )

◆ PG_FUNCTION_INFO_V1() [10/13]

PG_FUNCTION_INFO_V1 ( hstore_to_json_loose  )

◆ PG_FUNCTION_INFO_V1() [11/13]

PG_FUNCTION_INFO_V1 ( hstore_to_json  )

◆ PG_FUNCTION_INFO_V1() [12/13]

PG_FUNCTION_INFO_V1 ( hstore_to_jsonb  )

◆ PG_FUNCTION_INFO_V1() [13/13]

PG_FUNCTION_INFO_V1 ( hstore_to_jsonb_loose  )

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 22 of file hstore_io.c.