PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "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 "hstore.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

#define GV_INESCVAL   2

Definition at line 56 of file hstore_io.c.

Referenced by get_val().

#define GV_INVAL   1

Definition at line 55 of file hstore_io.c.

Referenced by get_val().

#define GV_WAITESCESCIN   4

Definition at line 58 of file hstore_io.c.

Referenced by get_val().

#define GV_WAITESCIN   3

Definition at line 57 of file hstore_io.c.

Referenced by get_val().

#define GV_WAITVAL   0

Definition at line 54 of file hstore_io.c.

Referenced by get_val().

#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)
signed int int32
Definition: c.h:253
Definition: regguts.h:298
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021

Definition at line 42 of file hstore_io.c.

Referenced by get_val().

#define WDEL   4

Definition at line 179 of file hstore_io.c.

Referenced by parse_hstore().

#define WEQ   2

Definition at line 177 of file hstore_io.c.

Referenced by parse_hstore().

#define WGT   3

Definition at line 178 of file hstore_io.c.

Referenced by parse_hstore().

#define WKEY   0

Definition at line 175 of file hstore_io.c.

Referenced by parse_hstore().

#define WVAL   1

Definition at line 176 of file hstore_io.c.

Referenced by parse_hstore().

Typedef Documentation

Function Documentation

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

Definition at line 282 of file hstore_io.c.

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

Referenced by hstoreUniquePairs().

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

Definition at line 1105 of file hstore_io.c.

Referenced by hstore_out().

1106 {
1107  char *ptr = src;
1108 
1109  while (ptr - src < len)
1110  {
1111  if (*ptr == '"' || *ptr == '\\')
1112  *dst++ = '\\';
1113  *dst++ = *ptr++;
1114  }
1115  return dst;
1116 }
static bool get_val ( HSParser state,
bool  ignoreeq,
bool escaped 
)
static

Definition at line 61 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().

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

Definition at line 642 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, NULL, palloc(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, TEXTOID, Pairs::val, Pairs::vallen, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

643 {
644  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
645  int ndims = ARR_NDIM(in_array);
646  int count;
647  int32 buflen;
648  HStore *out;
649  Pairs *pairs;
650  Datum *in_datums;
651  bool *in_nulls;
652  int in_count;
653  int i;
654 
655  Assert(ARR_ELEMTYPE(in_array) == TEXTOID);
656 
657  switch (ndims)
658  {
659  case 0:
660  out = hstorePairs(NULL, 0, 0);
661  PG_RETURN_POINTER(out);
662 
663  case 1:
664  if ((ARR_DIMS(in_array)[0]) % 2)
665  ereport(ERROR,
666  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
667  errmsg("array must have even number of elements")));
668  break;
669 
670  case 2:
671  if ((ARR_DIMS(in_array)[1]) != 2)
672  ereport(ERROR,
673  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
674  errmsg("array must have two columns")));
675  break;
676 
677  default:
678  ereport(ERROR,
679  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
680  errmsg("wrong number of array subscripts")));
681  }
682 
683  deconstruct_array(in_array,
684  TEXTOID, -1, false, 'i',
685  &in_datums, &in_nulls, &in_count);
686 
687  count = in_count / 2;
688 
689  /* see discussion in hstoreArrayToPairs() */
690  if (count > MaxAllocSize / sizeof(Pairs))
691  ereport(ERROR,
692  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
693  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
694  count, (int) (MaxAllocSize / sizeof(Pairs)))));
695 
696  pairs = palloc(count * sizeof(Pairs));
697 
698  for (i = 0; i < count; ++i)
699  {
700  if (in_nulls[i * 2])
701  ereport(ERROR,
702  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
703  errmsg("null value not allowed for hstore key")));
704 
705  if (in_nulls[i * 2 + 1])
706  {
707  pairs[i].key = VARDATA_ANY(in_datums[i * 2]);
708  pairs[i].val = NULL;
709  pairs[i].keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(in_datums[i * 2]));
710  pairs[i].vallen = 4;
711  pairs[i].isnull = true;
712  pairs[i].needfree = false;
713  }
714  else
715  {
716  pairs[i].key = VARDATA_ANY(in_datums[i * 2]);
717  pairs[i].val = VARDATA_ANY(in_datums[i * 2 + 1]);
718  pairs[i].keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(in_datums[i * 2]));
719  pairs[i].vallen = hstoreCheckValLen(VARSIZE_ANY_EXHDR(in_datums[i * 2 + 1]));
720  pairs[i].isnull = false;
721  pairs[i].needfree = false;
722  }
723  }
724 
725  count = hstoreUniquePairs(pairs, count, &buflen);
726 
727  out = hstorePairs(pairs, count, buflen);
728 
729  PG_RETURN_POINTER(out);
730 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:349
#define TEXTOID
Definition: pg_type.h:324
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:364
int errcode(int sqlerrcode)
Definition: elog.c:575
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
signed int int32
Definition: c.h:253
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:244
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:275
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:375
#define ereport(elevel, rest)
Definition: elog.h:122
#define MaxAllocSize
Definition: memutils.h:40
uintptr_t Datum
Definition: postgres.h:374
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:312
size_t keylen
Definition: hstore.h:165
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
bool isnull
Definition: hstore.h:167
#define ARR_NDIM(a)
Definition: array.h:271
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3475
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:354
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:342
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: hstore.h:161
#define ARR_ELEMTYPE(a)
Definition: array.h:273
Datum hstore_from_arrays ( PG_FUNCTION_ARGS  )

Definition at line 525 of file hstore_io.c.

References ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, Assert, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, NULL, palloc(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_RETURN_NULL, PG_RETURN_POINTER, TEXTOID, Pairs::val, Pairs::vallen, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

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

Definition at line 755 of file hstore_io.c.

References Assert, tupleDesc::attrs, ColumnIOData::column_type, RecordIOData::columns, fmgr_info_cxt(), FmgrInfo::fn_mcxt, get_fn_expr_argtype(), getTypeOutputInfo(), heap_deform_tuple(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, InvalidOid, Pairs::isnull, ItemPointerSetInvalid, Pairs::key, Pairs::keylen, lookup_rowtype_tupdesc(), MaxTupleAttributeNumber, MemoryContextAlloc(), MemSet, NameStr, tupleDesc::natts, RecordIOData::ncolumns, Pairs::needfree, NULL, offsetof, OutputFunctionCall(), palloc(), PG_ARGISNULL, 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, ColumnIOData::typiofunc, Pairs::val, Pairs::vallen, value, and values.

756 {
757  HeapTupleHeader rec;
758  int32 buflen;
759  HStore *out;
760  Pairs *pairs;
761  Oid tupType;
762  int32 tupTypmod;
763  TupleDesc tupdesc;
764  HeapTupleData tuple;
765  RecordIOData *my_extra;
766  int ncolumns;
767  int i,
768  j;
769  Datum *values;
770  bool *nulls;
771 
772  if (PG_ARGISNULL(0))
773  {
774  Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
775 
776  /*
777  * have no tuple to look at, so the only source of type info is the
778  * argtype. The lookup_rowtype_tupdesc call below will error out if we
779  * don't have a known composite type oid here.
780  */
781  tupType = argtype;
782  tupTypmod = -1;
783 
784  rec = NULL;
785  }
786  else
787  {
788  rec = PG_GETARG_HEAPTUPLEHEADER(0);
789 
790  /* Extract type info from the tuple itself */
791  tupType = HeapTupleHeaderGetTypeId(rec);
792  tupTypmod = HeapTupleHeaderGetTypMod(rec);
793  }
794 
795  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
796  ncolumns = tupdesc->natts;
797 
798  /*
799  * We arrange to look up the needed I/O info just once per series of
800  * calls, assuming the record type doesn't change underneath us.
801  */
802  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
803  if (my_extra == NULL ||
804  my_extra->ncolumns != ncolumns)
805  {
806  fcinfo->flinfo->fn_extra =
807  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
808  offsetof(RecordIOData, columns) +
809  ncolumns * sizeof(ColumnIOData));
810  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
811  my_extra->record_type = InvalidOid;
812  my_extra->record_typmod = 0;
813  }
814 
815  if (my_extra->record_type != tupType ||
816  my_extra->record_typmod != tupTypmod)
817  {
818  MemSet(my_extra, 0,
819  offsetof(RecordIOData, columns) +
820  ncolumns * sizeof(ColumnIOData));
821  my_extra->record_type = tupType;
822  my_extra->record_typmod = tupTypmod;
823  my_extra->ncolumns = ncolumns;
824  }
825 
826  Assert(ncolumns <= MaxTupleAttributeNumber); /* thus, no overflow */
827  pairs = palloc(ncolumns * sizeof(Pairs));
828 
829  if (rec)
830  {
831  /* Build a temporary HeapTuple control structure */
833  ItemPointerSetInvalid(&(tuple.t_self));
834  tuple.t_tableOid = InvalidOid;
835  tuple.t_data = rec;
836 
837  values = (Datum *) palloc(ncolumns * sizeof(Datum));
838  nulls = (bool *) palloc(ncolumns * sizeof(bool));
839 
840  /* Break down the tuple into fields */
841  heap_deform_tuple(&tuple, tupdesc, values, nulls);
842  }
843  else
844  {
845  values = NULL;
846  nulls = NULL;
847  }
848 
849  for (i = 0, j = 0; i < ncolumns; ++i)
850  {
851  ColumnIOData *column_info = &my_extra->columns[i];
852  Oid column_type = tupdesc->attrs[i]->atttypid;
853  char *value;
854 
855  /* Ignore dropped columns in datatype */
856  if (tupdesc->attrs[i]->attisdropped)
857  continue;
858 
859  pairs[j].key = NameStr(tupdesc->attrs[i]->attname);
860  pairs[j].keylen = hstoreCheckKeyLen(strlen(NameStr(tupdesc->attrs[i]->attname)));
861 
862  if (!nulls || nulls[i])
863  {
864  pairs[j].val = NULL;
865  pairs[j].vallen = 4;
866  pairs[j].isnull = true;
867  pairs[j].needfree = false;
868  ++j;
869  continue;
870  }
871 
872  /*
873  * Convert the column value to text
874  */
875  if (column_info->column_type != column_type)
876  {
877  bool typIsVarlena;
878 
879  getTypeOutputInfo(column_type,
880  &column_info->typiofunc,
881  &typIsVarlena);
882  fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
883  fcinfo->flinfo->fn_mcxt);
884  column_info->column_type = column_type;
885  }
886 
887  value = OutputFunctionCall(&column_info->proc, values[i]);
888 
889  pairs[j].val = value;
890  pairs[j].vallen = hstoreCheckValLen(strlen(value));
891  pairs[j].isnull = false;
892  pairs[j].needfree = false;
893  ++j;
894  }
895 
896  ncolumns = hstoreUniquePairs(pairs, j, &buflen);
897 
898  out = hstorePairs(pairs, ncolumns, buflen);
899 
900  ReleaseTupleDesc(tupdesc);
901 
902  PG_RETURN_POINTER(out);
903 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
static struct @76 value
FmgrInfo proc
Definition: hstore_io.c:742
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2600
MemoryContext fn_mcxt
Definition: fmgr.h:62
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1245
#define MaxTupleAttributeNumber
Definition: htup_details.h:33
Oid record_type
Definition: hstore_io.c:747
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:364
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define MemSet(start, val, len)
Definition: c.h:852
size_t vallen
Definition: hstore.h:166
#define PG_GETARG_HEAPTUPLEHEADER(n)
Definition: fmgr.h:275
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
bool needfree
Definition: hstore.h:168
int32 record_typmod
Definition: hstore_io.c:748
signed int int32
Definition: c.h:253
char * val
Definition: hstore.h:164
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1926
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:455
char * key
Definition: hstore.h:163
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:2220
ItemPointerData t_self
Definition: htup.h:65
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:375
uint32 t_len
Definition: htup.h:64
Oid t_tableOid
Definition: htup.h:66
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]
Definition: hstore_io.c:750
uintptr_t Datum
Definition: postgres.h:374
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:312
#define InvalidOid
Definition: postgres_ext.h:36
size_t keylen
Definition: hstore.h:165
#define PG_ARGISNULL(n)
Definition: fmgr.h:166
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
bool isnull
Definition: hstore.h:167
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:935
static Datum values[MAXATTR]
Definition: bootstrap.c:162
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:354
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:131
void * palloc(Size size)
Definition: mcxt.c:891
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
int i
#define NameStr(name)
Definition: c.h:494
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:107
Definition: hstore.h:161
#define offsetof(type, field)
Definition: c.h:550
Oid column_type
Definition: hstore_io.c:739
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
Datum hstore_from_text ( PG_FUNCTION_ARGS  )

Definition at line 489 of file hstore_io.c.

References hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), Pairs::isnull, Pairs::key, Pairs::keylen, Pairs::needfree, NULL, PG_ARGISNULL, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_POINTER, Pairs::val, val, Pairs::vallen, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

490 {
491  text *key;
492  text *val = NULL;
493  Pairs p;
494  HStore *out;
495 
496  if (PG_ARGISNULL(0))
497  PG_RETURN_NULL();
498 
499  p.needfree = false;
500  key = PG_GETARG_TEXT_PP(0);
501  p.key = VARDATA_ANY(key);
503 
504  if (PG_ARGISNULL(1))
505  {
506  p.vallen = 0;
507  p.isnull = true;
508  }
509  else
510  {
511  val = PG_GETARG_TEXT_PP(1);
512  p.val = VARDATA_ANY(val);
514  p.isnull = false;
515  }
516 
517  out = hstorePairs(&p, 1, p.keylen + p.vallen);
518 
519  PG_RETURN_POINTER(out);
520 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:349
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:364
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:270
char * key
Definition: hstore.h:163
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:375
size_t keylen
Definition: hstore.h:165
#define PG_ARGISNULL(n)
Definition: fmgr.h:166
#define NULL
Definition: c.h:226
bool isnull
Definition: hstore.h:167
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:354
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:342
Definition: c.h:434
Definition: hstore.h:161
long val
Definition: informix.c:689
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum hstore_in ( PG_FUNCTION_ARGS  )

Definition at line 406 of file hstore_io.c.

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

407 {
408  HSParser state;
409  int32 buflen;
410  HStore *out;
411 
412  state.begin = PG_GETARG_CSTRING(0);
413 
414  parse_hstore(&state);
415 
416  state.pcur = hstoreUniquePairs(state.pairs, state.pcur, &buflen);
417 
418  out = hstorePairs(state.pairs, state.pcur, buflen);
419 
420  PG_RETURN_POINTER(out);
421 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
signed int int32
Definition: c.h:253
static void parse_hstore(HSParser *state)
Definition: hstore_io.c:183
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:375
int pcur
Definition: hstore_io.c:38
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:312
Definition: regguts.h:298
Pairs * pairs
Definition: hstore_io.c:37
char * begin
Definition: hstore_io.c:31
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:233
Datum hstore_out ( PG_FUNCTION_ARGS  )

Definition at line 1120 of file hstore_io.c.

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

1121 {
1122  HStore *in = PG_GETARG_HS(0);
1123  int buflen,
1124  i;
1125  int count = HS_COUNT(in);
1126  char *out,
1127  *ptr;
1128  char *base = STRPTR(in);
1129  HEntry *entries = ARRPTR(in);
1130 
1131  if (count == 0)
1133 
1134  buflen = 0;
1135 
1136  /*
1137  * this loop overestimates due to pessimistic assumptions about escaping,
1138  * so very large hstore values can't be output. this could be fixed, but
1139  * many other data types probably have the same issue. This replaced code
1140  * that used the original varlena size for calculations, which was wrong
1141  * in some subtle ways.
1142  */
1143 
1144  for (i = 0; i < count; i++)
1145  {
1146  /* include "" and => and comma-space */
1147  buflen += 6 + 2 * HSTORE_KEYLEN(entries, i);
1148  /* include "" only if nonnull */
1149  buflen += 2 + (HSTORE_VALISNULL(entries, i)
1150  ? 2
1151  : 2 * HSTORE_VALLEN(entries, i));
1152  }
1153 
1154  out = ptr = palloc(buflen);
1155 
1156  for (i = 0; i < count; i++)
1157  {
1158  *ptr++ = '"';
1159  ptr = cpw(ptr, HSTORE_KEY(entries, base, i), HSTORE_KEYLEN(entries, i));
1160  *ptr++ = '"';
1161  *ptr++ = '=';
1162  *ptr++ = '>';
1163  if (HSTORE_VALISNULL(entries, i))
1164  {
1165  *ptr++ = 'N';
1166  *ptr++ = 'U';
1167  *ptr++ = 'L';
1168  *ptr++ = 'L';
1169  }
1170  else
1171  {
1172  *ptr++ = '"';
1173  ptr = cpw(ptr, HSTORE_VAL(entries, base, i), HSTORE_VALLEN(entries, i));
1174  *ptr++ = '"';
1175  }
1176 
1177  if (i + 1 != count)
1178  {
1179  *ptr++ = ',';
1180  *ptr++ = ' ';
1181  }
1182  }
1183  *ptr = '\0';
1184 
1185  PG_RETURN_CSTRING(out);
1186 }
Definition: hstore.h:44
char * pstrdup(const char *in)
Definition: mcxt.c:1165
#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:1105
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:306
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * palloc(Size size)
Definition: mcxt.c:891
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:26
HSTORE_POLLUTE ( hstore_from_text  ,
tconvert   
)
Datum hstore_populate_record ( PG_FUNCTION_ARGS  )

Definition at line 908 of file hstore_io.c.

References ARRPTR, tupleDesc::attrs, ColumnIOData::column_type, RecordIOData::columns, 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(), MemoryContextAlloc(), MemSet, NameStr, tupleDesc::natts, RecordIOData::ncolumns, NULL, offsetof, palloc(), PG_ARGISNULL, PG_GETARG_HEAPTUPLEHEADER, PG_GETARG_HS, 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, type_is_rowtype(), ColumnIOData::typiofunc, ColumnIOData::typioparam, value, and values.

909 {
910  Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
911  HStore *hs;
912  HEntry *entries;
913  char *ptr;
914  HeapTupleHeader rec;
915  Oid tupType;
916  int32 tupTypmod;
917  TupleDesc tupdesc;
918  HeapTupleData tuple;
919  HeapTuple rettuple;
920  RecordIOData *my_extra;
921  int ncolumns;
922  int i;
923  Datum *values;
924  bool *nulls;
925 
926  if (!type_is_rowtype(argtype))
927  ereport(ERROR,
928  (errcode(ERRCODE_DATATYPE_MISMATCH),
929  errmsg("first argument must be a rowtype")));
930 
931  if (PG_ARGISNULL(0))
932  {
933  if (PG_ARGISNULL(1))
934  PG_RETURN_NULL();
935 
936  rec = NULL;
937 
938  /*
939  * have no tuple to look at, so the only source of type info is the
940  * argtype. The lookup_rowtype_tupdesc call below will error out if we
941  * don't have a known composite type oid here.
942  */
943  tupType = argtype;
944  tupTypmod = -1;
945  }
946  else
947  {
948  rec = PG_GETARG_HEAPTUPLEHEADER(0);
949 
950  if (PG_ARGISNULL(1))
951  PG_RETURN_POINTER(rec);
952 
953  /* Extract type info from the tuple itself */
954  tupType = HeapTupleHeaderGetTypeId(rec);
955  tupTypmod = HeapTupleHeaderGetTypMod(rec);
956  }
957 
958  hs = PG_GETARG_HS(1);
959  entries = ARRPTR(hs);
960  ptr = STRPTR(hs);
961 
962  /*
963  * if the input hstore is empty, we can only skip the rest if we were
964  * passed in a non-null record, since otherwise there may be issues with
965  * domain nulls.
966  */
967 
968  if (HS_COUNT(hs) == 0 && rec)
969  PG_RETURN_POINTER(rec);
970 
971  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
972  ncolumns = tupdesc->natts;
973 
974  if (rec)
975  {
976  /* Build a temporary HeapTuple control structure */
978  ItemPointerSetInvalid(&(tuple.t_self));
979  tuple.t_tableOid = InvalidOid;
980  tuple.t_data = rec;
981  }
982 
983  /*
984  * We arrange to look up the needed I/O info just once per series of
985  * calls, assuming the record type doesn't change underneath us.
986  */
987  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
988  if (my_extra == NULL ||
989  my_extra->ncolumns != ncolumns)
990  {
991  fcinfo->flinfo->fn_extra =
992  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
993  offsetof(RecordIOData, columns) +
994  ncolumns * sizeof(ColumnIOData));
995  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
996  my_extra->record_type = InvalidOid;
997  my_extra->record_typmod = 0;
998  }
999 
1000  if (my_extra->record_type != tupType ||
1001  my_extra->record_typmod != tupTypmod)
1002  {
1003  MemSet(my_extra, 0,
1004  offsetof(RecordIOData, columns) +
1005  ncolumns * sizeof(ColumnIOData));
1006  my_extra->record_type = tupType;
1007  my_extra->record_typmod = tupTypmod;
1008  my_extra->ncolumns = ncolumns;
1009  }
1010 
1011  values = (Datum *) palloc(ncolumns * sizeof(Datum));
1012  nulls = (bool *) palloc(ncolumns * sizeof(bool));
1013 
1014  if (rec)
1015  {
1016  /* Break down the tuple into fields */
1017  heap_deform_tuple(&tuple, tupdesc, values, nulls);
1018  }
1019  else
1020  {
1021  for (i = 0; i < ncolumns; ++i)
1022  {
1023  values[i] = (Datum) 0;
1024  nulls[i] = true;
1025  }
1026  }
1027 
1028  for (i = 0; i < ncolumns; ++i)
1029  {
1030  ColumnIOData *column_info = &my_extra->columns[i];
1031  Oid column_type = tupdesc->attrs[i]->atttypid;
1032  char *value;
1033  int idx;
1034  int vallen;
1035 
1036  /* Ignore dropped columns in datatype */
1037  if (tupdesc->attrs[i]->attisdropped)
1038  {
1039  nulls[i] = true;
1040  continue;
1041  }
1042 
1043  idx = hstoreFindKey(hs, 0,
1044  NameStr(tupdesc->attrs[i]->attname),
1045  strlen(NameStr(tupdesc->attrs[i]->attname)));
1046 
1047  /*
1048  * we can't just skip here if the key wasn't found since we might have
1049  * a domain to deal with. If we were passed in a non-null record
1050  * datum, we assume that the existing values are valid (if they're
1051  * not, then it's not our fault), but if we were passed in a null,
1052  * then every field which we don't populate needs to be run through
1053  * the input function just in case it's a domain type.
1054  */
1055  if (idx < 0 && rec)
1056  continue;
1057 
1058  /*
1059  * Prepare to convert the column value from text
1060  */
1061  if (column_info->column_type != column_type)
1062  {
1063  getTypeInputInfo(column_type,
1064  &column_info->typiofunc,
1065  &column_info->typioparam);
1066  fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
1067  fcinfo->flinfo->fn_mcxt);
1068  column_info->column_type = column_type;
1069  }
1070 
1071  if (idx < 0 || HSTORE_VALISNULL(entries, idx))
1072  {
1073  /*
1074  * need InputFunctionCall to happen even for nulls, so that domain
1075  * checks are done
1076  */
1077  values[i] = InputFunctionCall(&column_info->proc, NULL,
1078  column_info->typioparam,
1079  tupdesc->attrs[i]->atttypmod);
1080  nulls[i] = true;
1081  }
1082  else
1083  {
1084  vallen = HSTORE_VALLEN(entries, idx);
1085  value = palloc(1 + vallen);
1086  memcpy(value, HSTORE_VAL(entries, ptr, idx), vallen);
1087  value[vallen] = 0;
1088 
1089  values[i] = InputFunctionCall(&column_info->proc, value,
1090  column_info->typioparam,
1091  tupdesc->attrs[i]->atttypmod);
1092  nulls[i] = false;
1093  }
1094  }
1095 
1096  rettuple = heap_form_tuple(tupdesc, values, nulls);
1097 
1098  ReleaseTupleDesc(tupdesc);
1099 
1101 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
static struct @76 value
FmgrInfo proc
Definition: hstore_io.c:742
MemoryContext fn_mcxt
Definition: fmgr.h:62
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1245
Oid record_type
Definition: hstore_io.c:747
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:852
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:264
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define PG_GETARG_HEAPTUPLEHEADER(n)
Definition: fmgr.h:275
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
int32 record_typmod
Definition: hstore_io.c:748
signed int int32
Definition: c.h:253
HeapTupleHeader t_data
Definition: htup.h:67
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:455
#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:37
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:2220
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
Oid t_tableOid
Definition: htup.h:66
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2372
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2567
#define ereport(elevel, rest)
Definition: elog.h:122
ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]
Definition: hstore_io.c:750
uintptr_t Datum
Definition: postgres.h:374
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:445
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1882
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_ARGISNULL(n)
Definition: fmgr.h:166
#define NULL
Definition: c.h:226
Definition: hstore.h:18
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
Oid typioparam
Definition: hstore_io.c:741
#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:935
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define ItemPointerSetInvalid(pointer)
Definition: itemptr.h:131
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
#define STRPTR(x)
Definition: hstore.h:76
int i
#define NameStr(name)
Definition: c.h:494
#define ARRPTR(x)
Definition: cube.c:26
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:107
#define PG_RETURN_NULL()
Definition: fmgr.h:289
#define offsetof(type, field)
Definition: c.h:550
Oid column_type
Definition: hstore_io.c:739
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:439
Datum hstore_recv ( PG_FUNCTION_ARGS  )

