Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit050710b

Browse files
author
Michael Meskes
committed
Add bytea datatype to ECPG.
So far ECPG programs had to treat binary data for bytea column as 'char' type.But this meant converting from/to escaped format with PQunescapeBytea/PQescapeBytea() and therefore forcing users to add unnecessary code and costfor the conversion in runtime. By adding a dedicated datatype for bytea most ofthis special handling is no longer needed.Author: Matsumura-san ("Matsumura, Ryo" <matsumura.ryo@jp.fujitsu.com>)Discussion:https://postgr.es/m/flat/03040DFF97E6E54E88D3BFEE5F5480F737A141F9@G01JPEXMBYT04
1 parent3fdc374 commit050710b

File tree

18 files changed

+983
-49
lines changed

18 files changed

+983
-49
lines changed

‎doc/src/sgml/ecpg.sgml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ do
917917

918918
<row>
919919
<entry><type>character(<replaceable>n</replaceable>)</type>, <type>varchar(<replaceable>n</replaceable>)</type>, <type>text</type></entry>
920-
<entry><type>char[<replaceable>n</replaceable>+1]</type>, <type>VARCHAR[<replaceable>n</replaceable>+1]</type><footnote><para>declared in <filename>ecpglib.h</filename></para></footnote></entry>
920+
<entry><type>char[<replaceable>n</replaceable>+1]</type>, <type>VARCHAR[<replaceable>n</replaceable>+1]</type></entry>
921921
</row>
922922

923923
<row>
@@ -947,7 +947,7 @@ do
947947

948948
<row>
949949
<entry><type>bytea</type></entry>
950-
<entry><type>char *</type></entry>
950+
<entry><type>char *</type>, <type>bytea[<replaceable>n</replaceable>]</type></entry>
951951
</row>
952952
</tbody>
953953
</tgroup>
@@ -1204,6 +1204,36 @@ EXEC SQL END DECLARE SECTION;
12041204
</programlisting>
12051205
</para>
12061206
</sect4>
1207+
1208+
<sect4>
1209+
<title id="ecpg-type-bytea">bytea</title>
1210+
1211+
<para>
1212+
The handling of the <type>bytea</type> type is also similar to
1213+
the <type>VARCHAR</type>. The definition on an array of type
1214+
<type>bytea</type> is converted into a named struct for every
1215+
variable. A declaration like:
1216+
<programlisting>
1217+
bytea var[180];
1218+
</programlisting>
1219+
is converted into:
1220+
<programlisting>
1221+
struct bytea_var { int len; char arr[180]; } var;
1222+
</programlisting>
1223+
The member <structfield>arr</structfield> hosts binary format
1224+
data. It also can handle even <literal>'\0'</literal> as part of
1225+
data unlike <type>VARCHAR</type>.
1226+
The data is converted from/to hex format and sent/received by
1227+
ecpglib.
1228+
</para>
1229+
1230+
<note>
1231+
<para>
1232+
<type>bytea</type> variable can be used only when
1233+
<xref linkend="guc-bytea-output"/> is set to <literal>hex</literal>.
1234+
</para>
1235+
</note>
1236+
</sect4>
12071237
</sect3>
12081238

12091239
<sect3 id="ecpg-variables-nonprimitive-c">

‎src/interfaces/ecpg/ecpglib/data.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,86 @@ check_special_value(char *ptr, double *retval, char **endptr)
122122
return false;
123123
}
124124

125+
/* imported from src/backend/utils/adt/encode.c */
126+
127+
unsigned
128+
ecpg_hex_enc_len(unsignedsrclen)
129+
{
130+
returnsrclen <<1;
131+
}
132+
133+
unsigned
134+
ecpg_hex_dec_len(unsignedsrclen)
135+
{
136+
returnsrclen >>1;
137+
}
138+
139+
staticinlinechar
140+
get_hex(charc)
141+
{
142+
staticconstint8hexlookup[128]= {
143+
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
144+
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
145+
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
146+
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
147+
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
148+
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
149+
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
150+
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
151+
};
152+
intres=-1;
153+
154+
if (c>0&&c<127)
155+
res=hexlookup[(unsignedchar)c];
156+
157+
return (char)res;
158+
}
159+
160+
staticunsigned
161+
hex_decode(constchar*src,unsignedlen,char*dst)
162+
{
163+
constchar*s,
164+
*srcend;
165+
charv1,
166+
v2,
167+
*p;
168+
169+
srcend=src+len;
170+
s=src;
171+
p=dst;
172+
while (s<srcend)
173+
{
174+
if (*s==' '||*s=='\n'||*s=='\t'||*s=='\r')
175+
{
176+
s++;
177+
continue;
178+
}
179+
v1=get_hex(*s++) <<4;
180+
if (s >=srcend)
181+
return-1;
182+
183+
v2=get_hex(*s++);
184+
*p++=v1 |v2;
185+
}
186+
187+
returnp-dst;
188+
}
189+
190+
unsigned
191+
ecpg_hex_encode(constchar*src,unsignedlen,char*dst)
192+
{
193+
staticconstcharhextbl[]="0123456789abcdef";
194+
constchar*end=src+len;
195+
196+
while (src<end)
197+
{
198+
*dst++=hextbl[(*src >>4)&0xF];
199+
*dst++=hextbl[*src&0xF];
200+
src++;
201+
}
202+
returnlen*2;
203+
}
204+
125205
bool
126206
ecpg_get_data(constPGresult*results,intact_tuple,intact_field,intlineno,
127207
enumECPGttypetype,enumECPGttypeind_type,
@@ -447,6 +527,55 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
447527
return false;
448528
break;
449529

530+
caseECPGt_bytea:
531+
{
532+
structECPGgeneric_varchar*variable=
533+
(structECPGgeneric_varchar*) (var+offset*act_tuple);
534+
longdst_size,
535+
src_size,
536+
dec_size;
537+
538+
dst_size=ecpg_hex_enc_len(varcharsize);
539+
src_size=size-2;/* exclude backslash + 'x' */
540+
dec_size=src_size<dst_size ?src_size :dst_size;
541+
variable->len=hex_decode(pval+2,dec_size,variable->arr);
542+
543+
if (dst_size<src_size)
544+
{
545+
longrcv_size=ecpg_hex_dec_len(size-2);
546+
547+
/* truncation */
548+
switch (ind_type)
549+
{
550+
caseECPGt_short:
551+
caseECPGt_unsigned_short:
552+
*((short*) (ind+ind_offset*act_tuple))=rcv_size;
553+
break;
554+
caseECPGt_int:
555+
caseECPGt_unsigned_int:
556+
*((int*) (ind+ind_offset*act_tuple))=rcv_size;
557+
break;
558+
caseECPGt_long:
559+
caseECPGt_unsigned_long:
560+
*((long*) (ind+ind_offset*act_tuple))=rcv_size;
561+
break;
562+
#ifdefHAVE_LONG_LONG_INT
563+
caseECPGt_long_long:
564+
caseECPGt_unsigned_long_long:
565+
*((long longint*) (ind+ind_offset*act_tuple))=rcv_size;
566+
break;
567+
#endif/* HAVE_LONG_LONG_INT */
568+
default:
569+
break;
570+
}
571+
sqlca->sqlwarn[0]=sqlca->sqlwarn[1]='W';
572+
}
573+
574+
pval+=size;
575+
576+
}
577+
break;
578+
450579
caseECPGt_char:
451580
caseECPGt_unsigned_char:
452581
caseECPGt_string:

‎src/interfaces/ecpg/ecpglib/descriptor.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,28 @@ ECPGset_desc_header(int lineno, const char *desc_name, int count)
587587
return true;
588588
}
589589

590+
staticvoid
591+
set_desc_attr(structdescriptor_item*desc_item,structvariable*var,
592+
char*tobeinserted)
593+
{
594+
if (var->type!=ECPGt_bytea)
595+
desc_item->is_binary= false;
596+
597+
else
598+
{
599+
structECPGgeneric_varchar*variable=
600+
(structECPGgeneric_varchar*) (var->value);
601+
602+
desc_item->is_binary= true;
603+
desc_item->data_len=variable->len;
604+
}
605+
606+
ecpg_free(desc_item->data);/* free() takes care of a
607+
* potential NULL value */
608+
desc_item->data= (char*)tobeinserted;
609+
}
610+
611+
590612
bool
591613
ECPGset_desc(intlineno,constchar*desc_name,intindex,...)
592614
{
@@ -666,9 +688,7 @@ ECPGset_desc(int lineno, const char *desc_name, int index,...)
666688
return false;
667689
}
668690

669-
ecpg_free(desc_item->data);/* free() takes care of a
670-
* potential NULL value */
671-
desc_item->data= (char*)tobeinserted;
691+
set_desc_attr(desc_item,var,tobeinserted);
672692
tobeinserted=NULL;
673693
break;
674694
}

‎src/interfaces/ecpg/ecpglib/ecpglib_extern.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ struct ECPGgeneric_varchar
4040
chararr[FLEXIBLE_ARRAY_MEMBER];
4141
};
4242

43+
/* A generic bytea type. */
44+
structECPGgeneric_bytea
45+
{
46+
intlen;
47+
chararr[FLEXIBLE_ARRAY_MEMBER];
48+
};
49+
4350
/*
4451
* type information cache
4552
*/
@@ -75,6 +82,8 @@ struct statement
7582
#endif
7683
intnparams;
7784
char**paramvalues;
85+
int*paramlengths;
86+
int*paramformats;
7887
PGresult*results;
7988
};
8089

@@ -133,6 +142,8 @@ struct descriptor_item
133142
intprecision;
134143
intscale;
135144
inttype;
145+
boolis_binary;
146+
intdata_len;
136147
structdescriptor_item*next;
137148
};
138149

@@ -226,6 +237,9 @@ struct sqlda_compat *ecpg_build_compat_sqlda(int, PGresult *, int, enum COMPAT_M
226237
voidecpg_set_compat_sqlda(int,structsqlda_compat**,constPGresult*,int,enumCOMPAT_MODE);
227238
structsqlda_struct*ecpg_build_native_sqlda(int,PGresult*,int,enumCOMPAT_MODE);
228239
voidecpg_set_native_sqlda(int,structsqlda_struct**,constPGresult*,int,enumCOMPAT_MODE);
240+
unsignedecpg_hex_dec_len(unsignedsrclen);
241+
unsignedecpg_hex_enc_len(unsignedsrclen);
242+
unsignedecpg_hex_encode(constchar*src,unsignedlen,char*dst);
229243

230244
/* SQLSTATE values generated or processed by ecpglib (intentionally
231245
* not exported -- users should refer to the codes directly) */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp