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

Commitcc4fede

Browse files
committed
Centralize json and jsonb handling of datetime types
The creates a single function JsonEncodeDateTime which will format thesedata types in an efficient and consistent manner. This will be all themore important when we come to jsonpath so we don't have to implement yetmore code doing the same thing in two more places.This also extends the code to handle time and timetz types which werenot previously handled specially. This requires exposing the time2tm andtimetz2tm functions.Patch from Nikita Glukhov
1 parentd91da5e commitcc4fede

File tree

5 files changed

+109
-95
lines changed

5 files changed

+109
-95
lines changed

‎src/backend/utils/adt/date.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
#endif
4242

4343

44-
staticinttime2tm(TimeADTtime,structpg_tm*tm,fsec_t*fsec);
45-
staticinttimetz2tm(TimeTzADT*time,structpg_tm*tm,fsec_t*fsec,int*tzp);
4644
staticinttm2time(structpg_tm*tm,fsec_tfsec,TimeADT*result);
4745
staticinttm2timetz(structpg_tm*tm,fsec_tfsec,inttz,TimeTzADT*result);
4846
staticvoidAdjustTimeForTypmod(TimeADT*time,int32typmod);
@@ -1249,7 +1247,7 @@ tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
12491247
* If out of this range, leave as UTC (in practice that could only happen
12501248
* if pg_time_t is just 32 bits) - thomas 97/05/27
12511249
*/
1252-
staticint
1250+
int
12531251
time2tm(TimeADTtime,structpg_tm*tm,fsec_t*fsec)
12541252
{
12551253
tm->tm_hour=time /USECS_PER_HOUR;
@@ -2073,7 +2071,7 @@ timetztypmodout(PG_FUNCTION_ARGS)
20732071
/* timetz2tm()
20742072
* Convert TIME WITH TIME ZONE data type to POSIX time structure.
20752073
*/
2076-
staticint
2074+
int
20772075
timetz2tm(TimeTzADT*time,structpg_tm*tm,fsec_t*fsec,int*tzp)
20782076
{
20792077
TimeOffsettrem=time->time;

‎src/backend/utils/adt/json.c

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,12 +1503,70 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
15031503
pfree(outputstr);
15041504
break;
15051505
caseJSONTYPE_DATE:
1506+
{
1507+
charbuf[MAXDATELEN+1];
1508+
1509+
JsonEncodeDateTime(buf,val,DATEOID);
1510+
appendStringInfo(result,"\"%s\"",buf);
1511+
}
1512+
break;
1513+
caseJSONTYPE_TIMESTAMP:
1514+
{
1515+
charbuf[MAXDATELEN+1];
1516+
1517+
JsonEncodeDateTime(buf,val,TIMESTAMPOID);
1518+
appendStringInfo(result,"\"%s\"",buf);
1519+
}
1520+
break;
1521+
caseJSONTYPE_TIMESTAMPTZ:
1522+
{
1523+
charbuf[MAXDATELEN+1];
1524+
1525+
JsonEncodeDateTime(buf,val,TIMESTAMPTZOID);
1526+
appendStringInfo(result,"\"%s\"",buf);
1527+
}
1528+
break;
1529+
caseJSONTYPE_JSON:
1530+
/* JSON and JSONB output will already be escaped */
1531+
outputstr=OidOutputFunctionCall(outfuncoid,val);
1532+
appendStringInfoString(result,outputstr);
1533+
pfree(outputstr);
1534+
break;
1535+
caseJSONTYPE_CAST:
1536+
/* outfuncoid refers to a cast function, not an output function */
1537+
jsontext=DatumGetTextPP(OidFunctionCall1(outfuncoid,val));
1538+
outputstr=text_to_cstring(jsontext);
1539+
appendStringInfoString(result,outputstr);
1540+
pfree(outputstr);
1541+
pfree(jsontext);
1542+
break;
1543+
default:
1544+
outputstr=OidOutputFunctionCall(outfuncoid,val);
1545+
escape_json(result,outputstr);
1546+
pfree(outputstr);
1547+
break;
1548+
}
1549+
}
1550+
1551+
/*
1552+
* Encode 'value' of datetime type 'typid' into JSON string in ISO format using
1553+
* optionally preallocated buffer 'buf'.
1554+
*/
1555+
char*
1556+
JsonEncodeDateTime(char*buf,Datumvalue,Oidtypid)
1557+
{
1558+
if (!buf)
1559+
buf=palloc(MAXDATELEN+1);
1560+
1561+
switch (typid)
1562+
{
1563+
caseDATEOID:
15061564
{
15071565
DateADTdate;
15081566
structpg_tmtm;
1509-
charbuf[MAXDATELEN+1];
15101567

1511-
date=DatumGetDateADT(val);
1568+
date=DatumGetDateADT(value);
1569+
15121570
/* Same as date_out(), but forcing DateStyle */
15131571
if (DATE_NOT_FINITE(date))
15141572
EncodeSpecialDate(date,buf);
@@ -1518,17 +1576,40 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
15181576
&(tm.tm_year),&(tm.tm_mon),&(tm.tm_mday));
15191577
EncodeDateOnly(&tm,USE_XSD_DATES,buf);
15201578
}
1521-
appendStringInfo(result,"\"%s\"",buf);
15221579
}
15231580
break;
1524-
caseJSONTYPE_TIMESTAMP:
1581+
caseTIMEOID:
1582+
{
1583+
TimeADTtime=DatumGetTimeADT(value);
1584+
structpg_tmtt,
1585+
*tm=&tt;
1586+
fsec_tfsec;
1587+
1588+
/* Same as time_out(), but forcing DateStyle */
1589+
time2tm(time,tm,&fsec);
1590+
EncodeTimeOnly(tm,fsec, false,0,USE_XSD_DATES,buf);
1591+
}
1592+
break;
1593+
caseTIMETZOID:
1594+
{
1595+
TimeTzADT*time=DatumGetTimeTzADTP(value);
1596+
structpg_tmtt,
1597+
*tm=&tt;
1598+
fsec_tfsec;
1599+
inttz;
1600+
1601+
/* Same as timetz_out(), but forcing DateStyle */
1602+
timetz2tm(time,tm,&fsec,&tz);
1603+
EncodeTimeOnly(tm,fsec, true,tz,USE_XSD_DATES,buf);
1604+
}
1605+
break;
1606+
caseTIMESTAMPOID:
15251607
{
15261608
Timestamptimestamp;
15271609
structpg_tmtm;
15281610
fsec_tfsec;
1529-
charbuf[MAXDATELEN+1];
15301611

1531-
timestamp=DatumGetTimestamp(val);
1612+
timestamp=DatumGetTimestamp(value);
15321613
/* Same as timestamp_out(), but forcing DateStyle */
15331614
if (TIMESTAMP_NOT_FINITE(timestamp))
15341615
EncodeSpecialTimestamp(timestamp,buf);
@@ -1538,19 +1619,17 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
15381619
ereport(ERROR,
15391620
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
15401621
errmsg("timestamp out of range")));
1541-
appendStringInfo(result,"\"%s\"",buf);
15421622
}
15431623
break;
1544-
caseJSONTYPE_TIMESTAMPTZ:
1624+
caseTIMESTAMPTZOID:
15451625
{
15461626
TimestampTztimestamp;
15471627
structpg_tmtm;
15481628
inttz;
15491629
fsec_tfsec;
15501630
constchar*tzn=NULL;
1551-
charbuf[MAXDATELEN+1];
15521631

1553-
timestamp=DatumGetTimestampTz(val);
1632+
timestamp=DatumGetTimestampTz(value);
15541633
/* Same as timestamptz_out(), but forcing DateStyle */
15551634
if (TIMESTAMP_NOT_FINITE(timestamp))
15561635
EncodeSpecialTimestamp(timestamp,buf);
@@ -1560,29 +1639,14 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
15601639
ereport(ERROR,
15611640
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
15621641
errmsg("timestamp out of range")));
1563-
appendStringInfo(result,"\"%s\"",buf);
15641642
}
15651643
break;
1566-
caseJSONTYPE_JSON:
1567-
/* JSON and JSONB output will already be escaped */
1568-
outputstr=OidOutputFunctionCall(outfuncoid,val);
1569-
appendStringInfoString(result,outputstr);
1570-
pfree(outputstr);
1571-
break;
1572-
caseJSONTYPE_CAST:
1573-
/* outfuncoid refers to a cast function, not an output function */
1574-
jsontext=DatumGetTextPP(OidFunctionCall1(outfuncoid,val));
1575-
outputstr=text_to_cstring(jsontext);
1576-
appendStringInfoString(result,outputstr);
1577-
pfree(outputstr);
1578-
pfree(jsontext);
1579-
break;
15801644
default:
1581-
outputstr=OidOutputFunctionCall(outfuncoid,val);
1582-
escape_json(result,outputstr);
1583-
pfree(outputstr);
1584-
break;
1645+
elog(ERROR,"unknown jsonb value datetime type oid %d",typid);
1646+
returnNULL;
15851647
}
1648+
1649+
returnbuf;
15861650
}
15871651