Definition at line 426 of file hstore_io.c.

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

427 {
428  int32 buflen;
429  HStore *out;
430  Pairs *pairs;
431  int32 i;
432  int32 pcount;
434 
435  pcount = pq_getmsgint(buf, 4);
436 
437  if (pcount == 0)
438  {
439  out = hstorePairs(NULL, 0, 0);
440  PG_RETURN_POINTER(out);
441  }
442 
443  if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
444  ereport(ERROR,
445  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
446  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
447  pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
448  pairs = palloc(pcount * sizeof(Pairs));
449 
450  for (i = 0; i < pcount; ++i)
451  {
452  int rawlen = pq_getmsgint(buf, 4);
453  int len;
454 
455  if (rawlen < 0)
456  ereport(ERROR,
457  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
458  errmsg("null value not allowed for hstore key")));
459 
460  pairs[i].key = pq_getmsgtext(buf, rawlen, &len);
461  pairs[i].keylen = hstoreCheckKeyLen(len);
462  pairs[i].needfree = true;
463 
464  rawlen = pq_getmsgint(buf, 4);
465  if (rawlen < 0)
466  {
467  pairs[i].val = NULL;
468  pairs[i].vallen = 0;
469  pairs[i].isnull = true;
470  }
471  else
472  {
473  pairs[i].val = pq_getmsgtext(buf, rawlen, &len);
474  pairs[i].vallen = hstoreCheckValLen(len);
475  pairs[i].isnull = false;
476  }
477  }
478 
479  pcount = hstoreUniquePairs(pairs, pcount, &buflen);
480 
481  out = hstorePairs(pairs, pcount, buflen);
482 
483  PG_RETURN_POINTER(out);
484 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
StringInfoData * StringInfo
Definition: stringinfo.h:46
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:364
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
signed int int32
Definition: c.h:253
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:375
static char * buf
Definition: pg_test_fsync.c:65
#define ereport(elevel, rest)
Definition: elog.h:122
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:588
#define MaxAllocSize
Definition: memutils.h:40
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:312
size_t keylen
Definition: hstore.h:165
#define NULL
Definition: c.h:226
bool isnull
Definition: hstore.h:167
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:354
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:448
Definition: hstore.h:161
Datum hstore_send ( PG_FUNCTION_ARGS  )

Definition at line 1191 of file hstore_io.c.

References ARRPTR, buf, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, PG_GETARG_HS, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint(), pq_sendtext(), and STRPTR.

1192 {
1193  HStore *in = PG_GETARG_HS(0);
1194  int i;
1195  int count = HS_COUNT(in);
1196  char *base = STRPTR(in);
1197  HEntry *entries = ARRPTR(in);
1199 
1200  pq_begintypsend(&buf);
1201 
1202  pq_sendint(&buf, count, 4);
1203 
1204  for (i = 0; i < count; i++)
1205  {
1206  int32 keylen = HSTORE_KEYLEN(entries, i);
1207 
1208  pq_sendint(&buf, keylen, 4);
1209  pq_sendtext(&buf, HSTORE_KEY(entries, base, i), keylen);
1210  if (HSTORE_VALISNULL(entries, i))
1211  {
1212  pq_sendint(&buf, -1, 4);
1213  }
1214  else
1215  {
1216  int32 vallen = HSTORE_VALLEN(entries, i);
1217 
1218  pq_sendint(&buf, vallen, 4);
1219  pq_sendtext(&buf, HSTORE_VAL(entries, base, i), vallen);
1220  }
1221  }
1222 
1224 }
Definition: hstore.h:44
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:163
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:313
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
signed int int32
Definition: c.h:253
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
static char * buf
Definition: pg_test_fsync.c:65
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void pq_sendint(StringInfo buf, int i, int b)
Definition: pqformat.c:236
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:26
Datum hstore_to_json ( PG_FUNCTION_ARGS  )

Definition at line 1292 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_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), PG_GETARG_HS, PG_RETURN_TEXT_P, resetStringInfo(), and STRPTR.

1293 {
1294  HStore *in = PG_GETARG_HS(0);
1295  int i;
1296  int count = HS_COUNT(in);
1297  char *base = STRPTR(in);
1298  HEntry *entries = ARRPTR(in);
1299  StringInfoData tmp,
1300  dst;
1301 
1302  if (count == 0)
1304 
1305  initStringInfo(&tmp);
1306  initStringInfo(&dst);
1307 
1308  appendStringInfoChar(&dst, '{');
1309 
1310  for (i = 0; i < count; i++)
1311  {
1312  resetStringInfo(&tmp);
1313  appendBinaryStringInfo(&tmp, HSTORE_KEY(entries, base, i),
1314  HSTORE_KEYLEN(entries, i));
1315  escape_json(&dst, tmp.data);
1316  appendStringInfoString(&dst, ": ");
1317  if (HSTORE_VALISNULL(entries, i))
1318  appendStringInfoString(&dst, "null");
1319  else
1320  {
1321  resetStringInfo(&tmp);
1322  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1323  HSTORE_VALLEN(entries, i));
1324  escape_json(&dst, tmp.data);
1325  }
1326 
1327  if (i + 1 != count)
1328  appendStringInfoString(&dst, ", ");
1329  }
1330  appendStringInfoChar(&dst, '}');
1331 
1333 }
Definition: hstore.h:44
void escape_json(StringInfo buf, const char *str)
Definition: json.c:2432
#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:189
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:163
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:94
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:314
text * cstring_to_text(const char *s)
Definition: varlena.c:151
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:26
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
Datum hstore_to_json_loose ( PG_FUNCTION_ARGS  )

Definition at line 1237 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_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), IsValidJsonNumber(), StringInfoData::len, PG_GETARG_HS, PG_RETURN_TEXT_P, resetStringInfo(), and STRPTR.

1238 {
1239  HStore *in = PG_GETARG_HS(0);
1240  int i;
1241  int count = HS_COUNT(in);
1242  char *base = STRPTR(in);
1243  HEntry *entries = ARRPTR(in);
1244  StringInfoData tmp,
1245  dst;
1246 
1247  if (count == 0)
1249 
1250  initStringInfo(&tmp);
1251  initStringInfo(&dst);
1252 
1253  appendStringInfoChar(&dst, '{');
1254 
1255  for (i = 0; i < count; i++)
1256  {
1257  resetStringInfo(&tmp);
1258  appendBinaryStringInfo(&tmp, HSTORE_KEY(entries, base, i),
1259  HSTORE_KEYLEN(entries, i));
1260  escape_json(&dst, tmp.data);
1261  appendStringInfoString(&dst, ": ");
1262  if (HSTORE_VALISNULL(entries, i))
1263  appendStringInfoString(&dst, "null");
1264  /* guess that values of 't' or 'f' are booleans */
1265  else if (HSTORE_VALLEN(entries, i) == 1 &&
1266  *(HSTORE_VAL(entries, base, i)) == 't')
1267  appendStringInfoString(&dst, "true");
1268  else if (HSTORE_VALLEN(entries, i) == 1 &&
1269  *(HSTORE_VAL(entries, base, i)) == 'f')
1270  appendStringInfoString(&dst, "false");
1271  else
1272  {
1273  resetStringInfo(&tmp);
1274  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1275  HSTORE_VALLEN(entries, i));
1276  if (IsValidJsonNumber(tmp.data, tmp.len))
1277  appendBinaryStringInfo(&dst, tmp.data, tmp.len);
1278  else
1279  escape_json(&dst, tmp.data);
1280  }
1281 
1282  if (i + 1 != count)
1283  appendStringInfoString(&dst, ", ");
1284  }
1285  appendStringInfoChar(&dst, '}');
1286 
1288 }
Definition: hstore.h:44
void escape_json(StringInfo buf, const char *str)
Definition: json.c:2432
#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:192
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:163
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:94
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:314
text * cstring_to_text(const char *s)
Definition: varlena.c:151
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:26
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
Datum hstore_to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1337 of file hstore_io.c.

References ARRPTR, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, jbvNull, jbvString, JsonbValueToJsonb(), NULL, PG_GETARG_HS, PG_RETURN_POINTER, pushJsonbValue(), STRPTR, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

1338 {
1339  HStore *in = PG_GETARG_HS(0);
1340  int i;
1341  int count = HS_COUNT(in);
1342  char *base = STRPTR(in);
1343  HEntry *entries = ARRPTR(in);
1345  JsonbValue *res;
1346 
1347  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1348 
1349  for (i = 0; i < count; i++)
1350  {
1351  JsonbValue key,
1352  val;
1353 
1354  key.type = jbvString;
1355  key.val.string.len = HSTORE_KEYLEN(entries, i);
1356  key.val.string.val = HSTORE_KEY(entries, base, i);
1357 
1358  (void) pushJsonbValue(&state, WJB_KEY, &key);
1359 
1360  if (HSTORE_VALISNULL(entries, i))
1361  {
1362  val.type = jbvNull;
1363  }
1364  else
1365  {
1366  val.type = jbvString;
1367  val.val.string.len = HSTORE_VALLEN(entries, i);
1368  val.val.string.val = HSTORE_VAL(entries, base, i);
1369  }
1370  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1371  }
1372 
1373  res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
1374 
1376 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:79
char * val
Definition: jsonb.h:259
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
Definition: jsonb.h:231
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:517
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
Definition: jsonb.h:23
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define NULL
Definition: c.h:226
Definition: regguts.h:298
Definition: hstore.h:18
enum jbvType type
Definition: jsonb.h:250
#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:26
long val
Definition: informix.c:689
Datum hstore_to_jsonb_loose ( PG_FUNCTION_ARGS  )

Definition at line 1380 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(), IsValidJsonNumber(), jbvBool, jbvNull, jbvNumeric, jbvString, JsonbValueToJsonb(), StringInfoData::len, NULL, numeric_in(), PG_GETARG_HS, PG_RETURN_POINTER, pushJsonbValue(), resetStringInfo(), STRPTR, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

1381 {
1382  HStore *in = PG_GETARG_HS(0);
1383  int i;
1384  int count = HS_COUNT(in);
1385  char *base = STRPTR(in);
1386  HEntry *entries = ARRPTR(in);
1388  JsonbValue *res;
1389  StringInfoData tmp;
1390 
1391  initStringInfo(&tmp);
1392 
1393  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1394 
1395  for (i = 0; i < count; i++)
1396  {
1397  JsonbValue key,
1398  val;
1399 
1400  key.type = jbvString;
1401  key.val.string.len = HSTORE_KEYLEN(entries, i);
1402  key.val.string.val = HSTORE_KEY(entries, base, i);
1403 
1404  (void) pushJsonbValue(&state, WJB_KEY, &key);
1405 
1406  if (HSTORE_VALISNULL(entries, i))
1407  {
1408  val.type = jbvNull;
1409  }
1410  /* guess that values of 't' or 'f' are booleans */
1411  else if (HSTORE_VALLEN(entries, i) == 1 &&
1412  *(HSTORE_VAL(entries, base, i)) == 't')
1413  {
1414  val.type = jbvBool;
1415  val.val.boolean = true;
1416  }
1417  else if (HSTORE_VALLEN(entries, i) == 1 &&
1418  *(HSTORE_VAL(entries, base, i)) == 'f')
1419  {
1420  val.type = jbvBool;
1421  val.val.boolean = false;
1422  }
1423  else
1424  {
1425  resetStringInfo(&tmp);
1426  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1427  HSTORE_VALLEN(entries, i));
1428  if (IsValidJsonNumber(tmp.data, tmp.len))
1429  {
1430  val.type = jbvNumeric;
1431  val.val.numeric = DatumGetNumeric(
1433  CStringGetDatum(tmp.data), 0, -1));
1434  }
1435  else
1436  {
1437  val.type = jbvString;
1438  val.val.string.len = HSTORE_VALLEN(entries, i);
1439  val.val.string.val = HSTORE_VAL(entries, base, i);
1440  }
1441  }
1442  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1443  }
1444 
1445  res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
1446 
1448 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
Definition: hstore.h:44
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:79
char * val
Definition: jsonb.h:259
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
Definition: jsonb.h:234
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
Definition: jsonb.h:231
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:517
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
bool IsValidJsonNumber(const char *str, int len)
Definition: json.c:192
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_GETARG_HS(x)
Definition: hstore.h:154
#define CStringGetDatum(X)
Definition: postgres.h:586
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:94
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:559
Definition: jsonb.h:23
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:559
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define NULL
Definition: c.h:226
Definition: regguts.h:298
Definition: hstore.h:18
enum jbvType type
Definition: jsonb.h:250
#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:26
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:240
long val
Definition: informix.c:689
size_t hstoreCheckKeyLen ( size_t  len)

Definition at line 354 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().

355 {
356  if (len > HSTORE_MAX_KEY_LEN)
357  ereport(ERROR,
358  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
359  errmsg("string too long for hstore key")));
360  return len;
361 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define HSTORE_MAX_KEY_LEN
Definition: hstore.h:41
int errmsg(const char *fmt,...)
Definition: elog.c:797
size_t hstoreCheckValLen ( size_t  len)

Definition at line 364 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().

365 {
366  if (len > HSTORE_MAX_VALUE_LEN)
367  ereport(ERROR,
368  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
369  errmsg("string too long for hstore value")));
370  return len;
371 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HSTORE_MAX_VALUE_LEN
Definition: hstore.h:42
HStore* hstorePairs ( Pairs pairs,
int32  pcount,
int32  buflen 
)

Definition at line 375 of file hstore_io.c.

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

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

376 {
377  HStore *out;
378  HEntry *entry;
379  char *ptr;
380  char *buf;
381  int32 len;
382  int32 i;
383 
384  len = CALCDATASIZE(pcount, buflen);
385  out = palloc(len);
386  SET_VARSIZE(out, len);
387  HS_SETCOUNT(out, pcount);
388 
389  if (pcount == 0)
390  return out;
391 
392  entry = ARRPTR(out);
393  buf = ptr = STRPTR(out);
394 
395  for (i = 0; i < pcount; i++)
396  HS_ADDITEM(entry, buf, ptr, pairs[i]);
397 
398  HS_FINALIZE(out, pcount, buf, ptr);
399 
400  return out;
401 }
Definition: hstore.h:44
signed int int32
Definition: c.h:253
static char * buf
Definition: pg_test_fsync.c:65
#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:891
#define STRPTR(x)
Definition: hstore.h:76
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
#define ARRPTR(x)
Definition: cube.c:26
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
int hstoreUniquePairs ( Pairs a,
int32  l,
int32 buflen 
)

Definition at line 312 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().

313 {
314  Pairs *ptr,
315  *res;
316 
317  *buflen = 0;
318  if (l < 2)
319  {
320  if (l == 1)
321  *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen);
322  return l;
323  }
324 
325  qsort((void *) a, l, sizeof(Pairs), comparePairs);
326  ptr = a + 1;
327  res = a;
328  while (ptr - a < l)
329  {
330  if (ptr->keylen == res->keylen &&
331  memcmp(ptr->key, res->key, res->keylen) == 0)
332  {
333  if (ptr->needfree)
334  {
335  pfree(ptr->key);
336  pfree(ptr->val);
337  }
338  }
339  else
340  {
341  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
342  res++;
343  memcpy(res, ptr, sizeof(Pairs));
344  }
345 
346  ptr++;
347  }
348 
349  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
350  return res + 1 - a;
351 }
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:992
static int comparePairs(const void *a, const void *b)
Definition: hstore_io.c:282
size_t keylen
Definition: hstore.h:165
bool isnull
Definition: hstore.h:167
#define qsort(a, b, c, d)
Definition: port.h:440
Definition: hstore.h:161
static void parse_hstore ( HSParser state)
static

Definition at line 183 of file hstore_io.c.

References HSParser::begin, HSParser::cur, elog, ERROR, get_val(), hstoreCheckKeyLen(), hstoreCheckValLen(), Pairs::isnull, Pairs::key, Pairs::keylen, Pairs::needfree, NULL, 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().

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

Variable Documentation

PG_MODULE_MAGIC

Definition at line 23 of file hstore_io.c.