@@ -235,6 +235,43 @@ date_send(PG_FUNCTION_ARGS)
235235 PG_RETURN_BYTEA_P (pq_endtypsend (& buf ));
236236}
237237
238+ /*
239+ * make_date - date constructor
240+ */
241+ Datum
242+ make_date (PG_FUNCTION_ARGS )
243+ {
244+ struct pg_tm tm ;
245+ DateADT date ;
246+ int dterr ;
247+
248+ tm .tm_year = PG_GETARG_INT32 (0 );
249+ tm .tm_mon = PG_GETARG_INT32 (1 );
250+ tm .tm_mday = PG_GETARG_INT32 (2 );
251+
252+ /*
253+ * Note: we'll reject zero or negative year values. Perhaps negatives
254+ * should be allowed to represent BC years?
255+ */
256+ dterr = ValidateDate (DTK_DATE_M , false, false, false, & tm );
257+
258+ if (dterr != 0 )
259+ ereport (ERROR ,
260+ (errcode (ERRCODE_DATETIME_FIELD_OVERFLOW ),
261+ errmsg ("date field value out of range: %d-%02d-%02d" ,
262+ tm .tm_year , tm .tm_mon , tm .tm_mday )));
263+
264+ if (!IS_VALID_JULIAN (tm .tm_year , tm .tm_mon , tm .tm_mday ))
265+ ereport (ERROR ,
266+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
267+ errmsg ("date out of range: %d-%02d-%02d" ,
268+ tm .tm_year , tm .tm_mon , tm .tm_mday )));
269+
270+ date = date2j (tm .tm_year , tm .tm_mon , tm .tm_mday ) - POSTGRES_EPOCH_JDATE ;
271+
272+ PG_RETURN_DATEADT (date );
273+ }
274+
238275/*
239276 * Convert reserved date values to string.
240277 */
@@ -1208,6 +1245,39 @@ timetypmodout(PG_FUNCTION_ARGS)
12081245 PG_RETURN_CSTRING (anytime_typmodout (false, typmod ));
12091246}
12101247
1248+ /*
1249+ * make_time - time constructor
1250+ */
1251+ Datum
1252+ make_time (PG_FUNCTION_ARGS )
1253+ {
1254+ int tm_hour = PG_GETARG_INT32 (0 );
1255+ int tm_min = PG_GETARG_INT32 (1 );
1256+ double sec = PG_GETARG_FLOAT8 (2 );
1257+ TimeADT time ;
1258+
1259+ /* This should match the checks in DecodeTimeOnly */
1260+ if (tm_hour < 0 || tm_min < 0 || tm_min > MINS_PER_HOUR - 1 ||
1261+ sec < 0 || sec > SECS_PER_MINUTE ||
1262+ tm_hour > HOURS_PER_DAY ||
1263+ /* test for > 24:00:00 */
1264+ (tm_hour == HOURS_PER_DAY && (tm_min > 0 || sec > 0 )))
1265+ ereport (ERROR ,
1266+ (errcode (ERRCODE_DATETIME_FIELD_OVERFLOW ),
1267+ errmsg ("time field value out of range: %d:%02d:%02g" ,
1268+ tm_hour , tm_min , sec )));
1269+
1270+ /* This should match tm2time */
1271+ #ifdef HAVE_INT64_TIMESTAMP
1272+ time = (((tm_hour * MINS_PER_HOUR + tm_min ) * SECS_PER_MINUTE )
1273+ * USECS_PER_SEC ) + rint (sec * USECS_PER_SEC );
1274+ #else
1275+ time = ((tm_hour * MINS_PER_HOUR + tm_min ) * SECS_PER_MINUTE ) + sec ;
1276+ #endif
1277+
1278+ PG_RETURN_TIMEADT (time );
1279+ }
1280+
12111281
12121282/* time_transform()
12131283 * Flatten calls to time_scale() and timetz_scale() that solely represent
0 commit comments