15881652
/*

‎src/backend/utils/adt/jsonb.c

Lines changed: 9 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -786,71 +786,19 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
786786
}
787787
break;
788788
caseJSONBTYPE_DATE:
789-
{
790-
DateADTdate;
791-
structpg_tmtm;
792-
charbuf[MAXDATELEN+1];
793-
794-
date=DatumGetDateADT(val);
795-
/* Same as date_out(), but forcing DateStyle */
796-
if (DATE_NOT_FINITE(date))
797-
EncodeSpecialDate(date,buf);
798-
else
799-
{
800-
j2date(date+POSTGRES_EPOCH_JDATE,
801-
&(tm.tm_year),&(tm.tm_mon),&(tm.tm_mday));
802-
EncodeDateOnly(&tm,USE_XSD_DATES,buf);
803-
}
804-
jb.type=jbvString;
805-
jb.val.string.len=strlen(buf);
806-
jb.val.string.val=pstrdup(buf);
807-
}
789+
jb.type=jbvString;
790+
jb.val.string.val=JsonEncodeDateTime(NULL,val,DATEOID);
791+
jb.val.string.len=strlen(jb.val.string.val);
808792
break;
809793
caseJSONBTYPE_TIMESTAMP:
810-
{
811-
Timestamptimestamp;
812-
structpg_tmtm;
813-
fsec_tfsec;
814-
charbuf[MAXDATELEN+1];
815-
816-
timestamp=DatumGetTimestamp(val);
817-
/* Same as timestamp_out(), but forcing DateStyle */
818-
if (TIMESTAMP_NOT_FINITE(timestamp))
819-
EncodeSpecialTimestamp(timestamp,buf);
820-
elseif (timestamp2tm(timestamp,NULL,&tm,&fsec,NULL,NULL)==0)
821-
EncodeDateTime(&tm,fsec, false,0,NULL,USE_XSD_DATES,buf);
822-
else
823-
ereport(ERROR,
824-
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
825-
errmsg("timestamp out of range")));
826-
jb.type=jbvString;
827-
jb.val.string.len=strlen(buf);
828-
jb.val.string.val=pstrdup(buf);
829-
}
794+
jb.type=jbvString;
795+
jb.val.string.val=JsonEncodeDateTime(NULL,val,TIMESTAMPOID);
796+
jb.val.string.len=strlen(jb.val.string.val);
830797
break;
831798
caseJSONBTYPE_TIMESTAMPTZ:
832-
{
833-
TimestampTztimestamp;
834-
structpg_tmtm;
835-
inttz;
836-
fsec_tfsec;
837-
constchar*tzn=NULL;
838-
charbuf[MAXDATELEN+1];
839-
840-
timestamp=DatumGetTimestampTz(val);
841-
/* Same as timestamptz_out(), but forcing DateStyle */
842-
if (TIMESTAMP_NOT_FINITE(timestamp))
843-
EncodeSpecialTimestamp(timestamp,buf);
844-
elseif (timestamp2tm(timestamp,&tz,&tm,&fsec,&tzn,NULL)==0)
845-
EncodeDateTime(&tm,fsec, true,tz,tzn,USE_XSD_DATES,buf);
846-
else
847-
ereport(ERROR,
848-
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
849-
errmsg("timestamp out of range")));
850-
jb.type=jbvString;
851-
jb.val.string.len=strlen(buf);
852-
jb.val.string.val=pstrdup(buf);
853-
}
799+
jb.type=jbvString;
800+
jb.val.string.val=JsonEncodeDateTime(NULL,val,TIMESTAMPTZOID);
801+
jb.val.string.len=strlen(jb.val.string.val);
854802
break;
855803
caseJSONBTYPE_JSONCAST:
856804
caseJSONBTYPE_JSON:

‎src/include/utils/date.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include<math.h>
1818

1919
#include"fmgr.h"
20-
20+
#include"datatype/timestamp.h"
2121

2222
typedefint32DateADT;
2323

@@ -73,5 +73,7 @@ extern void EncodeSpecialDate(DateADT dt, char *str);
7373
externDateADTGetSQLCurrentDate(void);
7474
externTimeTzADT*GetSQLCurrentTime(int32typmod);
7575
externTimeADTGetSQLLocalTime(int32typmod);
76+
externinttime2tm(TimeADTtime,structpg_tm*tm,fsec_t*fsec);
77+
externinttimetz2tm(TimeTzADT*time,structpg_tm*tm,fsec_t*fsec,int*tzp);
7678

7779
#endif/* DATE_H */

‎src/include/utils/jsonapi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,6 @@ extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state,
147147
externtext*transform_json_string_values(text*json,void*action_state,
148148
JsonTransformStringValuesActiontransform_action);
149149

150+
externchar*JsonEncodeDateTime(char*buf,Datumvalue,Oidtypid);
151+
150152
#endif/* JSONAPI_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp