PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
hstore_io.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "common/jsonapi.h"
#include "funcapi.h"
#include "hstore.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "nodes/miscnodes.h"
#include "parser/scansup.h"
#include "utils/builtins.h"
#include "utils/json.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 PRSSYNTAXERROR   return prssyntaxerror(state)
 
#define PRSEOF   return prseof(state)
 
#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

 PG_MODULE_MAGIC_EXT (.name="hstore",.version=PG_VERSION)
 
 HSTORE_POLLUTE (hstore_from_text, tconvert)
 
static bool hstoreCheckKeyLength (size_t len, HSParser *state)
 
static bool hstoreCheckValLength (size_t len, HSParser *state)
 
static bool prssyntaxerror (HSParser *state)
 
static bool prseof (HSParser *state)
 
static bool get_val (HSParser *state, bool ignoreeq, bool *escaped)
 
static bool 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)
 

Macro Definition Documentation

◆ GV_INESCVAL

#define GV_INESCVAL   2

Definition at line 91 of file hstore_io.c.

◆ GV_INVAL

#define GV_INVAL   1

Definition at line 90 of file hstore_io.c.

◆ GV_WAITESCESCIN

#define GV_WAITESCESCIN   4

Definition at line 93 of file hstore_io.c.

◆ GV_WAITESCIN

#define GV_WAITESCIN   3

Definition at line 92 of file hstore_io.c.

◆ GV_WAITVAL

#define GV_WAITVAL   0

Definition at line 89 of file hstore_io.c.

◆ PRSEOF

#define PRSEOF   return prseof(state)

Definition at line 76 of file hstore_io.c.

◆ PRSSYNTAXERROR

#define PRSSYNTAXERROR   return prssyntaxerror(state)

Definition at line 62 of file hstore_io.c.

◆ 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)
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2170
Definition: regguts.h:323

Definition at line 51 of file hstore_io.c.

◆ WDEL

#define WDEL   4

Definition at line 214 of file hstore_io.c.

◆ WEQ

#define WEQ   2

Definition at line 212 of file hstore_io.c.

◆ WGT

#define WGT   3

Definition at line 213 of file hstore_io.c.

◆ WKEY

#define WKEY   0

Definition at line 210 of file hstore_io.c.

◆ WVAL

#define WVAL   1

Definition at line 211 of file hstore_io.c.

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 329 of file hstore_io.c.

330{
331 const Pairs *pa = a;
332 const Pairs *pb = b;
333
334 if (pa->keylen == pb->keylen)
335 {
336 int res = memcmp(pa->key, pb->key, pa->keylen);
337
338 if (res)
339 return res;
340
341 /* guarantee that needfree will be later */
342 if (pb->needfree == pa->needfree)
343 return 0;
344 else if (pa->needfree)
345 return 1;
346 else
347 return -1;
348 }
349 return (pa->keylen > pb->keylen) ? 1 : -1;
350}
int b
Definition: isn.c:74
int a
Definition: isn.c:73
Definition: hstore.h:162
size_t keylen
Definition: hstore.h:165
char * key
Definition: hstore.h:163
bool needfree
Definition: hstore.h:168

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

Referenced by hstoreUniquePairs().

◆ cpw()

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

Definition at line 1210 of file hstore_io.c.

1211{
1212 char *ptr = src;
1213
1214 while (ptr - src < len)
1215 {
1216 if (*ptr == '"' || *ptr == '\\')
1217 *dst++ = '\\';
1218 *dst++ = *ptr++;
1219 }
1220 return dst;
1221}
const void size_t len

References len.

Referenced by hstore_out().

◆ get_val()

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

Definition at line 96 of file hstore_io.c.

97{
98 int st = GV_WAITVAL;
99
100 state->wordlen = 32;
101 state->cur = state->word = palloc(state->wordlen);
102 *escaped = false;
103
104 while (1)
105 {
106 if (st == GV_WAITVAL)
107 {
108 if (*(state->ptr) == '"')
109 {
110 *escaped = true;
111 st = GV_INESCVAL;
112 }
113 else if (*(state->ptr) == '\0')
114 {
115 return false;
116 }
117 else if (*(state->ptr) == '=' && !ignoreeq)
118 {
120 }
121 else if (*(state->ptr) == '\\')
122 {
123 st = GV_WAITESCIN;
124 }
125 else if (!scanner_isspace((unsigned char) *(state->ptr)))
126 {
127 *(state->cur) = *(state->ptr);
128 state->cur++;
129 st = GV_INVAL;
130 }
131 }
132 else if (st == GV_INVAL)
133 {
134 if (*(state->ptr) == '\\')
135 {
136 st = GV_WAITESCIN;
137 }
138 else if (*(state->ptr) == '=' && !ignoreeq)
139 {
140 state->ptr--;
141 return true;
142 }
143 else if (*(state->ptr) == ',' && ignoreeq)
144 {
145 state->ptr--;
146 return true;
147 }
148 else if (scanner_isspace((unsigned char) *(state->ptr)))
149 {
150 return true;
151 }
152 else if (*(state->ptr) == '\0')
153 {
154 state->ptr--;
155 return true;
156 }
157 else
158 {
160 *(state->cur) = *(state->ptr);
161 state->cur++;
162 }
163 }
164 else if (st == GV_INESCVAL)
165 {
166 if (*(state->ptr) == '\\')
167 {
168 st = GV_WAITESCESCIN;
169 }
170 else if (*(state->ptr) == '"')
171 {
172 return true;
173 }
174 else if (*(state->ptr) == '\0')
175 {
176 PRSEOF;
177 }
178 else
179 {
181 *(state->cur) = *(state->ptr);
182 state->cur++;
183 }
184 }
185 else if (st == GV_WAITESCIN)
186 {
187 if (*(state->ptr) == '\0')
188 PRSEOF;
190 *(state->cur) = *(state->ptr);
191 state->cur++;
192 st = GV_INVAL;
193 }
194 else if (st == GV_WAITESCESCIN)
195 {
196 if (*(state->ptr) == '\0')
197 PRSEOF;
199 *(state->cur) = *(state->ptr);
200 state->cur++;
201 st = GV_INESCVAL;
202 }
203 else
204 elog(ERROR, "unrecognized get_val state: %d", st);
205
206 state->ptr++;
207 }
208}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define PRSSYNTAXERROR
Definition: hstore_io.c:62
#define GV_INVAL
Definition: hstore_io.c:90
#define GV_WAITESCESCIN
Definition: hstore_io.c:93
#define GV_INESCVAL
Definition: hstore_io.c:91
#define RESIZEPRSBUF
Definition: hstore_io.c:51
#define PRSEOF
Definition: hstore_io.c:76
#define GV_WAITVAL
Definition: hstore_io.c:89
#define GV_WAITESCIN
Definition: hstore_io.c:92
void * palloc(Size size)
Definition: mcxt.c:1943
bool scanner_isspace(char ch)
Definition: scansup.c:117

References elog, ERROR, GV_INESCVAL, GV_INVAL, GV_WAITESCESCIN, GV_WAITESCIN, GV_WAITVAL, palloc(), PRSEOF, PRSSYNTAXERROR, RESIZEPRSBUF, and scanner_isspace().

Referenced by parse_hstore().

◆ hstore_from_array()

Datum hstore_from_array ( PG_FUNCTION_ARGS  )

Definition at line 718 of file hstore_io.c.

719{
720 ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
721 int ndims = ARR_NDIM(in_array);
722 int count;
723 int32 buflen;
724 HStore *out;
725 Pairs *pairs;
726 Datum *in_datums;
727 bool *in_nulls;
728 int in_count;
729 int i;
730
731 Assert(ARR_ELEMTYPE(in_array) == TEXTOID);
732
733 switch (ndims)
734 {
735 case 0:
736 out = hstorePairs(NULL, 0, 0);
738
739 case 1:
740 if ((ARR_DIMS(in_array)[0]) % 2)
742 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
743 errmsg("array must have even number of elements")));
744 break;
745
746 case 2:
747 if ((ARR_DIMS(in_array)[1]) != 2)
749 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
750 errmsg("array must have two columns")));
751 break;
752
753 default:
755 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
756 errmsg("wrong number of array subscripts")));
757 }
758
759 deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
760
761 count = in_count / 2;
762
763 /* see discussion in hstoreArrayToPairs() */
764 if (count > MaxAllocSize / sizeof(Pairs))
766 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
767 errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
768 count, (int) (MaxAllocSize / sizeof(Pairs)))));
769
770 pairs = palloc(count * sizeof(Pairs));
771
772 for (i = 0; i < count; ++i)
773 {
774 if (in_nulls[i * 2])
776 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
777 errmsg("null value not allowed for hstore key")));
778
779 if (in_nulls[i * 2 + 1])
780 {
781 pairs[i].key = VARDATA(in_datums[i * 2]);
782 pairs[i].val = NULL;
783 pairs[i].keylen =
784 hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
785 pairs[i].vallen = 4;
786 pairs[i].isnull = true;
787 pairs[i].needfree = false;
788 }
789 else
790 {
791 pairs[i].key = VARDATA(in_datums[i * 2]);
792 pairs[i].val = VARDATA(in_datums[i * 2 + 1]);
793 pairs[i].keylen =
794 hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
795 pairs[i].vallen =
796 hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ);
797 pairs[i].isnull = false;
798 pairs[i].needfree = false;
799 }
800 }
801
802 count = hstoreUniquePairs(pairs, count, &buflen);
803
804 out = hstorePairs(pairs, count, buflen);
805
807}
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3697
#define VARHDRSZ
Definition: c.h:663
int32_t int32
Definition: c.h:498
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereport(elevel,...)
Definition: elog.h:149
#define MaxAllocSize
Definition: fe_memutils.h:22
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
Assert(PointerIsAligned(start, uint64))
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:448
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:427
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:407
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:359
int i
Definition: isn.c:77
uintptr_t Datum
Definition: postgres.h:69
Definition: hstore.h:45
char * val
Definition: hstore.h:164
bool isnull
Definition: hstore.h:167
size_t vallen
Definition: hstore.h:166
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARSIZE(PTR)
Definition: varatt.h:279

References ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, Assert(), deconstruct_array_builtin(), 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.

◆ hstore_from_arrays()

Datum hstore_from_arrays ( PG_FUNCTION_ARGS  )

Definition at line 602 of file hstore_io.c.

603{
604 int32 buflen;
605 HStore *out;
606 Pairs *pairs;
607 Datum *key_datums;
608 bool *key_nulls;
609 int key_count;
610 Datum *value_datums;
611 bool *value_nulls;
612 int value_count;
613 ArrayType *key_array;
614 ArrayType *value_array;
615 int i;
616
617 if (PG_ARGISNULL(0))
619
620 key_array = PG_GETARG_ARRAYTYPE_P(0);
621
622 Assert(ARR_ELEMTYPE(key_array) == TEXTOID);
623
624 /*
625 * must check >1 rather than != 1 because empty arrays have 0 dimensions,
626 * not 1
627 */
628
629 if (ARR_NDIM(key_array) > 1)
631 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
632 errmsg("wrong number of array subscripts")));
633
634 deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
635
636 /* see discussion in hstoreArrayToPairs() */
637 if (key_count > MaxAllocSize / sizeof(Pairs))
639 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
640 errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
641 key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
642
643 /* value_array might be NULL */
644
645 if (PG_ARGISNULL(1))
646 {
647 value_array = NULL;
648 value_count = key_count;
649 value_datums = NULL;
650 value_nulls = NULL;
651 }
652 else
653 {
654 value_array = PG_GETARG_ARRAYTYPE_P(1);
655
656 Assert(ARR_ELEMTYPE(value_array) == TEXTOID);
657
658 if (ARR_NDIM(value_array) > 1)
660 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
661 errmsg("wrong number of array subscripts")));
662
663 if ((ARR_NDIM(key_array) > 0 || ARR_NDIM(value_array) > 0) &&
664 (ARR_NDIM(key_array) != ARR_NDIM(value_array) ||
665 ARR_DIMS(key_array)[0] != ARR_DIMS(value_array)[0] ||
666 ARR_LBOUND(key_array)[0] != ARR_LBOUND(value_array)[0]))
668 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
669 errmsg("arrays must have same bounds")));
670
671 deconstruct_array_builtin(value_array, TEXTOID, &value_datums, &value_nulls, &value_count);
672
673 Assert(key_count == value_count);
674 }
675
676 pairs = palloc(key_count * sizeof(Pairs));
677
678 for (i = 0; i < key_count; ++i)
679 {
680 if (key_nulls[i])
682 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
683 errmsg("null value not allowed for hstore key")));
684
685 if (!value_nulls || value_nulls[i])
686 {
687 pairs[i].key = VARDATA(key_datums[i]);
688 pairs[i].val = NULL;
689 pairs[i].keylen =
690 hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
691 pairs[i].vallen = 4;
692 pairs[i].isnull = true;
693 pairs[i].needfree = false;
694 }
695 else
696 {
697 pairs[i].key = VARDATA(key_datums[i]);
698 pairs[i].val = VARDATA(value_datums[i]);
699 pairs[i].keylen =
700 hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
701 pairs[i].vallen =
702 hstoreCheckValLen(VARSIZE(value_datums[i]) - VARHDRSZ);
703 pairs[i].isnull = false;
704 pairs[i].needfree = false;
705 }
706 }
707
708 key_count = hstoreUniquePairs(pairs, key_count, &buflen);
709
710 out = hstorePairs(pairs, key_count, buflen);
711
713}
#define ARR_LBOUND(a)
Definition: array.h:296
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345

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

◆ hstore_from_record()

Datum hstore_from_record ( PG_FUNCTION_ARGS  )

Definition at line 834 of file hstore_io.c.

835{
836 HeapTupleHeader rec;
837 int32 buflen;
838 HStore *out;
839 Pairs *pairs;
840 Oid tupType;
841 int32 tupTypmod;
842 TupleDesc tupdesc;
843 HeapTupleData tuple;
844 RecordIOData *my_extra;
845 int ncolumns;
846 int i,
847 j;
848 Datum *values;
849 bool *nulls;
850
851 if (PG_ARGISNULL(0))
852 {
853 Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
854
855 /*
856 * We have no tuple to look at, so the only source of type info is the
857 * argtype --- which might be domain over composite, but we don't care
858 * here, since we have no need to be concerned about domain
859 * constraints. The lookup_rowtype_tupdesc_domain call below will
860 * error out if we don't have a known composite type oid here.
861 */
862 tupType = argtype;
863 tupTypmod = -1;
864
865 rec = NULL;
866 }
867 else
868 {
870
871 /*
872 * Extract type info from the tuple itself -- this will work even for
873 * anonymous record types.
874 */
875 tupType = HeapTupleHeaderGetTypeId(rec);
876 tupTypmod = HeapTupleHeaderGetTypMod(rec);
877 }
878
879 tupdesc = lookup_rowtype_tupdesc_domain(tupType, tupTypmod, false);
880 ncolumns = tupdesc->natts;
881
882 /*
883 * We arrange to look up the needed I/O info just once per series of
884 * calls, assuming the record type doesn't change underneath us.
885 */
886 my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
887 if (my_extra == NULL ||
888 my_extra->ncolumns != ncolumns)
889 {
890 fcinfo->flinfo->fn_extra =
891 MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
892 offsetof(RecordIOData, columns) +
893 ncolumns * sizeof(ColumnIOData));
894 my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
895 my_extra->record_type = InvalidOid;
896 my_extra->record_typmod = 0;
897 }
898
899 if (my_extra->record_type != tupType ||
900 my_extra->record_typmod != tupTypmod)
901 {
902 MemSet(my_extra, 0,
903 offsetof(RecordIOData, columns) +
904 ncolumns * sizeof(ColumnIOData));
905 my_extra->record_type = tupType;
906 my_extra->record_typmod = tupTypmod;
907 my_extra->ncolumns = ncolumns;
908 }
909
910 Assert(ncolumns <= MaxTupleAttributeNumber); /* thus, no overflow */
911 pairs = palloc(ncolumns * sizeof(Pairs));
912
913 if (rec)
914 {
915 /* Build a temporary HeapTuple control structure */
918 tuple.t_tableOid = InvalidOid;
919 tuple.t_data = rec;
920
921 values = (Datum *) palloc(ncolumns * sizeof(Datum));
922 nulls = (bool *) palloc(ncolumns * sizeof(bool));
923
924 /* Break down the tuple into fields */
925 heap_deform_tuple(&tuple, tupdesc, values, nulls);
926 }
927 else
928 {
929 values = NULL;
930 nulls = NULL;
931 }
932
933 for (i = 0, j = 0; i < ncolumns; ++i)
934 {
935 ColumnIOData *column_info = &my_extra->columns[i];
936 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
937 Oid column_type = att->atttypid;
938 char *value;
939
940 /* Ignore dropped columns in datatype */
941 if (att->attisdropped)
942 continue;
943
944 pairs[j].key = NameStr(att->attname);
945 pairs[j].keylen = hstoreCheckKeyLen(strlen(NameStr(att->attname)));
946
947 if (!nulls || nulls[i])
948 {
949 pairs[j].val = NULL;
950 pairs[j].vallen = 4;
951 pairs[j].isnull = true;
952 pairs[j].needfree = false;
953 ++j;
954 continue;
955 }
956
957 /*
958 * Convert the column value to text
959 */
960 if (column_info->column_type != column_type)
961 {
962 bool typIsVarlena;
963
964 getTypeOutputInfo(column_type,
965 &column_info->typiofunc,
966 &typIsVarlena);
967 fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
968 fcinfo->flinfo->fn_mcxt);
969 column_info->column_type = column_type;
970 }
971
972 value = OutputFunctionCall(&column_info->proc, values[i]);
973
974 pairs[j].val = value;
975 pairs[j].vallen = hstoreCheckValLen(strlen(value));
976 pairs[j].isnull = false;
977 pairs[j].needfree = false;
978 ++j;
979 }
980
981 ncolumns = hstoreUniquePairs(pairs, j, &buflen);
982
983 out = hstorePairs(pairs, ncolumns, buflen);
984
985 ReleaseTupleDesc(tupdesc);
986
988}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define NameStr(name)
Definition: c.h:717
#define MemSet(start, val, len)
Definition: c.h:991
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1910
#define PG_GETARG_HEAPTUPLEHEADER(n)
Definition: fmgr.h:312
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1346
static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)
Definition: htup_details.h:516
#define MaxTupleAttributeNumber
Definition: htup_details.h:34
static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)
Definition: htup_details.h:492
static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)
Definition: htup_details.h:504
static struct @165 value
int j
Definition: isn.c:78
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:3047
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1260
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
FmgrInfo proc
Definition: hstore_io.c:819
Oid column_type
Definition: hstore_io.c:816
MemoryContext fn_mcxt
Definition: fmgr.h:65
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]
Definition: hstore_io.c:829
Oid record_type
Definition: hstore_io.c:824
int32 record_typmod
Definition: hstore_io.c:825
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:219
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition: typcache.c:1978

References Assert(), 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, if(), InvalidOid, Pairs::isnull, ItemPointerSetInvalid(), j, Pairs::key, Pairs::keylen, lookup_rowtype_tupdesc_domain(), MaxTupleAttributeNumber, MemoryContextAlloc(), MemSet, NameStr, TupleDescData::natts, RecordIOData::ncolumns, Pairs::needfree, 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, TupleDescAttr(), ColumnIOData::typiofunc, Pairs::val, Pairs::vallen, value, and values.

◆ hstore_from_text()

Datum hstore_from_text ( PG_FUNCTION_ARGS  )

Definition at line 566 of file hstore_io.c.

567{
568 text *key;
569 text *val = NULL;
570 Pairs p;
571 HStore *out;
572
573 if (PG_ARGISNULL(0))
575
576 p.needfree = false;
578 p.key = VARDATA_ANY(key);
580
581 if (PG_ARGISNULL(1))
582 {
583 p.vallen = 0;
584 p.isnull = true;
585 }
586 else
587 {
589 p.val = VARDATA_ANY(val);
591 p.isnull = false;
592 }
593
594 out = hstorePairs(&p, 1, p.keylen + p.vallen);
595
597}
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
long val
Definition: informix.c:689
Definition: c.h:658
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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

◆ hstore_in()

Datum hstore_in ( PG_FUNCTION_ARGS  )

Definition at line 479 of file hstore_io.c.

480{
481 char *str = PG_GETARG_CSTRING(0);
482 Node *escontext = fcinfo->context;
484 int32 buflen;
485 HStore *out;
486
487 state.begin = str;
488 state.escontext = escontext;
489
490 if (!parse_hstore(&state))
492
493 state.pcur = hstoreUniquePairs(state.pairs, state.pcur, &buflen);
494
495 out = hstorePairs(state.pairs, state.pcur, buflen);
496
498}
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
const char * str
static bool parse_hstore(HSParser *state)
Definition: hstore_io.c:218
Definition: nodes.h:135

References hstorePairs(), hstoreUniquePairs(), parse_hstore(), PG_GETARG_CSTRING, PG_RETURN_NULL, PG_RETURN_POINTER, and str.

◆ hstore_out()

Datum hstore_out ( PG_FUNCTION_ARGS  )

Definition at line 1225 of file hstore_io.c.

1226{
1227 HStore *in = PG_GETARG_HSTORE_P(0);
1228 int buflen,
1229 i;
1230 int count = HS_COUNT(in);
1231 char *out,
1232 *ptr;
1233 char *base = STRPTR(in);
1234 HEntry *entries = ARRPTR(in);
1235
1236 if (count == 0)
1238
1239 buflen = 0;
1240
1241 /*
1242 * this loop overestimates due to pessimistic assumptions about escaping,
1243 * so very large hstore values can't be output. this could be fixed, but
1244 * many other data types probably have the same issue. This replaced code
1245 * that used the original varlena size for calculations, which was wrong
1246 * in some subtle ways.
1247 */
1248
1249 for (i = 0; i < count; i++)
1250 {
1251 /* include "" and => and comma-space */
1252 buflen += 6 + 2 * HSTORE_KEYLEN(entries, i);
1253 /* include "" only if nonnull */
1254 buflen += 2 + (HSTORE_VALISNULL(entries, i)
1255 ? 2
1256 : 2 * HSTORE_VALLEN(entries, i));
1257 }
1258
1259 out = ptr = palloc(buflen);
1260
1261 for (i = 0; i < count; i++)
1262 {
1263 *ptr++ = '"';
1264 ptr = cpw(ptr, HSTORE_KEY(entries, base, i), HSTORE_KEYLEN(entries, i));
1265 *ptr++ = '"';
1266 *ptr++ = '=';
1267 *ptr++ = '>';
1268 if (HSTORE_VALISNULL(entries, i))
1269 {
1270 *ptr++ = 'N';
1271 *ptr++ = 'U';
1272 *ptr++ = 'L';
1273 *ptr++ = 'L';
1274 }
1275 else
1276 {
1277 *ptr++ = '"';
1278 ptr = cpw(ptr, HSTORE_VAL(entries, base, i), HSTORE_VALLEN(entries, i));
1279 *ptr++ = '"';
1280 }
1281
1282 if (i + 1 != count)
1283 {
1284 *ptr++ = ',';
1285 *ptr++ = ' ';
1286 }
1287 }
1288 *ptr = '\0';
1289
1290 PG_RETURN_CSTRING(out);
1291}
#define ARRPTR(x)
Definition: cube.c:28
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
static char * cpw(char *dst, char *src, int len)
Definition: hstore_io.c:1210
char * pstrdup(const char *in)
Definition: mcxt.c:2325
Definition: hstore.h:19

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

◆ HSTORE_POLLUTE()

HSTORE_POLLUTE ( hstore_from_text  ,
tconvert   
)

◆ hstore_populate_record()

Datum hstore_populate_record ( PG_FUNCTION_ARGS  )

Definition at line 993 of file hstore_io.c.

994{
995 Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
996 HStore *hs;
997 HEntry *entries;
998 char *ptr;
999 HeapTupleHeader rec;
1000 Oid tupType;
1001 int32 tupTypmod;
1002 TupleDesc tupdesc;
1003 HeapTupleData tuple;
1004 HeapTuple rettuple;
1005 RecordIOData *my_extra;
1006 int ncolumns;
1007 int i;
1008 Datum *values;
1009 bool *nulls;
1010
1011 if (!type_is_rowtype(argtype))
1012 ereport(ERROR,
1013 (errcode(ERRCODE_DATATYPE_MISMATCH),
1014 errmsg("first argument must be a rowtype")));
1015
1016 if (PG_ARGISNULL(0))
1017 {
1018 if (PG_ARGISNULL(1))
1020
1021 rec = NULL;
1022
1023 /*
1024 * We have no tuple to look at, so the only source of type info is the
1025 * argtype. The lookup_rowtype_tupdesc_domain call below will error
1026 * out if we don't have a known composite type oid here.
1027 */
1028 tupType = argtype;
1029 tupTypmod = -1;
1030 }
1031 else
1032 {
1034
1035 if (PG_ARGISNULL(1))
1036 PG_RETURN_POINTER(rec);
1037
1038 /*
1039 * Extract type info from the tuple itself -- this will work even for
1040 * anonymous record types.
1041 */
1042 tupType = HeapTupleHeaderGetTypeId(rec);
1043 tupTypmod = HeapTupleHeaderGetTypMod(rec);
1044 }
1045
1046 hs = PG_GETARG_HSTORE_P(1);
1047 entries = ARRPTR(hs);
1048 ptr = STRPTR(hs);
1049
1050 /*
1051 * if the input hstore is empty, we can only skip the rest if we were
1052 * passed in a non-null record, since otherwise there may be issues with
1053 * domain nulls.
1054 */
1055
1056 if (HS_COUNT(hs) == 0 && rec)
1057 PG_RETURN_POINTER(rec);
1058
1059 /*
1060 * Lookup the input record's tupdesc. For the moment, we don't worry
1061 * about whether it is a domain over composite.
1062 */
1063 tupdesc = lookup_rowtype_tupdesc_domain(tupType, tupTypmod, false);
1064 ncolumns = tupdesc->natts;
1065
1066 if (rec)
1067 {
1068 /* Build a temporary HeapTuple control structure */
1070 ItemPointerSetInvalid(&(tuple.t_self));
1071 tuple.t_tableOid = InvalidOid;
1072 tuple.t_data = rec;
1073 }
1074
1075 /*
1076 * We arrange to look up the needed I/O info just once per series of
1077 * calls, assuming the record type doesn't change underneath us.
1078 */
1079 my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
1080 if (my_extra == NULL ||
1081 my_extra->ncolumns != ncolumns)
1082 {
1083 fcinfo->flinfo->fn_extra =
1084 MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
1085 offsetof(RecordIOData, columns) +
1086 ncolumns * sizeof(ColumnIOData));
1087 my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
1088 my_extra->record_type = InvalidOid;
1089 my_extra->record_typmod = 0;
1090 my_extra->domain_info = NULL;
1091 }
1092
1093 if (my_extra->record_type != tupType ||
1094 my_extra->record_typmod != tupTypmod)
1095 {
1096 MemSet(my_extra, 0,
1097 offsetof(RecordIOData, columns) +
1098 ncolumns * sizeof(ColumnIOData));
1099 my_extra->record_type = tupType;
1100 my_extra->record_typmod = tupTypmod;
1101 my_extra->ncolumns = ncolumns;
1102 }
1103
1104 values = (Datum *) palloc(ncolumns * sizeof(Datum));
1105 nulls = (bool *) palloc(ncolumns * sizeof(bool));
1106
1107 if (rec)
1108 {
1109 /* Break down the tuple into fields */
1110 heap_deform_tuple(&tuple, tupdesc, values, nulls);
1111 }
1112 else
1113 {
1114 for (i = 0; i < ncolumns; ++i)
1115 {
1116 values[i] = (Datum) 0;
1117 nulls[i] = true;
1118 }
1119 }
1120
1121 for (i = 0; i < ncolumns; ++i)
1122 {
1123 ColumnIOData *column_info = &my_extra->columns[i];
1124 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1125 Oid column_type = att->atttypid;
1126 char *value;
1127 int idx;
1128 int vallen;
1129
1130 /* Ignore dropped columns in datatype */
1131 if (att->attisdropped)
1132 {
1133 nulls[i] = true;
1134 continue;
1135 }
1136
1137 idx = hstoreFindKey(hs, 0,
1138 NameStr(att->attname),
1139 strlen(NameStr(att->attname)));
1140
1141 /*
1142 * we can't just skip here if the key wasn't found since we might have
1143 * a domain to deal with. If we were passed in a non-null record
1144 * datum, we assume that the existing values are valid (if they're
1145 * not, then it's not our fault), but if we were passed in a null,
1146 * then every field which we don't populate needs to be run through
1147 * the input function just in case it's a domain type.
1148 */
1149 if (idx < 0 && rec)
1150 continue;
1151
1152 /*
1153 * Prepare to convert the column value from text
1154 */
1155 if (column_info->column_type != column_type)
1156 {
1157 getTypeInputInfo(column_type,
1158 &column_info->typiofunc,
1159 &column_info->typioparam);
1160 fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
1161 fcinfo->flinfo->fn_mcxt);
1162 column_info->column_type = column_type;
1163 }
1164
1165 if (idx < 0 || HSTORE_VALISNULL(entries, idx))
1166 {
1167 /*
1168 * need InputFunctionCall to happen even for nulls, so that domain
1169 * checks are done
1170 */
1171 values[i] = InputFunctionCall(&column_info->proc, NULL,
1172 column_info->typioparam,
1173 att->atttypmod);
1174 nulls[i] = true;
1175 }
1176 else
1177 {
1178 vallen = HSTORE_VALLEN(entries, idx);
1179 value = palloc(1 + vallen);
1180 memcpy(value, HSTORE_VAL(entries, ptr, idx), vallen);
1181 value[vallen] = 0;
1182
1183 values[i] = InputFunctionCall(&column_info->proc, value,
1184 column_info->typioparam,
1185 att->atttypmod);
1186 nulls[i] = false;
1187 }
1188 }
1189
1190 rettuple = heap_form_tuple(tupdesc, values, nulls);
1191
1192 /*
1193 * If the target type is domain over composite, all we know at this point
1194 * is that we've made a valid value of the base composite type. Must
1195 * check domain constraints before deciding we're done.
1196 */
1197 if (argtype != tupdesc->tdtypeid)
1198 domain_check(HeapTupleGetDatum(rettuple), false,
1199 argtype,
1200 &my_extra->domain_info,
1201 fcinfo->flinfo->fn_mcxt);
1202
1203 ReleaseTupleDesc(tupdesc);
1204
1206}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt)
Definition: domains.c:346
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1530
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
PGDLLEXPORT int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2795
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:3014
Oid typioparam
Definition: hstore_io.c:818
void * domain_info
Definition: hstore_io.c:827
Oid tdtypeid
Definition: tupdesc.h:138

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(), if(), InputFunctionCall(), InvalidOid, ItemPointerSetInvalid(), lookup_rowtype_tupdesc_domain(), MemoryContextAlloc(), MemSet, NameStr, TupleDescData::natts, RecordIOData::ncolumns, 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.

◆ hstore_recv()

Datum hstore_recv ( PG_FUNCTION_ARGS  )

Definition at line 503 of file hstore_io.c.

504{
505 int32 buflen;
506 HStore *out;
507 Pairs *pairs;
508 int32 i;
509 int32 pcount;
511
512 pcount = pq_getmsgint(buf, 4);
513
514 if (pcount == 0)
515 {
516 out = hstorePairs(NULL, 0, 0);
518 }
519
520 if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
522 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
523 errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
524 pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
525 pairs = palloc(pcount * sizeof(Pairs));
526
527 for (i = 0; i < pcount; ++i)
528 {
529 int rawlen = pq_getmsgint(buf, 4);
530 int len;
531
532 if (rawlen < 0)
534 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
535 errmsg("null value not allowed for hstore key")));
536
537 pairs[i].key = pq_getmsgtext(buf, rawlen, &len);
538 pairs[i].keylen = hstoreCheckKeyLen(len);
539 pairs[i].needfree = true;
540
541 rawlen = pq_getmsgint(buf, 4);
542 if (rawlen < 0)
543 {
544 pairs[i].val = NULL;
545 pairs[i].vallen = 0;
546 pairs[i].isnull = true;
547 }
548 else
549 {
550 pairs[i].val = pq_getmsgtext(buf, rawlen, &len);
551 pairs[i].vallen = hstoreCheckValLen(len);
552 pairs[i].isnull = false;
553 }
554 }
555
556 pcount = hstoreUniquePairs(pairs, pcount, &buflen);
557
558 out = hstorePairs(pairs, pcount, buflen);
559
561}
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
static char * buf
Definition: pg_test_fsync.c:72
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
StringInfoData * StringInfo
Definition: stringinfo.h:54

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

◆ hstore_send()

Datum hstore_send ( PG_FUNCTION_ARGS  )

Definition at line 1296 of file hstore_io.c.

1297{
1298 HStore *in = PG_GETARG_HSTORE_P(0);
1299 int i;
1300 int count = HS_COUNT(in);
1301 char *base = STRPTR(in);
1302 HEntry *entries = ARRPTR(in);
1304
1306
1307 pq_sendint32(&buf, count);
1308
1309 for (i = 0; i < count; i++)
1310 {
1311 int32 keylen = HSTORE_KEYLEN(entries, i);
1312
1313 pq_sendint32(&buf, keylen);
1314 pq_sendtext(&buf, HSTORE_KEY(entries, base, i), keylen);
1315 if (HSTORE_VALISNULL(entries, i))
1316 {
1317 pq_sendint32(&buf, -1);
1318 }
1319 else
1320 {
1321 int32 vallen = HSTORE_VALLEN(entries, i);
1322
1323 pq_sendint32(&buf, vallen);
1324 pq_sendtext(&buf, HSTORE_VAL(entries, base, i), vallen);
1325 }
1326 }
1327
1329}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144

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

◆ hstore_to_json()

Datum hstore_to_json ( PG_FUNCTION_ARGS  )

Definition at line 1394 of file hstore_io.c.

1395{
1396 HStore *in = PG_GETARG_HSTORE_P(0);
1397 int i;
1398 int count = HS_COUNT(in);
1399 char *base = STRPTR(in);
1400 HEntry *entries = ARRPTR(in);
1401 StringInfoData dst;
1402
1403 if (count == 0)
1405
1406 initStringInfo(&dst);
1407
1408 appendStringInfoChar(&dst, '{');
1409
1410 for (i = 0; i < count; i++)
1411 {
1413 HSTORE_KEY(entries, base, i),
1414 HSTORE_KEYLEN(entries, i));
1415 appendStringInfoString(&dst, ": ");
1416 if (HSTORE_VALISNULL(entries, i))
1417 appendStringInfoString(&dst, "null");
1418 else
1419 {
1421 HSTORE_VAL(entries, base, i),
1422 HSTORE_VALLEN(entries, i));
1423 }
1424
1425 if (i + 1 != count)
1426 appendStringInfoString(&dst, ", ");
1427 }
1428 appendStringInfoChar(&dst, '}');
1429
1431}
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
void escape_json_with_len(StringInfo buf, const char *str, int len)
Definition: json.c:1631
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:204

References appendStringInfoChar(), appendStringInfoString(), ARRPTR, cstring_to_text_with_len(), StringInfoData::data, escape_json_with_len(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), StringInfoData::len, PG_GETARG_HSTORE_P, PG_RETURN_TEXT_P, and STRPTR.

◆ hstore_to_json_loose()

Datum hstore_to_json_loose ( PG_FUNCTION_ARGS  )

Definition at line 1342 of file hstore_io.c.

1343{
1344 HStore *in = PG_GETARG_HSTORE_P(0);
1345 int i;
1346 int count = HS_COUNT(in);
1347 char *base = STRPTR(in);
1348 HEntry *entries = ARRPTR(in);
1349 StringInfoData dst;
1350
1351 if (count == 0)
1353
1354 initStringInfo(&dst);
1355
1356 appendStringInfoChar(&dst, '{');
1357
1358 for (i = 0; i < count; i++)
1359 {
1361 HSTORE_KEY(entries, base, i),
1362 HSTORE_KEYLEN(entries, i));
1363 appendStringInfoString(&dst, ": ");
1364 if (HSTORE_VALISNULL(entries, i))
1365 appendStringInfoString(&dst, "null");
1366 /* guess that values of 't' or 'f' are booleans */
1367 else if (HSTORE_VALLEN(entries, i) == 1 &&
1368 *(HSTORE_VAL(entries, base, i)) == 't')
1369 appendStringInfoString(&dst, "true");
1370 else if (HSTORE_VALLEN(entries, i) == 1 &&
1371 *(HSTORE_VAL(entries, base, i)) == 'f')
1372 appendStringInfoString(&dst, "false");
1373 else
1374 {
1375 char *str = HSTORE_VAL(entries, base, i);
1376 int len = HSTORE_VALLEN(entries, i);
1377
1380 else
1382 }
1383
1384 if (i + 1 != count)
1385 appendStringInfoString(&dst, ", ");
1386 }
1387 appendStringInfoChar(&dst, '}');
1388
1390}
bool IsValidJsonNumber(const char *str, size_t len)
Definition: jsonapi.c:339
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281

References appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoString(), ARRPTR, cstring_to_text_with_len(), StringInfoData::data, escape_json_with_len(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), IsValidJsonNumber(), StringInfoData::len, len, PG_GETARG_HSTORE_P, PG_RETURN_TEXT_P, str, and STRPTR.

◆ hstore_to_jsonb()

Datum hstore_to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1435 of file hstore_io.c.

1436{
1437 HStore *in = PG_GETARG_HSTORE_P(0);
1438 int i;
1439 int count = HS_COUNT(in);
1440 char *base = STRPTR(in);
1441 HEntry *entries = ARRPTR(in);
1442 JsonbParseState *state = NULL;
1443 JsonbValue *res;
1444
1445 (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1446
1447 for (i = 0; i < count; i++)
1448 {
1450 val;
1451
1452 key.type = jbvString;
1453 key.val.string.len = HSTORE_KEYLEN(entries, i);
1454 key.val.string.val = HSTORE_KEY(entries, base, i);
1455
1456 (void) pushJsonbValue(&state, WJB_KEY, &key);
1457
1458 if (HSTORE_VALISNULL(entries, i))
1459 {
1460 val.type = jbvNull;
1461 }
1462 else
1463 {
1464 val.type = jbvString;
1465 val.val.string.len = HSTORE_VALLEN(entries, i);
1466 val.val.string.val = HSTORE_VAL(entries, base, i);
1467 }
1468 (void) pushJsonbValue(&state, WJB_VALUE, &val);
1469 }
1470
1471 res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
1472
1474}
@ jbvNull
Definition: jsonb.h:228
@ jbvString
Definition: jsonb.h:229
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:573
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:92

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

◆ hstore_to_jsonb_loose()

Datum hstore_to_jsonb_loose ( PG_FUNCTION_ARGS  )

Definition at line 1478 of file hstore_io.c.

1479{
1480 HStore *in = PG_GETARG_HSTORE_P(0);
1481 int i;
1482 int count = HS_COUNT(in);
1483 char *base = STRPTR(in);
1484 HEntry *entries = ARRPTR(in);
1485 JsonbParseState *state = NULL;
1486 JsonbValue *res;
1487 StringInfoData tmp;
1488
1489 initStringInfo(&tmp);
1490
1491 (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1492
1493 for (i = 0; i < count; i++)
1494 {
1496 val;
1497
1498 key.type = jbvString;
1499 key.val.string.len = HSTORE_KEYLEN(entries, i);
1500 key.val.string.val = HSTORE_KEY(entries, base, i);
1501
1502 (void) pushJsonbValue(&state, WJB_KEY, &key);
1503
1504 if (HSTORE_VALISNULL(entries, i))
1505 {
1506 val.type = jbvNull;
1507 }
1508 /* guess that values of 't' or 'f' are booleans */
1509 else if (HSTORE_VALLEN(entries, i) == 1 &&
1510 *(HSTORE_VAL(entries, base, i)) == 't')
1511 {
1512 val.type = jbvBool;
1513 val.val.boolean = true;
1514 }
1515 else if (HSTORE_VALLEN(entries, i) == 1 &&
1516 *(HSTORE_VAL(entries, base, i)) == 'f')
1517 {
1518 val.type = jbvBool;
1519 val.val.boolean = false;
1520 }
1521 else
1522 {
1523 resetStringInfo(&tmp);
1524 appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1525 HSTORE_VALLEN(entries, i));
1526 if (IsValidJsonNumber(tmp.data, tmp.len))
1527 {
1528 Datum numd;
1529
1530 val.type = jbvNumeric;
1532 CStringGetDatum(tmp.data),
1534 Int32GetDatum(-1));
1535 val.val.numeric = DatumGetNumeric(numd);
1536 }
1537 else
1538 {
1539 val.type = jbvString;
1540 val.val.string.len = HSTORE_VALLEN(entries, i);
1541 val.val.string.val = HSTORE_VAL(entries, base, i);
1542 }
1543 }
1544 (void) pushJsonbValue(&state, WJB_VALUE, &val);
1545 }
1546
1547 res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
1548
1550}
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:637
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:686
@ jbvNumeric
Definition: jsonb.h:230
@ jbvBool
Definition: jsonb.h:231
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:61
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:126

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, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ hstoreCheckKeyLen()

size_t hstoreCheckKeyLen ( size_t  len)

Definition at line 407 of file hstore_io.c.

408{
411 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
412 errmsg("string too long for hstore key")));
413 return len;
414}
#define HSTORE_MAX_KEY_LEN
Definition: hstore.h:41

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

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

◆ hstoreCheckKeyLength()

static bool hstoreCheckKeyLength ( size_t  len,
HSParser state 
)
static

Definition at line 417 of file hstore_io.c.

418{
420 ereturn(state->escontext, false,
421 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
422 errmsg("string too long for hstore key")));
423 return true;
424}
#define ereturn(context, dummy_value,...)
Definition: elog.h:277

References ereturn, errcode(), errmsg(), HSTORE_MAX_KEY_LEN, and len.

Referenced by parse_hstore().

◆ hstoreCheckValLen()

size_t hstoreCheckValLen ( size_t  len)

Definition at line 427 of file hstore_io.c.

428{
431 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
432 errmsg("string too long for hstore value")));
433 return len;
434}
#define HSTORE_MAX_VALUE_LEN
Definition: hstore.h:42

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

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

◆ hstoreCheckValLength()

static bool hstoreCheckValLength ( size_t  len,
HSParser state 
)
static

Definition at line 437 of file hstore_io.c.

438{
440 ereturn(state->escontext, false,
441 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
442 errmsg("string too long for hstore value")));
443 return true;
444}

References ereturn, errcode(), errmsg(), HSTORE_MAX_VALUE_LEN, and len.

Referenced by parse_hstore().

◆ hstorePairs()

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

Definition at line 448 of file hstore_io.c.

449{
450 HStore *out;
451 HEntry *entry;
452 char *ptr;
453 char *buf;
454 int32 len;
455 int32 i;
456
457 len = CALCDATASIZE(pcount, buflen);
458 out = palloc(len);
459 SET_VARSIZE(out, len);
460 HS_SETCOUNT(out, pcount);
461
462 if (pcount == 0)
463 return out;
464
465 entry = ARRPTR(out);
466 buf = ptr = STRPTR(out);
467
468 for (i = 0; i < pcount; i++)
469 HS_ADDITEM(entry, buf, ptr, pairs[i]);
470
471 HS_FINALIZE(out, pcount, buf, ptr);
472
473 return out;
474}
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
#define HS_ADDITEM(dent_, dbuf_, dptr_, pair_)
Definition: hstore.h:112
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

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

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

◆ hstoreUniquePairs()

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

Definition at line 359 of file hstore_io.c.

360{
361 Pairs *ptr,
362 *res;
363
364 *buflen = 0;
365 if (l < 2)
366 {
367 if (l == 1)
368 *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen);
369 return l;
370 }
371
372 qsort(a, l, sizeof(Pairs), comparePairs);
373
374 /*
375 * We can't use qunique here because we have some clean-up code to run on
376 * removed elements.
377 */
378 ptr = a + 1;
379 res = a;
380 while (ptr - a < l)
381 {
382 if (ptr->keylen == res->keylen &&
383 memcmp(ptr->key, res->key, res->keylen) == 0)
384 {
385 if (ptr->needfree)
386 {
387 pfree(ptr->key);
388 pfree(ptr->val);
389 }
390 }
391 else
392 {
393 *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
394 res++;
395 if (res != ptr)
396 memcpy(res, ptr, sizeof(Pairs));
397 }
398
399 ptr++;
400 }
401
402 *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
403 return res + 1 - a;
404}
static int comparePairs(const void *a, const void *b)
Definition: hstore_io.c:329
void pfree(void *pointer)
Definition: mcxt.c:2150
#define qsort(a, b, c, d)
Definition: port.h:479

References a, 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().

◆ parse_hstore()

static bool parse_hstore ( HSParser state)
static

Definition at line 218 of file hstore_io.c.

219{
220 int st = WKEY;
221 bool escaped = false;
222
223 state->plen = 16;
224 state->pairs = (Pairs *) palloc(sizeof(Pairs) * state->plen);
225 state->pcur = 0;
226 state->ptr = state->begin;
227 state->word = NULL;
228
229 while (1)
230 {
231 if (st == WKEY)
232 {
233 if (!get_val(state, false, &escaped))
234 {
235 if (SOFT_ERROR_OCCURRED(state->escontext))
236 return false;
237 return true; /* EOF, all okay */
238 }
239 if (state->pcur >= state->plen)
240 {
241 state->plen *= 2;
242 state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen);
243 }
244 if (!hstoreCheckKeyLength(state->cur - state->word, state))
245 return false;
246 state->pairs[state->pcur].key = state->word;
247 state->pairs[state->pcur].keylen = state->cur - state->word;
248 state->pairs[state->pcur].val = NULL;
249 state->word = NULL;
250 st = WEQ;
251 }
252 else if (st == WEQ)
253 {
254 if (*(state->ptr) == '=')
255 {
256 st = WGT;
257 }
258 else if (*(state->ptr) == '\0')
259 {
260 PRSEOF;
261 }
262 else if (!scanner_isspace((unsigned char) *(state->ptr)))
263 {
265 }
266 }
267 else if (st == WGT)
268 {
269 if (*(state->ptr) == '>')
270 {
271 st = WVAL;
272 }
273 else if (*(state->ptr) == '\0')
274 {
275 PRSEOF;
276 }
277 else
278 {
280 }
281 }
282 else if (st == WVAL)
283 {
284 if (!get_val(state, true, &escaped))
285 {
286 if (SOFT_ERROR_OCCURRED(state->escontext))
287 return false;
288 PRSEOF;
289 }
290 if (!hstoreCheckValLength(state->cur - state->word, state))
291 return false;
292 state->pairs[state->pcur].val = state->word;
293 state->pairs[state->pcur].vallen = state->cur - state->word;
294 state->pairs[state->pcur].isnull = false;
295 state->pairs[state->pcur].needfree = true;
296 if (state->cur - state->word == 4 && !escaped)
297 {
298 state->word[4] = '\0';
299 if (pg_strcasecmp(state->word, "null") == 0)
300 state->pairs[state->pcur].isnull = true;
301 }
302 state->word = NULL;
303 state->pcur++;
304 st = WDEL;
305 }
306 else if (st == WDEL)
307 {
308 if (*(state->ptr) == ',')
309 {
310 st = WKEY;
311 }
312 else if (*(state->ptr) == '\0')
313 {
314 return true;
315 }
316 else if (!scanner_isspace((unsigned char) *(state->ptr)))
317 {
319 }
320 }
321 else
322 elog(ERROR, "unrecognized parse_hstore state: %d", st);
323
324 state->ptr++;
325 }
326}
#define WDEL
Definition: hstore_io.c:214
static bool get_val(HSParser *state, bool ignoreeq, bool *escaped)
Definition: hstore_io.c:96
#define WKEY
Definition: hstore_io.c:210
static bool hstoreCheckValLength(size_t len, HSParser *state)
Definition: hstore_io.c:437
#define WGT
Definition: hstore_io.c:213
#define WVAL
Definition: hstore_io.c:211
static bool hstoreCheckKeyLength(size_t len, HSParser *state)
Definition: hstore_io.c:417
#define WEQ
Definition: hstore_io.c:212
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:53
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36

References elog, ERROR, get_val(), hstoreCheckKeyLength(), hstoreCheckValLength(), palloc(), pg_strcasecmp(), PRSEOF, PRSSYNTAXERROR, repalloc(), scanner_isspace(), SOFT_ERROR_OCCURRED, WDEL, WEQ, WGT, WKEY, and WVAL.

Referenced by hstore_in().

◆ PG_FUNCTION_INFO_V1() [1/13]

PG_FUNCTION_INFO_V1 ( hstore_from_array  )

◆ PG_FUNCTION_INFO_V1() [2/13]

PG_FUNCTION_INFO_V1 ( hstore_from_arrays  )

◆ PG_FUNCTION_INFO_V1() [3/13]

PG_FUNCTION_INFO_V1 ( hstore_from_record  )

◆ PG_FUNCTION_INFO_V1() [4/13]

PG_FUNCTION_INFO_V1 ( hstore_from_text  )

◆ PG_FUNCTION_INFO_V1() [5/13]

PG_FUNCTION_INFO_V1 ( hstore_in  )

◆ PG_FUNCTION_INFO_V1() [6/13]

PG_FUNCTION_INFO_V1 ( hstore_out  )

◆ PG_FUNCTION_INFO_V1() [7/13]

PG_FUNCTION_INFO_V1 ( hstore_populate_record  )

◆ PG_FUNCTION_INFO_V1() [8/13]

PG_FUNCTION_INFO_V1 ( hstore_recv  )

◆ 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  )

◆ PG_FUNCTION_INFO_V1() [11/13]

PG_FUNCTION_INFO_V1 ( hstore_to_json_loose  )

◆ 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  )

◆ PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( name = "hstore",
version = PG_VERSION 
)

◆ prseof()

static bool prseof ( HSParser state)
static

Definition at line 79 of file hstore_io.c.

80{
81 errsave(state->escontext,
82 (errcode(ERRCODE_SYNTAX_ERROR),
83 errmsg("syntax error in hstore: unexpected end of string")));
84 /* In soft error situation, return false as convenience for caller */
85 return false;
86}
#define errsave(context,...)
Definition: elog.h:261

References errcode(), errmsg(), and errsave.

◆ prssyntaxerror()

static bool prssyntaxerror ( HSParser state)
static

Definition at line 65 of file hstore_io.c.

66{
67 errsave(state->escontext,
68 (errcode(ERRCODE_SYNTAX_ERROR),
69 errmsg("syntax error in hstore, near \"%.*s\" at position %d",
70 pg_mblen(state->ptr), state->ptr,
71 (int) (state->ptr - state->begin))));
72 /* In soft error situation, return false as convenience for caller */
73 return false;
74}
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023

References errcode(), errmsg(), errsave, and pg_mblen().