PostgreSQL Source Code git master
hstore_io.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "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

 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)
 

Variables

 PG_MODULE_MAGIC
 

Macro Definition Documentation

◆ GV_INESCVAL

#define GV_INESCVAL   2

Definition at line 88 of file hstore_io.c.

◆ GV_INVAL

#define GV_INVAL   1

Definition at line 87 of file hstore_io.c.

◆ GV_WAITESCESCIN

#define GV_WAITESCESCIN   4

Definition at line 90 of file hstore_io.c.

◆ GV_WAITESCIN

#define GV_WAITESCIN   3

Definition at line 89 of file hstore_io.c.

◆ GV_WAITVAL

#define GV_WAITVAL   0

Definition at line 86 of file hstore_io.c.

◆ PRSEOF

#define PRSEOF   return prseof(state)

Definition at line 73 of file hstore_io.c.

◆ PRSSYNTAXERROR

#define PRSSYNTAXERROR   return prssyntaxerror(state)

Definition at line 59 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:1541
Definition: regguts.h:323

Definition at line 48 of file hstore_io.c.

◆ WDEL

#define WDEL   4

Definition at line 211 of file hstore_io.c.

◆ WEQ

#define WEQ   2

Definition at line 209 of file hstore_io.c.

◆ WGT

#define WGT   3

Definition at line 210 of file hstore_io.c.

◆ WKEY

#define WKEY   0

Definition at line 207 of file hstore_io.c.

◆ WVAL

#define WVAL   1

Definition at line 208 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 326 of file hstore_io.c.

327{
328 const Pairs *pa = a;
329 const Pairs *pb = b;
330
331 if (pa->keylen == pb->keylen)
332 {
333 int res = memcmp(pa->key, pb->key, pa->keylen);
334
335 if (res)
336 return res;
337
338 /* guarantee that needfree will be later */
339 if (pb->needfree == pa->needfree)
340 return 0;
341 else if (pa->needfree)
342 return 1;
343 else
344 return -1;
345 }
346 return (pa->keylen > pb->keylen) ? 1 : -1;
347}
int b
Definition: isn.c:69
int a
Definition: isn.c:68
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, Pairs::needfree, and res.

Referenced by hstoreUniquePairs().

◆ cpw()

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

Definition at line 1207 of file hstore_io.c.

1208{
1209 char *ptr = src;
1210
1211 while (ptr - src < len)
1212 {
1213 if (*ptr == '"' || *ptr == '\\')
1214 *dst++ = '\\';
1215 *dst++ = *ptr++;
1216 }
1217 return dst;
1218}
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 93 of file hstore_io.c.

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

716{
717 ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
718 int ndims = ARR_NDIM(in_array);
719 int count;
720 int32 buflen;
721 HStore *out;
722 Pairs *pairs;
723 Datum *in_datums;
724 bool *in_nulls;
725 int in_count;
726 int i;
727
728 Assert(ARR_ELEMTYPE(in_array) == TEXTOID);
729
730 switch (ndims)
731 {
732 case 0:
733 out = hstorePairs(NULL, 0, 0);
735
736 case 1:
737 if ((ARR_DIMS(in_array)[0]) % 2)
739 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
740 errmsg("array must have even number of elements")));
741 break;
742
743 case 2:
744 if ((ARR_DIMS(in_array)[1]) != 2)
746 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
747 errmsg("array must have two columns")));
748 break;
749
750 default:
752 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
753 errmsg("wrong number of array subscripts")));
754 }
755
756 deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
757
758 count = in_count / 2;
759
760 /* see discussion in hstoreArrayToPairs() */
761 if (count > MaxAllocSize / sizeof(Pairs))
763 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
764 errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
765 count, (int) (MaxAllocSize / sizeof(Pairs)))));
766
767 pairs = palloc(count * sizeof(Pairs));
768
769 for (i = 0; i < count; ++i)
770 {
771 if (in_nulls[i * 2])
773 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
774 errmsg("null value not allowed for hstore key")));
775
776 if (in_nulls[i * 2 + 1])
777 {
778 pairs[i].key = VARDATA(in_datums[i * 2]);
779 pairs[i].val = NULL;
780 pairs[i].keylen =
781 hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
782 pairs[i].vallen = 4;
783 pairs[i].isnull = true;
784 pairs[i].needfree = false;
785 }
786 else
787 {
788 pairs[i].key = VARDATA(in_datums[i * 2]);
789 pairs[i].val = VARDATA(in_datums[i * 2 + 1]);
790 pairs[i].keylen =
791 hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
792 pairs[i].vallen =
793 hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ);
794 pairs[i].isnull = false;
795 pairs[i].needfree = false;
796 }
797 }
798
799 count = hstoreUniquePairs(pairs, count, &buflen);
800
801 out = hstorePairs(pairs, count, buflen);
802
804}
#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:649
#define Assert(condition)
Definition: c.h:815
int32_t int32
Definition: c.h:484
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
#define MaxAllocSize
Definition: fe_memutils.h:22
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:445
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:424
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:404
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:356
int i
Definition: isn.c:72
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 599 of file hstore_io.c.

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

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

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

564{
565 text *key;
566 text *val = NULL;
567 Pairs p;
568 HStore *out;
569
570 if (PG_ARGISNULL(0))
572
573 p.needfree = false;
575 p.key = VARDATA_ANY(key);
577
578 if (PG_ARGISNULL(1))
579 {
580 p.vallen = 0;
581 p.isnull = true;
582 }
583 else
584 {
586 p.val = VARDATA_ANY(val);
588 p.isnull = false;
589 }
590
591 out = hstorePairs(&p, 1, p.keylen + p.vallen);
592
594}
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
long val
Definition: informix.c:689
Definition: c.h:644
#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 476 of file hstore_io.c.

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

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

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

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

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

501{
502 int32 buflen;
503 HStore *out;
504 Pairs *pairs;
505 int32 i;
506 int32 pcount;
508
509 pcount = pq_getmsgint(buf, 4);
510
511 if (pcount == 0)
512 {
513 out = hstorePairs(NULL, 0, 0);
515 }
516
517 if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
519 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
520 errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
521 pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
522 pairs = palloc(pcount * sizeof(Pairs));
523
524 for (i = 0; i < pcount; ++i)
525 {
526 int rawlen = pq_getmsgint(buf, 4);
527 int len;
528
529 if (rawlen < 0)
531 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
532 errmsg("null value not allowed for hstore key")));
533
534 pairs[i].key = pq_getmsgtext(buf, rawlen, &len);
535 pairs[i].keylen = hstoreCheckKeyLen(len);
536 pairs[i].needfree = true;
537
538 rawlen = pq_getmsgint(buf, 4);
539 if (rawlen < 0)
540 {
541 pairs[i].val = NULL;
542 pairs[i].vallen = 0;
543 pairs[i].isnull = true;
544 }
545 else
546 {
547 pairs[i].val = pq_getmsgtext(buf, rawlen, &len);
548 pairs[i].vallen = hstoreCheckValLen(len);
549 pairs[i].isnull = false;
550 }
551 }
552
553 pcount = hstoreUniquePairs(pairs, pcount, &buflen);
554
555 out = hstorePairs(pairs, pcount, buflen);
556
558}
#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 1293 of file hstore_io.c.

1294{
1295 HStore *in = PG_GETARG_HSTORE_P(0);
1296 int i;
1297 int count = HS_COUNT(in);
1298 char *base = STRPTR(in);
1299 HEntry *entries = ARRPTR(in);
1301
1303
1304 pq_sendint32(&buf, count);
1305
1306 for (i = 0; i < count; i++)
1307 {
1308 int32 keylen = HSTORE_KEYLEN(entries, i);
1309
1310 pq_sendint32(&buf, keylen);
1311 pq_sendtext(&buf, HSTORE_KEY(entries, base, i), keylen);
1312 if (HSTORE_VALISNULL(entries, i))
1313 {
1314 pq_sendint32(&buf, -1);
1315 }
1316 else
1317 {
1318 int32 vallen = HSTORE_VALLEN(entries, i);
1319
1320 pq_sendint32(&buf, vallen);
1321 pq_sendtext(&buf, HSTORE_VAL(entries, base, i), vallen);
1322 }
1323 }
1324
1326}
#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 1391 of file hstore_io.c.

1392{
1393 HStore *in = PG_GETARG_HSTORE_P(0);
1394 int i;
1395 int count = HS_COUNT(in);
1396 char *base = STRPTR(in);
1397 HEntry *entries = ARRPTR(in);
1398 StringInfoData dst;
1399
1400 if (count == 0)
1402
1403 initStringInfo(&dst);
1404
1405 appendStringInfoChar(&dst, '{');
1406
1407 for (i = 0; i < count; i++)
1408 {
1410 HSTORE_KEY(entries, base, i),
1411 HSTORE_KEYLEN(entries, i));
1412 appendStringInfoString(&dst, ": ");
1413 if (HSTORE_VALISNULL(entries, i))
1414 appendStringInfoString(&dst, "null");
1415 else
1416 {
1418 HSTORE_VAL(entries, base, i),
1419 HSTORE_VALLEN(entries, i));
1420 }
1421
1422 if (i + 1 != count)
1423 appendStringInfoString(&dst, ", ");
1424 }
1425 appendStringInfoChar(&dst, '}');
1426
1428}
#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:196

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

1340{
1341 HStore *in = PG_GETARG_HSTORE_P(0);
1342 int i;
1343 int count = HS_COUNT(in);
1344 char *base = STRPTR(in);
1345 HEntry *entries = ARRPTR(in);
1346 StringInfoData dst;
1347
1348 if (count == 0)
1350
1351 initStringInfo(&dst);
1352
1353 appendStringInfoChar(&dst, '{');
1354
1355 for (i = 0; i < count; i++)
1356 {
1358 HSTORE_KEY(entries, base, i),
1359 HSTORE_KEYLEN(entries, i));
1360 appendStringInfoString(&dst, ": ");
1361 if (HSTORE_VALISNULL(entries, i))
1362 appendStringInfoString(&dst, "null");
1363 /* guess that values of 't' or 'f' are booleans */
1364 else if (HSTORE_VALLEN(entries, i) == 1 &&
1365 *(HSTORE_VAL(entries, base, i)) == 't')
1366 appendStringInfoString(&dst, "true");
1367 else if (HSTORE_VALLEN(entries, i) == 1 &&
1368 *(HSTORE_VAL(entries, base, i)) == 'f')
1369 appendStringInfoString(&dst, "false");
1370 else
1371 {
1372 char *str = HSTORE_VAL(entries, base, i);
1373 int len = HSTORE_VALLEN(entries, i);
1374
1377 else
1379 }
1380
1381 if (i + 1 != count)
1382 appendStringInfoString(&dst, ", ");
1383 }
1384 appendStringInfoChar(&dst, '}');
1385
1387}
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 1432 of file hstore_io.c.

1433{
1434 HStore *in = PG_GETARG_HSTORE_P(0);
1435 int i;
1436 int count = HS_COUNT(in);
1437 char *base = STRPTR(in);
1438 HEntry *entries = ARRPTR(in);
1439 JsonbParseState *state = NULL;
1440 JsonbValue *res;
1441
1442 (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1443
1444 for (i = 0; i < count; i++)
1445 {
1447 val;
1448
1449 key.type = jbvString;
1450 key.val.string.len = HSTORE_KEYLEN(entries, i);
1451 key.val.string.val = HSTORE_KEY(entries, base, i);
1452
1453 (void) pushJsonbValue(&state, WJB_KEY, &key);
1454
1455 if (HSTORE_VALISNULL(entries, i))
1456 {
1457 val.type = jbvNull;
1458 }
1459 else
1460 {
1461 val.type = jbvString;
1462 val.val.string.len = HSTORE_VALLEN(entries, i);
1463 val.val.string.val = HSTORE_VAL(entries, base, i);
1464 }
1465 (void) pushJsonbValue(&state, WJB_VALUE, &val);
1466 }
1467
1469
1471}
@ 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(), res, 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 1475 of file hstore_io.c.

1476{
1477 HStore *in = PG_GETARG_HSTORE_P(0);
1478 int i;
1479 int count = HS_COUNT(in);
1480 char *base = STRPTR(in);
1481 HEntry *entries = ARRPTR(in);
1482 JsonbParseState *state = NULL;
1483 JsonbValue *res;
1484 StringInfoData tmp;
1485
1486 initStringInfo(&tmp);
1487
1488 (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1489
1490 for (i = 0; i < count; i++)
1491 {
1493 val;
1494
1495 key.type = jbvString;
1496 key.val.string.len = HSTORE_KEYLEN(entries, i);
1497 key.val.string.val = HSTORE_KEY(entries, base, i);
1498
1499 (void) pushJsonbValue(&state, WJB_KEY, &key);
1500
1501 if (HSTORE_VALISNULL(entries, i))
1502 {
1503 val.type = jbvNull;
1504 }
1505 /* guess that values of 't' or 'f' are booleans */
1506 else if (HSTORE_VALLEN(entries, i) == 1 &&
1507 *(HSTORE_VAL(entries, base, i)) == 't')
1508 {
1509 val.type = jbvBool;
1510 val.val.boolean = true;
1511 }
1512 else if (HSTORE_VALLEN(entries, i) == 1 &&
1513 *(HSTORE_VAL(entries, base, i)) == 'f')
1514 {
1515 val.type = jbvBool;
1516 val.val.boolean = false;
1517 }
1518 else
1519 {
1520 resetStringInfo(&tmp);
1521 appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1522 HSTORE_VALLEN(entries, i));
1523 if (IsValidJsonNumber(tmp.data, tmp.len))
1524 {
1525 Datum numd;
1526
1527 val.type = jbvNumeric;
1529 CStringGetDatum(tmp.data),
1531 Int32GetDatum(-1));
1532 val.val.numeric = DatumGetNumeric(numd);
1533 }
1534 else
1535 {
1536 val.type = jbvString;
1537 val.val.string.len = HSTORE_VALLEN(entries, i);
1538 val.val.string.val = HSTORE_VAL(entries, base, i);
1539 }
1540 }
1541 (void) pushJsonbValue(&state, WJB_VALUE, &val);
1542 }
1543
1545
1547}
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:637
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:645
@ 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(), res, resetStringInfo(), STRPTR, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ hstoreCheckKeyLen()

size_t hstoreCheckKeyLen ( size_t  len)

Definition at line 404 of file hstore_io.c.

405{
408 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
409 errmsg("string too long for hstore key")));
410 return len;
411}
#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 414 of file hstore_io.c.

415{
417 ereturn(state->escontext, false,
418 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
419 errmsg("string too long for hstore key")));
420 return true;
421}
#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 424 of file hstore_io.c.

425{
428 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
429 errmsg("string too long for hstore value")));
430 return len;
431}
#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 434 of file hstore_io.c.

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

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

446{
447 HStore *out;
448 HEntry *entry;
449 char *ptr;
450 char *buf;
451 int32 len;
452 int32 i;
453
454 len = CALCDATASIZE(pcount, buflen);
455 out = palloc(len);
456 SET_VARSIZE(out, len);
457 HS_SETCOUNT(out, pcount);
458
459 if (pcount == 0)
460 return out;
461
462 entry = ARRPTR(out);
463 buf = ptr = STRPTR(out);
464
465 for (i = 0; i < pcount; i++)
466 HS_ADDITEM(entry, buf, ptr, pairs[i]);
467
468 HS_FINALIZE(out, pcount, buf, ptr);
469
470 return out;
471}
#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 356 of file hstore_io.c.

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

References a, comparePairs(), Pairs::key, Pairs::keylen, Pairs::needfree, pfree(), qsort, res, and Pairs::val.

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

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

◆ prseof()

static bool prseof ( HSParser state)
static

Definition at line 76 of file hstore_io.c.

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

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

◆ prssyntaxerror()

static bool prssyntaxerror ( HSParser state)
static

Definition at line 62 of file hstore_io.c.

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

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

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 24 of file hstore_io.c.