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

Commit6206a88

Browse files
committed
Add SQL99 CONVERT() function.
1 parent34f03b1 commit6206a88

File tree

15 files changed

+1237
-211
lines changed

15 files changed

+1237
-211
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 413 additions & 1 deletion
Large diffs are not rendered by default.

‎src/backend/catalog/namespace.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.27 2002/07/29 23:46:35 tgl Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.28 2002/08/06 05:40:44 ishii Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1238,6 +1238,43 @@ PopSpecialNamespace(Oid namespaceId)
12381238
namespaceSearchPathValid= false;
12391239
}
12401240

1241+
/*
1242+
* FindConversionByName - find a conversion by possibly qualified name
1243+
*/
1244+
OidFindConversionByName(List*name)
1245+
{
1246+
char*conversion_name;
1247+
OidnamespaceId;
1248+
Oidconoid;
1249+
List*lptr;
1250+
1251+
/* Convert list of names to a name and namespace */
1252+
namespaceId=QualifiedNameGetCreationNamespace(name,&conversion_name);
1253+
1254+
if (length(name)>1)
1255+
{
1256+
/* Check we have usage rights in target namespace */
1257+
if (pg_namespace_aclcheck(namespaceId,GetUserId(),ACL_USAGE)!=ACLCHECK_OK)
1258+
returnInvalidOid;
1259+
1260+
returnFindConversion(conversion_name,namespaceId);
1261+
}
1262+
1263+
recomputeNamespacePath();
1264+
1265+
foreach(lptr,namespaceSearchPath)
1266+
{
1267+
OidnamespaceId= (Oid)lfirsti(lptr);
1268+
1269+
conoid=FindConversion(conversion_name,namespaceId);
1270+
if (OidIsValid(conoid))
1271+
returnconoid;
1272+
}
1273+
1274+
/* Not found in path */
1275+
returnInvalidOid;
1276+
}
1277+
12411278
/*
12421279
* FindDefaultConversionProc - find default encoding cnnversion proc
12431280
*/

‎src/backend/catalog/pg_conversion.c

Lines changed: 74 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.4 2002/08/05 03:29:16 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.5 2002/08/06 05:40:45 ishii Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -221,7 +221,7 @@ RemoveConversionById(Oid conversionOid)
221221
if (HeapTupleIsValid(tuple=heap_getnext(scan,ForwardScanDirection)))
222222
simple_heap_delete(rel,&tuple->t_self);
223223
else
224-
elog(ERROR,"Conversion %u does not exist",conversionOid);
224+
elog(ERROR,"conversion %u does not exist",conversionOid);
225225
heap_endscan(scan);
226226
heap_close(rel,RowExclusiveLock);
227227
}
@@ -233,47 +233,6 @@ RemoveConversionById(Oid conversionOid)
233233
* If found, returns the procedure's oid, otherwise InvalidOid.
234234
* ---------------
235235
*/
236-
#ifdefNOT_USED
237-
OidFindDefaultConversion(Oidname_space,int4for_encoding,int4to_encoding)
238-
{
239-
Relationrel;
240-
HeapScanDescscan;
241-
ScanKeyDatascanKeyData;
242-
HeapTupletuple;
243-
Form_pg_conversionbody;
244-
Oidproc=InvalidOid;
245-
246-
/* Check we have usage rights in target namespace */
247-
if (pg_namespace_aclcheck(name_space,GetUserId(),ACL_USAGE)!=ACLCHECK_OK)
248-
returnInvalidOid;
249-
250-
ScanKeyEntryInitialize(&scanKeyData,
251-
0,
252-
Anum_pg_conversion_connamespace,
253-
F_OIDEQ,
254-
ObjectIdGetDatum(name_space));
255-
256-
rel=heap_openr(ConversionRelationName,AccessShareLock);
257-
scan=heap_beginscan(rel,SnapshotNow,
258-
1,&scanKeyData);
259-
260-
while (HeapTupleIsValid(tuple=heap_getnext(scan,ForwardScanDirection)))
261-
{
262-
body= (Form_pg_conversion)GETSTRUCT(tuple);
263-
if (body->conforencoding==for_encoding&&
264-
body->contoencoding==to_encoding&&
265-
body->condefault== TRUE)
266-
{
267-
proc=body->conproc;
268-
break;
269-
}
270-
}
271-
heap_endscan(scan);
272-
heap_close(rel,AccessShareLock);
273-
returnproc;
274-
}
275-
#endif
276-
277236
OidFindDefaultConversion(Oidname_space,int4for_encoding,int4to_encoding)
278237
{
279238
CatCList*catlist;
@@ -309,34 +268,27 @@ Oid FindDefaultConversion(Oid name_space, int4 for_encoding, int4 to_encoding)
309268
/* ----------------
310269
* FindConversionByName
311270
*
312-
* Find conversion proc by possibly qualified conversion name.
271+
* Find conversion by namespace and conversion name.
272+
* Returns conversion oid.
313273
* ---------------
314274
*/
315-
OidFindConversionByName(List*name)
275+
OidFindConversion(constchar*conname,Oidconnamespace)
316276
{
317277
HeapTupletuple;
318-
char*conversion_name;
319-
OidnamespaceId;
320278
Oidprocoid;
279+
Oidconoid;
321280
AclResultaclresult;
322281

323-
/* Convert list of names to a name and namespace */
324-
namespaceId=QualifiedNameGetCreationNamespace(name,&conversion_name);
325-
326-
/* Check we have usage rights in target namespace */
327-
if (pg_namespace_aclcheck(namespaceId,GetUserId(),ACL_USAGE)!=ACLCHECK_OK)
328-
returnInvalidOid;
329-
330-
/* search pg_conversion by namespaceId and conversion name */
282+
/* search pg_conversion by connamespace and conversion name */
331283
tuple=SearchSysCache(CONNAMESP,
332-
PointerGetDatum(conversion_name),
333-
ObjectIdGetDatum(namespaceId),
284+
PointerGetDatum(conname),
285+
ObjectIdGetDatum(connamespace),
334286
0,0);
335287

336288
if (!HeapTupleIsValid(tuple))
337289
returnInvalidOid;
338-
339290
procoid= ((Form_pg_conversion)GETSTRUCT(tuple))->conproc;
291+
conoid=HeapTupleGetOid(tuple);
340292

341293
ReleaseSysCache(tuple);
342294

@@ -345,6 +297,69 @@ Oid FindConversionByName(List *name)
345297
if (aclresult!=ACLCHECK_OK)
346298
returnInvalidOid;
347299

348-
returnprocoid;
300+
returnconoid;
349301
}
350302

303+
/*
304+
* Execute SQL99's CONVERT function.
305+
*
306+
* CONVERT <left paren> <character value expression>
307+
* USING <form-of-use conversion name> <right paren>
308+
*
309+
* TEXT convert3(TEXT string, OID conversion_oid);
310+
*/
311+
Datum
312+
pg_convert3(PG_FUNCTION_ARGS)
313+
{
314+
text*string=PG_GETARG_TEXT_P(0);
315+
Oidconvoid=PG_GETARG_OID(1);
316+
HeapTupletuple;
317+
Form_pg_conversionbody;
318+
text*retval;
319+
unsignedchar*str;
320+
unsignedchar*result;
321+
intlen;
322+
323+
if (!OidIsValid(convoid))
324+
elog(ERROR,"Conversion does not exist");
325+
326+
/* make sure that source string is null terminated */
327+
len=VARSIZE(string)-VARHDRSZ;
328+
str=palloc(len+1);
329+
memcpy(str,VARDATA(string),len);
330+
*(str+len)='\0';
331+
332+
tuple=SearchSysCache(CONOID,
333+
ObjectIdGetDatum(convoid),
334+
0,0,0);
335+
if (!HeapTupleIsValid(tuple))
336+
elog(ERROR,"Conversion %u search from syscache failed",convoid);
337+
338+
result=palloc(len*4+1);
339+
340+
body= (Form_pg_conversion)GETSTRUCT(tuple);
341+
OidFunctionCall5(body->conproc,
342+
Int32GetDatum(body->conforencoding),
343+
Int32GetDatum(body->contoencoding),
344+
CStringGetDatum(str),
345+
CStringGetDatum(result),
346+
Int32GetDatum(len));
347+
348+
ReleaseSysCache(tuple);
349+
350+
/* build text data type structre. we cannot use textin() here,
351+
since textin assumes that input string encoding is same as
352+
database encoding. */
353+
len=strlen(result)+VARHDRSZ;
354+
retval=palloc(len);
355+
VARATT_SIZEP(retval)=len;
356+
memcpy(VARDATA(retval),result,len-VARHDRSZ);
357+
358+
pfree(result);
359+
pfree(str);
360+
361+
/* free memory if allocated by the toaster */
362+
PG_FREE_IF_COPY(string,0);
363+
364+
PG_RETURN_TEXT_P(retval);
365+
}

‎src/backend/parser/gram.y

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.356 2002/08/05 02:30:50 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.357 2002/08/06 05:40:45 ishii Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -53,6 +53,7 @@
5353
#include"access/htup.h"
5454
#include"catalog/index.h"
5555
#include"catalog/namespace.h"
56+
#include"catalog/pg_conversion.h"
5657
#include"catalog/pg_type.h"
5758
#include"nodes/makefuncs.h"
5859
#include"nodes/params.h"
@@ -216,7 +217,8 @@ static void doNegateFloat(Value *v);
216217
insert_target_list,def_list,opt_indirection,
217218
group_clause,TriggerFuncArgs,select_limit,
218219
opt_select_limit,opclass_item_list,trans_options,
219-
TableFuncElementList,OptTableFuncElementList
220+
TableFuncElementList,OptTableFuncElementList,
221+
convert_args
220222

221223
%type<range>into_clause,OptTempTableName
222224

@@ -232,7 +234,7 @@ static void doNegateFloat(Value *v);
232234
%type<jtype>join_type
233235

234236
%type<list>extract_list,overlay_list,position_list
235-
%type<list>substr_list,trim_list
237+
%type<list>substr_list,trim_list,convert_list
236238
%type<ival>opt_interval
237239
%type<node>overlay_placing,substr_from,substr_for
238240

@@ -329,7 +331,7 @@ static void doNegateFloat(Value *v);
329331
CACHE, CALLED, CASCADE, CASE, CAST, CHAIN, CHAR_P,
330332
CHARACTER, CHARACTERISTICS, CHECK, CHECKPOINT, CLASS, CLOSE,
331333
CLUSTER, COALESCE, COLLATE, COLUMN, COMMENT, COMMIT,
332-
COMMITTED, CONSTRAINT, CONSTRAINTS, CONVERSION_P, COPY, CREATE, CREATEDB,
334+
COMMITTED, CONSTRAINT, CONSTRAINTS, CONVERSION_P,CONVERT,COPY, CREATE, CREATEDB,
333335
CREATEUSER, CROSS, CURRENT_DATE, CURRENT_TIME,
334336
CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, CYCLE,
335337

@@ -6253,6 +6255,15 @@ c_expr:columnref{ $$ = (Node *) $1; }
62536255
n->agg_distinct =FALSE;
62546256
$$ = (Node *)n;
62556257
}
6258+
|CONVERT'('convert_list')'
6259+
{
6260+
FuncCall *n = makeNode(FuncCall);
6261+
n->funcname = SystemFuncName("convert");
6262+
n->args =$3;
6263+
n->agg_star =FALSE;
6264+
n->agg_distinct =FALSE;
6265+
$$ = (Node *)n;
6266+
}
62566267
|select_with_parens%precUMINUS
62576268
{
62586269
SubLink *n = makeNode(SubLink);
@@ -6418,6 +6429,48 @@ trim_list:a_expr FROM expr_list{ $$ = lappend($3, $1); }
64186429
|expr_list{$$ =$1; }
64196430
;
64206431

6432+
/* CONVERT() arguments. We accept followings:
6433+
* SQL99 syntax
6434+
* o CONVERT(TEXT string USING conversion_name)
6435+
*
6436+
* Function calls
6437+
* o CONVERT(TEXT string, NAME src_encoding_name, NAME dest_encoding_name)
6438+
* o CONVERT(TEXT string, NAME encoding_name)
6439+
*/
6440+
convert_list:
6441+
a_exprUSINGany_name
6442+
{
6443+
Oid oid = FindConversionByName($3);
6444+
Const *convoid = makeNode(Const);
6445+
6446+
if (!OidIsValid(oid))
6447+
{
6448+
elog(ERROR,"Conversion\"%s\" does not exist",
6449+
NameListToString($3));
6450+
}
6451+
6452+
convoid->consttype = OIDOID;
6453+
convoid->constlen =sizeof(Oid);
6454+
convoid->constvalue = oid;
6455+
convoid->constisnull =FALSE;
6456+
convoid->constbyval =TRUE;
6457+
convoid->constisset =FALSE;
6458+
convoid->constiscast =FALSE;
6459+
$$ = makeList2($1, convoid);
6460+
}
6461+
| convert_args
6462+
{
6463+
$$ =$1;
6464+
}
6465+
|/*EMPTY*/
6466+
{$$ = NIL; }
6467+
;
6468+
6469+
convert_args:a_expr{$$ = makeList1($1); }
6470+
| convert_args',' a_expr{$$ = lappend($1,$3); }
6471+
;
6472+
6473+
64216474
in_expr:select_with_parens
64226475
{
64236476
SubLink *n = makeNode(SubLink);

‎src/backend/parser/keywords.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.123 2002/07/29 22:14:11 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.124 2002/08/06 05:40:45 ishii Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -80,6 +80,7 @@ static const ScanKeyword ScanKeywords[] = {
8080
{"constraint",CONSTRAINT},
8181
{"constraints",CONSTRAINTS},
8282
{"conversion",CONVERSION_P},
83+
{"convert",CONVERT},
8384
{"copy",COPY},
8485
{"create",CREATE},
8586
{"createdb",CREATEDB},

‎src/backend/utils/mb/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Makefile for utils/mb
55
#
66
# IDENTIFICATION
7-
# $Header: /cvsroot/pgsql/src/backend/utils/mb/Makefile,v 1.18 2002/07/18 02:02:30 ishii Exp $
7+
# $Header: /cvsroot/pgsql/src/backend/utils/mb/Makefile,v 1.19 2002/08/06 05:40:45 ishii Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -24,7 +24,7 @@ clean distclean maintainer-clean:
2424

2525
SUBSYS.o:$(OBJS)
2626
@for dirin$(DIRS);do$(MAKE) -C$$dir all||exit;done
27-
$(LD)$(LDREL)$(LDOUT)SUBSYS.o$(OBJS)
27+
$(LD)$(LDREL)$(LDOUT)$@$^
2828

2929
dependdep:
3030
$(CC) -MM$(CFLAGS)*.c>depend

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp