PostgreSQL Source Code: src/backend/utils/adt/formatting.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60#ifdef DEBUG_TO_FROM_CHAR

61#define DEBUG_elog_output DEBUG3

62#endif

63

65

66#include <ctype.h>

68#include <math.h>

70#include <limits.h>

71#include <wctype.h>

72

73#ifdef USE_ICU

74#include <unicode/ustring.h>

75#endif

76

93

94

95

96

97

98

99#define DCH_FLAG 0x1

100#define NUM_FLAG 0x2

101#define STD_FLAG 0x4

102

103

104

105

106

107#define KeyWord_INDEX_SIZE ('~' - ' ')

108#define KeyWord_INDEX_FILTER(_c) ((_c) <= ' ' || (_c) >= '~' ? 0 : 1)

109

110

111

112

113

114#define DCH_MAX_ITEM_SIZ 12

115#define NUM_MAX_ITEM_SIZ 8

116

117

118

119

120

121

122typedef struct

123{

124 const char *name;

125 int len,

126 id,

127 type;

129

130

131

132

133

134

135

136

137typedef enum

138{

143

144typedef struct

145{

152

153typedef struct

154{

157 uint8 suffix;

160

161#define NODE_TYPE_END 1

162#define NODE_TYPE_ACTION 2

163#define NODE_TYPE_CHAR 3

164#define NODE_TYPE_SEPARATOR 4

165#define NODE_TYPE_SPACE 5

166

167#define SUFFTYPE_PREFIX 1

168#define SUFFTYPE_POSTFIX 2

169

170#define CLOCK_24_HOUR 0

171#define CLOCK_12_HOUR 1

172

173

174

175

176

177

179 "January", "February", "March", "April", "May", "June", "July",

180 "August", "September", "October", "November", "December", NULL

181};

182

184 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL

185};

186

187

188

189

190

191

192

193

194#define ADJUST_YEAR(year, is_interval) ((is_interval) ? (year) : ((year) <= 0 ? -((year) - 1) : (year)))

195

196#define A_D_STR "A.D."

197#define a_d_STR "a.d."

198#define AD_STR "AD"

199#define ad_STR "ad"

200

201#define B_C_STR "B.C."

202#define b_c_STR "b.c."

203#define BC_STR "BC"

204#define bc_STR "bc"

205

206

207

208

209

210

211

212

213

214

215

218

219

220

221

222

223#define A_M_STR "A.M."

224#define a_m_STR "a.m."

225#define AM_STR "AM"

226#define am_STR "am"

227

228#define P_M_STR "P.M."

229#define p_m_STR "p.m."

230#define PM_STR "PM"

231#define pm_STR "pm"

232

233

234

235

236

237

238

239

240

241

242

245

246

247

248

249

250

251

253{"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I", NULL};

254

256{"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i", NULL};

257

258

259

260

261

262static const char *const rm1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", NULL};

263static const char *const rm10[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", NULL};

264static const char *const rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", NULL};

265

266

267

268

269

270#define IS_VALID_SUB_COMB(curr, next) \

271 (((curr) == 'I' && ((next) == 'V' || (next) == 'X')) || \

272 ((curr) == 'X' && ((next) == 'L' || (next) == 'C')) || \

273 ((curr) == 'C' && ((next) == 'D' || (next) == 'M')))

274

275

276

277

278#define ROMAN_VAL(r) \

279 ((r) == 'I' ? 1 : \

280 (r) == 'V' ? 5 : \

281 (r) == 'X' ? 10 : \

282 (r) == 'L' ? 50 : \

283 (r) == 'C' ? 100 : \

284 (r) == 'D' ? 500 : \

285 (r) == 'M' ? 1000 : 0)

286

287

288

289

290#define MAX_ROMAN_LEN 15

291

292

293

294

295

296static const char *const numTH[] = {"ST", "ND", "RD", "TH", NULL};

297static const char *const numth[] = {"st", "nd", "rd", "th", NULL};

298

299

300

301

302

303#define TH_UPPER 1

304#define TH_LOWER 2

305

306

307

308

309

310typedef struct

311{

312 int pre,

313 post,

314 lsign,

315 flag,

317 multi,

322

323

324

325

326

327#define NUM_F_DECIMAL (1 << 1)

328#define NUM_F_LDECIMAL (1 << 2)

329#define NUM_F_ZERO (1 << 3)

330#define NUM_F_BLANK (1 << 4)

331#define NUM_F_FILLMODE (1 << 5)

332#define NUM_F_LSIGN (1 << 6)

333#define NUM_F_BRACKET (1 << 7)

334#define NUM_F_MINUS (1 << 8)

335#define NUM_F_PLUS (1 << 9)

336#define NUM_F_ROMAN (1 << 10)

337#define NUM_F_MULTI (1 << 11)

338#define NUM_F_PLUS_POST (1 << 12)

339#define NUM_F_MINUS_POST (1 << 13)

340#define NUM_F_EEEE (1 << 14)

341

342#define NUM_LSIGN_PRE (-1)

343#define NUM_LSIGN_POST 1

344#define NUM_LSIGN_NONE 0

345

346

347

348

349

350#define IS_DECIMAL(_f) ((_f)->flag & NUM_F_DECIMAL)

351#define IS_LDECIMAL(_f) ((_f)->flag & NUM_F_LDECIMAL)

352#define IS_ZERO(_f) ((_f)->flag & NUM_F_ZERO)

353#define IS_BLANK(_f) ((_f)->flag & NUM_F_BLANK)

354#define IS_FILLMODE(_f) ((_f)->flag & NUM_F_FILLMODE)

355#define IS_BRACKET(_f) ((_f)->flag & NUM_F_BRACKET)

356#define IS_MINUS(_f) ((_f)->flag & NUM_F_MINUS)

357#define IS_LSIGN(_f) ((_f)->flag & NUM_F_LSIGN)

358#define IS_PLUS(_f) ((_f)->flag & NUM_F_PLUS)

359#define IS_ROMAN(_f) ((_f)->flag & NUM_F_ROMAN)

360#define IS_MULTI(_f) ((_f)->flag & NUM_F_MULTI)

361#define IS_EEEE(_f) ((_f)->flag & NUM_F_EEEE)

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381#define DCH_CACHE_OVERHEAD \

382 MAXALIGN(sizeof(bool) + sizeof(int))

383#define NUM_CACHE_OVERHEAD \

384 MAXALIGN(sizeof(bool) + sizeof(int) + sizeof(NUMDesc))

385

386#define DCH_CACHE_SIZE \

387 ((2048 - DCH_CACHE_OVERHEAD) / (sizeof(FormatNode) + sizeof(char)) - 1)

388#define NUM_CACHE_SIZE \

389 ((1024 - NUM_CACHE_OVERHEAD) / (sizeof(FormatNode) + sizeof(char)) - 1)

390

391#define DCH_CACHE_ENTRIES 20

392#define NUM_CACHE_ENTRIES 20

393

394typedef struct

395{

402

403typedef struct

404{

411

412

414static int n_DCHCache = 0;

415static int DCHCounter = 0;

416

417

419static int n_NUMCache = 0;

420static int NUMCounter = 0;

421

422

423

424

425

426typedef struct

427{

434 d,

446 yysz,

447 clock,

448 tzsign,

451 ff;

452 bool has_tz;

453 int gmtoffset;

454 pg_tz *tzp;

455 char *abbrev;

457

458#define ZERO_tmfc(_X) memset(_X, 0, sizeof(TmFromChar))

459

460struct fmt_tz

461{

462 bool has_tz;

464};

465

466

467

468

469

470#ifdef DEBUG_TO_FROM_CHAR

471#define DEBUG_TMFC(_X) \

472 elog(DEBUG_elog_output, "TMFC:\nmode %d\nhh %d\npm %d\nmi %d\nss %d\nssss %d\nd %d\ndd %d\nddd %d\nmm %d\nms: %d\nyear %d\nbc %d\nww %d\nw %d\ncc %d\nj %d\nus: %d\nyysz: %d\nclock: %d", \

473 (_X)->mode, (_X)->hh, (_X)->pm, (_X)->mi, (_X)->ss, (_X)->ssss, \

474 (_X)->d, (_X)->dd, (_X)->ddd, (_X)->mm, (_X)->ms, (_X)->year, \

475 (_X)->bc, (_X)->ww, (_X)->w, (_X)->cc, (_X)->j, (_X)->us, \

476 (_X)->yysz, (_X)->clock)

477#define DEBUG_TM(_X) \

478 elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\

479 (_X)->tm_sec, (_X)->tm_year,\

480 (_X)->tm_min, (_X)->tm_wday, (_X)->tm_hour, (_X)->tm_yday,\

481 (_X)->tm_mday, (_X)->tm_isdst, (_X)->tm_mon)

482#else

483#define DEBUG_TMFC(_X)

484#define DEBUG_TM(_X)

485#endif

486

487

488

489

490

491

492

493

494

496{

506};

507

509{

510 struct fmt_tm tm;

512 const char *tzn;

514

515#define tmtcTm(_X) (&(_X)->tm)

516#define tmtcTzn(_X) ((_X)->tzn)

517#define tmtcFsec(_X) ((_X)->fsec)

518

519

520#define COPY_tm(_DST, _SRC) \

521do { \

522 (_DST)->tm_sec = (_SRC)->tm_sec; \

523 (_DST)->tm_min = (_SRC)->tm_min; \

524 (_DST)->tm_hour = (_SRC)->tm_hour; \

525 (_DST)->tm_mday = (_SRC)->tm_mday; \

526 (_DST)->tm_mon = (_SRC)->tm_mon; \

527 (_DST)->tm_year = (_SRC)->tm_year; \

528 (_DST)->tm_wday = (_SRC)->tm_wday; \

529 (_DST)->tm_yday = (_SRC)->tm_yday; \

530 (_DST)->tm_gmtoff = (_SRC)->tm_gmtoff; \

531} while(0)

532

533

534#define ZERO_tm(_X) \

535do { \

536 memset(_X, 0, sizeof(*(_X))); \

537 (_X)->tm_mday = (_X)->tm_mon = 1; \

538} while(0)

539

540#define ZERO_tmtc(_X) \

541do { \

542 ZERO_tm( tmtcTm(_X) ); \

543 tmtcFsec(_X) = 0; \

544 tmtcTzn(_X) = NULL; \

545} while(0)

546

547

548

549

550

551#define INVALID_FOR_INTERVAL \

552do { \

553 if (is_interval) \

554 ereport(ERROR, \

555 (errcode(ERRCODE_INVALID_DATETIME_FORMAT), \

556 errmsg("invalid format specification for an interval value"), \

557 errhint("Intervals are not tied to specific calendar dates."))); \

558} while(0)

559

560

561

562

563

564

565

566

567

568#define DCH_S_FM 0x01

569#define DCH_S_TH 0x02

570#define DCH_S_th 0x04

571#define DCH_S_SP 0x08

572#define DCH_S_TM 0x10

573

574

575

576

577

578#define S_THth(_s) ((((_s) & DCH_S_TH) || ((_s) & DCH_S_th)) ? 1 : 0)

579#define S_TH(_s) (((_s) & DCH_S_TH) ? 1 : 0)

580#define S_th(_s) (((_s) & DCH_S_th) ? 1 : 0)

581#define S_TH_TYPE(_s) (((_s) & DCH_S_TH) ? TH_UPPER : TH_LOWER)

582

583

584#define S_FM(_s) (((_s) & DCH_S_FM) ? 1 : 0)

585#define S_SP(_s) (((_s) & DCH_S_SP) ? 1 : 0)

586#define S_TM(_s) (((_s) & DCH_S_TM) ? 1 : 0)

587

588

589

590

591

592#define TM_SUFFIX_LEN 2

593

602

603 {NULL, 0, 0, 0}

604};

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635typedef enum

636{

651 DCH_FF1,

749

750

753

754typedef enum

755{

792

793

796

797

798

799

800

802

915

916

917 {NULL, 0, 0, 0, 0}

918};

919

920

921

922

923

924

925

927

929 {".", 1, NUM_DEC},

930 {"0", 1, NUM_0},

931 {"9", 1, NUM_9},

932 {"B", 1, NUM_B},

933 {"C", 1, NUM_C},

934 {"D", 1, NUM_D},

935 {"EEEE", 4, NUM_E},

936 {"FM", 2, NUM_FM},

937 {"G", 1, NUM_G},

938 {"L", 1, NUM_L},

939 {"MI", 2, NUM_MI},

940 {"PL", 2, NUM_PL},

942 {"RN", 2, NUM_RN},

943 {"SG", 2, NUM_SG},

946 {"TH", 2, NUM_TH},

947 {"V", 1, NUM_V},

948 {"b", 1, NUM_B},

949 {"c", 1, NUM_C},

950 {"d", 1, NUM_D},

951 {"eeee", 4, NUM_E},

952 {"fm", 2, NUM_FM},

953 {"g", 1, NUM_G},

954 {"l", 1, NUM_L},

955 {"mi", 2, NUM_MI},

956 {"pl", 2, NUM_PL},

958 {"rn", 2, NUM_rn},

959 {"sg", 2, NUM_SG},

962 {"th", 2, NUM_th},

963 {"v", 1, NUM_V},

964

965

966 {NULL, 0, 0}

967};

968

969

970

971

972

973

975

976

977

978

979

980 -1, -1, -1, -1, -1, -1, -1, -1,

981 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

982 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

983 -1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,

984 DCH_FF1, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, DCH_OF,

985 DCH_P_M, DCH_Q, DCH_RM, DCH_SSSSS, DCH_TZH, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY,

986 -1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,

987 DCH_day, -1, DCH_ff1, -1, DCH_hh24, DCH_iddd, DCH_j, -1, -1, DCH_mi,

988 -1, DCH_of, DCH_p_m, DCH_q, DCH_rm, DCH_sssss, DCH_tzh, DCH_us, -1, DCH_ww,

990

991

992};

993

994

995

996

997

999

1000

1001

1002

1003

1004 -1, -1, -1, -1, -1, -1, -1, -1,

1005 -1, -1, -1, -1, NUM_COMMA, -1, NUM_DEC, -1, NUM_0, -1,

1006 -1, -1, -1, -1, -1, -1, -1, NUM_9, -1, -1,

1007 -1, -1, -1, -1, -1, -1, NUM_B, NUM_C, NUM_D, NUM_E,

1008 NUM_FM, NUM_G, -1, -1, -1, -1, NUM_L, NUM_MI, -1, -1,

1009 NUM_PL, -1, NUM_RN, NUM_SG, NUM_TH, -1, NUM_V, -1, -1, -1,

1010 -1, -1, -1, -1, -1, -1, -1, -1, NUM_b, NUM_c,

1011 NUM_d, NUM_e, NUM_fm, NUM_g, -1, -1, -1, -1, NUM_l, NUM_mi,

1012 -1, -1, NUM_pl, -1, NUM_rn, NUM_sg, NUM_th, -1, NUM_v, -1,

1013 -1, -1, -1, -1, -1, -1

1014

1015

1016};

1017

1018

1019

1020

1021

1023{

1026

1033

1034 read_dec,

1035 read_post,

1036 read_pre;

1037

1038 char *number,

1039 *number_p,

1041 *inout_p,

1043

1050

1051

1052#define DCH_DATED 0x01

1053#define DCH_TIMED 0x02

1054#define DCH_ZONED 0x04

1055

1056

1057

1058

1059

1060

1061#define OVERLOAD_TEST (Np->inout_p >= Np->inout + input_len)

1062#define AMOUNT_TEST(s) (Np->inout_p <= Np->inout + (input_len - (s)))

1063

1064

1065

1066

1067

1068

1070 const int *index);

1076

1081

1082#ifdef DEBUG_TO_FROM_CHAR

1083static void dump_index(const KeyWord *k, const int *index);

1084static void dump_node(FormatNode *node, int max);

1085#endif

1086

1087static const char *get_th(char *num, int type);

1092 Node *escontext);

1094 Node *escontext);

1098 Node *escontext);

1103 const char *const *array,

1104 char **localized_array, Oid collid,

1108 int *fprec, uint32 *flags, Node *escontext);

1109static char *fill_str(char *str, int c, int max);

1118 char *number, int input_len, int to_char_out_pre_spaces,

1126

1127

1128

1129

1130

1131

1132

1133

1136{

1137 int poz;

1138

1140 return NULL;

1141

1142 if ((poz = *(index + (*str - ' '))) > -1)

1143 {

1144 const KeyWord *k = kw + poz;

1145

1146 do

1147 {

1148 if (strncmp(str, k->name, k->len) == 0)

1149 return k;

1150 k++;

1151 if (!k->name)

1152 return NULL;

1153 } while (*str == *k->name);

1154 }

1155 return NULL;

1156}

1157

1160{

1162

1163 for (s = suf; s->name != NULL; s++)

1164 {

1166 continue;

1167

1168 if (strncmp(str, s->name, s->len) == 0)

1169 return s;

1170 }

1171 return NULL;

1172}

1173

1174static bool

1176{

1177

1178 return (*str > 0x20 && *str < 0x7F &&

1179 !(*str >= 'A' && *str <= 'Z') &&

1180 !(*str >= 'a' && *str <= 'z') &&

1181 !(*str >= '0' && *str <= '9'));

1182}

1183

1184

1185

1186

1187

1188static void

1190{

1192 return;

1193

1196 (errcode(ERRCODE_SYNTAX_ERROR),

1197 errmsg("\"EEEE\" must be the last pattern used")));

1198

1199 switch (n->key->id)

1200 {

1204 (errcode(ERRCODE_SYNTAX_ERROR),

1205 errmsg("\"9\" must be ahead of \"PR\"")));

1207 {

1209 break;

1210 }

1212 ++num->post;

1213 else

1214 ++num->pre;

1215 break;

1216

1220 (errcode(ERRCODE_SYNTAX_ERROR),

1221 errmsg("\"0\" must be ahead of \"PR\"")));

1223 {

1226 }

1228 ++num->pre;

1229 else

1230 ++num->post;

1231

1233 break;

1234

1236 if (num->pre == 0 && num->post == 0 && (IS\_ZERO(num)))

1238 break;

1239

1243

1247 (errcode(ERRCODE_SYNTAX_ERROR),

1248 errmsg("multiple decimal points")));

1251 (errcode(ERRCODE_SYNTAX_ERROR),

1252 errmsg("cannot use \"V\" and decimal point together")));

1254 break;

1255

1258 break;

1259

1263 (errcode(ERRCODE_SYNTAX_ERROR),

1264 errmsg("cannot use \"S\" twice")));

1267 (errcode(ERRCODE_SYNTAX_ERROR),

1268 errmsg("cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together")));

1270 {

1275 }

1277 {

1281 }

1282 break;

1283

1287 (errcode(ERRCODE_SYNTAX_ERROR),

1288 errmsg("cannot use \"S\" and \"MI\" together")));

1292 break;

1293

1297 (errcode(ERRCODE_SYNTAX_ERROR),

1298 errmsg("cannot use \"S\" and \"PL\" together")));

1302 break;

1303

1307 (errcode(ERRCODE_SYNTAX_ERROR),

1308 errmsg("cannot use \"S\" and \"SG\" together")));

1311 break;

1312

1316 (errcode(ERRCODE_SYNTAX_ERROR),

1317 errmsg("cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together")));

1319 break;

1320

1325 (errcode(ERRCODE_SYNTAX_ERROR),

1326 errmsg("cannot use \"RN\" twice")));

1328 break;

1329

1333 break;

1334

1338 (errcode(ERRCODE_SYNTAX_ERROR),

1339 errmsg("cannot use \"V\" and decimal point together")));

1341 break;

1342

1346 (errcode(ERRCODE_SYNTAX_ERROR),

1347 errmsg("cannot use \"EEEE\" twice")));

1352 (errcode(ERRCODE_SYNTAX_ERROR),

1353 errmsg("\"EEEE\" is incompatible with other formats"),

1354 errdetail("\"EEEE\" may only be used together with digit and decimal point patterns.")));

1356 break;

1357 }

1358

1362 (errcode(ERRCODE_SYNTAX_ERROR),

1363 errmsg("\"RN\" is incompatible with other formats"),

1364 errdetail("\"RN\" may only be used together with \"FM\".")));

1365}

1366

1367

1368

1369

1370

1371

1372

1373

1374static void

1377{

1379

1380#ifdef DEBUG_TO_FROM_CHAR

1381 elog(DEBUG_elog_output, "to_char/number(): run parser");

1382#endif

1383

1384 n = node;

1385

1386 while (*str)

1387 {

1388 int suffix = 0;

1390

1391

1392

1393

1396 {

1397 suffix |= s->id;

1398 if (s->len)

1400 }

1401

1402

1403

1404

1406 {

1411

1412

1413

1414

1417

1418

1419

1420

1423 {

1425 if (s->len)

1427 }

1428

1429 n++;

1430 }

1431 else if (*str)

1432 {

1433 int chlen;

1434

1436 {

1437

1438

1439

1440

1441

1442 if (strchr("-./,':; ", *str) == NULL)

1444 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

1445 errmsg("invalid datetime format separator: \"%s\"",

1447

1448 if (*str == ' ')

1450 else

1452

1455 n->key = NULL;

1457 n++;

1459 }

1460 else if (*str == '"')

1461 {

1462

1463

1464

1466 while (*str)

1467 {

1468 if (*str == '"')

1469 {

1471 break;

1472 }

1473

1474 if (*str == '\\' && *(str + 1))

1480 n->key = NULL;

1482 n++;

1483 str += chlen;

1484 }

1485 }

1486 else

1487 {

1488

1489

1490

1491

1492 if (*str == '\\' && *(str + 1) == '"')

1495

1498 else if (isspace((unsigned char) *str))

1500 else

1502

1505 n->key = NULL;

1507 n++;

1508 str += chlen;

1509 }

1510 }

1511 }

1512

1515}

1516

1517

1518

1519

1520

1521#ifdef DEBUG_TO_FROM_CHAR

1522

1523#define DUMP_THth(_suf) (S_TH(_suf) ? "TH" : (S_th(_suf) ? "th" : " "))

1524#define DUMP_FM(_suf) (S_FM(_suf) ? "FM" : " ")

1525

1526static void

1528{

1530 int a;

1531

1532 elog(DEBUG_elog_output, "to_from-char(): DUMP FORMAT");

1533

1534 for (a = 0, n = node; a <= max; n++, a++)

1535 {

1537 elog(DEBUG_elog_output, "%d:\t NODE_TYPE_ACTION '%s'\t(%s,%s)",

1540 elog(DEBUG_elog_output, "%d:\t NODE_TYPE_CHAR '%s'",

1543 {

1544 elog(DEBUG_elog_output, "%d:\t NODE_TYPE_END", a);

1545 return;

1546 }

1547 else

1548 elog(DEBUG_elog_output, "%d:\t unknown NODE!", a);

1549 }

1550}

1551#endif

1552

1553

1554

1555

1556

1557

1558

1559

1560

1561

1562static const char *

1564{

1565 int len = strlen(num),

1566 last;

1567

1568 last = *(num + (len - 1));

1569 if (!isdigit((unsigned char) last))

1571 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

1572 errmsg("\"%s\" is not a number", num)));

1573

1574

1575

1576

1577

1578 if ((len > 1) && (num[len - 2] == '1'))

1579 last = 0;

1580

1581 switch (last)

1582 {

1583 case '1':

1585 return numTH[0];

1586 return numth[0];

1587 case '2':

1589 return numTH[1];

1590 return numth[1];

1591 case '3':

1593 return numTH[2];

1594 return numth[2];

1595 default:

1597 return numTH[3];

1598 return numth[3];

1599 }

1600}

1601

1602

1603

1604

1605

1606

1607static char *

1609{

1610 if (dest != num)

1611 strcpy(dest, num);

1613 return dest;

1614}

1615

1616

1617

1618

1619

1620

1621

1622

1623

1624

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636char *

1638{

1639 char *result;

1641

1642 if (!buff)

1643 return NULL;

1644

1646 {

1647

1648

1649

1650

1652 (errcode(ERRCODE_INDETERMINATE_COLLATION),

1653 errmsg("could not determine which collation to use for %s function",

1654 "lower()"),

1655 errhint("Use the COLLATE clause to set the collation explicitly.")));

1656 }

1657

1659

1660

1662 {

1664 }

1665 else

1666 {

1667 const char *src = buff;

1668 size_t srclen = nbytes;

1669 size_t dstsize;

1670 char *dst;

1671 size_t needed;

1672

1673

1674 dstsize = srclen + 1;

1675 dst = palloc(dstsize);

1676

1677 needed = pg_strlower(dst, dstsize, src, srclen, mylocale);

1678 if (needed + 1 > dstsize)

1679 {

1680

1681 dstsize = needed + 1;

1682 dst = repalloc(dst, dstsize);

1683 needed = pg_strlower(dst, dstsize, src, srclen, mylocale);

1684 Assert(needed + 1 <= dstsize);

1685 }

1686

1687 Assert(dst[needed] == '\0');

1688 result = dst;

1689 }

1690

1691 return result;

1692}

1693

1694

1695

1696

1697

1698

1699

1700char *

1702{

1703 char *result;

1705

1706 if (!buff)

1707 return NULL;

1708

1710 {

1711

1712

1713

1714

1716 (errcode(ERRCODE_INDETERMINATE_COLLATION),

1717 errmsg("could not determine which collation to use for %s function",

1718 "upper()"),

1719 errhint("Use the COLLATE clause to set the collation explicitly.")));

1720 }

1721

1723

1724

1726 {

1728 }

1729 else

1730 {

1731 const char *src = buff;

1732 size_t srclen = nbytes;

1733 size_t dstsize;

1734 char *dst;

1735 size_t needed;

1736

1737

1738 dstsize = srclen + 1;

1739 dst = palloc(dstsize);

1740

1741 needed = pg_strupper(dst, dstsize, src, srclen, mylocale);

1742 if (needed + 1 > dstsize)

1743 {

1744

1745 dstsize = needed + 1;

1746 dst = repalloc(dst, dstsize);

1747 needed = pg_strupper(dst, dstsize, src, srclen, mylocale);

1748 Assert(needed + 1 <= dstsize);

1749 }

1750

1751 Assert(dst[needed] == '\0');

1752 result = dst;

1753 }

1754

1755 return result;

1756}

1757

1758

1759

1760

1761

1762

1763

1764char *

1766{

1767 char *result;

1769

1770 if (!buff)

1771 return NULL;

1772

1774 {

1775

1776

1777

1778

1780 (errcode(ERRCODE_INDETERMINATE_COLLATION),

1781 errmsg("could not determine which collation to use for %s function",

1782 "initcap()"),

1783 errhint("Use the COLLATE clause to set the collation explicitly.")));

1784 }

1785

1787

1788

1790 {

1792 }

1793 else

1794 {

1795 const char *src = buff;

1796 size_t srclen = nbytes;

1797 size_t dstsize;

1798 char *dst;

1799 size_t needed;

1800

1801

1802 dstsize = srclen + 1;

1803 dst = palloc(dstsize);

1804

1805 needed = pg_strtitle(dst, dstsize, src, srclen, mylocale);

1806 if (needed + 1 > dstsize)

1807 {

1808

1809 dstsize = needed + 1;

1810 dst = repalloc(dst, dstsize);

1811 needed = pg_strtitle(dst, dstsize, src, srclen, mylocale);

1812 Assert(needed + 1 <= dstsize);

1813 }

1814

1815 Assert(dst[needed] == '\0');

1816 result = dst;

1817 }

1818

1819 return result;

1820}

1821

1822

1823

1824

1825

1826

1827

1828char *

1830{

1831 char *result;

1833

1834 if (!buff)

1835 return NULL;

1836

1838 {

1839

1840

1841

1842

1844 (errcode(ERRCODE_INDETERMINATE_COLLATION),

1845 errmsg("could not determine which collation to use for %s function",

1846 "lower()"),

1847 errhint("Use the COLLATE clause to set the collation explicitly.")));

1848 }

1849

1852 (errcode(ERRCODE_SYNTAX_ERROR),

1853 errmsg("Unicode case folding can only be performed if server encoding is UTF8")));

1854

1856

1857

1859 {

1861 }

1862 else

1863 {

1864 const char *src = buff;

1865 size_t srclen = nbytes;

1866 size_t dstsize;

1867 char *dst;

1868 size_t needed;

1869

1870

1871 dstsize = srclen + 1;

1872 dst = palloc(dstsize);

1873

1874 needed = pg_strfold(dst, dstsize, src, srclen, mylocale);

1875 if (needed + 1 > dstsize)

1876 {

1877

1878 dstsize = needed + 1;

1879 dst = repalloc(dst, dstsize);

1880 needed = pg_strfold(dst, dstsize, src, srclen, mylocale);

1881 Assert(needed + 1 <= dstsize);

1882 }

1883

1884 Assert(dst[needed] == '\0');

1885 result = dst;

1886 }

1887

1888 return result;

1889}

1890

1891

1892

1893

1894

1895

1896

1897char *

1899{

1900 char *result;

1901 char *p;

1902

1903 if (!buff)

1904 return NULL;

1905

1906 result = pnstrdup(buff, nbytes);

1907

1908 for (p = result; *p; p++)

1910

1911 return result;

1912}

1913

1914

1915

1916

1917

1918

1919

1920char *

1922{

1923 char *result;

1924 char *p;

1925

1926 if (!buff)

1927 return NULL;

1928

1929 result = pnstrdup(buff, nbytes);

1930

1931 for (p = result; *p; p++)

1933

1934 return result;

1935}

1936

1937

1938

1939

1940

1941

1942

1943char *

1945{

1946 char *result;

1947 char *p;

1948 int wasalnum = false;

1949

1950 if (!buff)

1951 return NULL;

1952

1953 result = pnstrdup(buff, nbytes);

1954

1955 for (p = result; *p; p++)

1956 {

1957 char c;

1958

1959 if (wasalnum)

1961 else

1963

1964 wasalnum = ((c >= 'A' && c <= 'Z') ||

1965 (c >= 'a' && c <= 'z') ||

1966 (c >= '0' && c <= '9'));

1967 }

1968

1969 return result;

1970}

1971

1972

1973

1974static char *

1976{

1978}

1979

1980static char *

1982{

1984}

1985

1986static char *

1988{

1990}

1991

1992static char *

1994{

1996}

1997

1998static char *

2000{

2002}

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013#define SKIP_THth(ptr, _suf) \

2014 do { \

2015 if (S_THth(_suf)) \

2016 { \

2017 if (*(ptr)) (ptr) += pg_mblen(ptr); \

2018 if (*(ptr)) (ptr) += pg_mblen(ptr); \

2019 } \

2020 } while (0)

2021

2022

2023#ifdef DEBUG_TO_FROM_CHAR

2024

2025

2026

2027

2028

2029static void

2030dump_index(const KeyWord *k, const int *index)

2031{

2032 int i,

2033 count = 0,

2034 free_i = 0;

2035

2036 elog(DEBUG_elog_output, "TO-FROM_CHAR: Dump KeyWord Index:");

2037

2039 {

2041 {

2042 elog(DEBUG_elog_output, "\t%c: %s, ", i + 32, k[index[i]].name);

2043 count++;

2044 }

2045 else

2046 {

2047 free_i++;

2048 elog(DEBUG_elog_output, "\t(%d) %c %d", i, i + 32, index[i]);

2049 }

2050 }

2051 elog(DEBUG_elog_output, "\n\t\tUsed positions: %d,\n\t\tFree positions: %d",

2052 count, free_i);

2053}

2054#endif

2055

2056

2057

2058

2059

2060static bool

2062{

2064 return false;

2065

2067 return true;

2068

2069

2070

2071

2072 n++;

2073

2074

2076 return true;

2077

2079 {

2081 return false;

2082

2083 return true;

2084 }

2085 else if (n->character[1] == '\0' &&

2086 isdigit((unsigned char) n->character[0]))

2087 return false;

2088

2089 return true;

2090}

2091

2092

2093static int

2095{

2096

2097

2098

2099

2100

2101 if (year < 70)

2102 return year + 2000;

2103

2104 else if (year < 100)

2105 return year + 1900;

2106

2107 else if (year < 520)

2108 return year + 2000;

2109

2110 else if (year < 1000)

2111 return year + 1000;

2112 else

2113 return year;

2114}

2115

2116

2117static int

2119{

2120 int len = 0;

2121

2122 while (*str && isspace((unsigned char) *str))

2123 {

2126 }

2127 return len;

2128}

2129

2130

2131

2132

2133

2134

2135

2136

2137

2138

2139static bool

2141 Node *escontext)

2142{

2144 {

2147 else if (tmfc->mode != mode)

2148 ereturn(escontext, false,

2149 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

2150 errmsg("invalid combination of date conventions"),

2151 errhint("Do not mix Gregorian and ISO week date "

2152 "conventions in a formatting template.")));

2153 }

2154 return true;

2155}

2156

2157

2158

2159

2160

2161

2162

2163

2164

2165

2166static bool

2168 Node *escontext)

2169{

2171 ereturn(escontext, false,

2172 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

2173 errmsg("conflicting values for \"%s\" field in formatting string",

2175 errdetail("This value contradicts a previous setting "

2176 "for the same field type.")));

2178 return true;

2179}

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192

2193

2194

2195

2196

2197

2198

2199

2200

2201

2202static int

2204 Node *escontext)

2205{

2206 long result;

2208 const char *init = *src;

2209 int used;

2210

2211

2212

2213

2215

2217 used = (int) strlcpy(copy, *src, len + 1);

2218

2220 {

2221

2222

2223

2224

2225 char *endptr;

2226

2227 errno = 0;

2228 result = strtol(init, &endptr, 10);

2229 *src = endptr;

2230 }

2231 else

2232 {

2233

2234

2235

2236

2237 char *last;

2238

2239 if (used < len)

2241 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

2242 errmsg("source string too short for \"%s\" formatting field",

2244 errdetail("Field requires %d characters, but only %d remain.",

2245 len, used),

2246 errhint("If your source string is not fixed-width, "

2247 "try using the \"FM\" modifier.")));

2248

2249 errno = 0;

2250 result = strtol(copy, &last, 10);

2251 used = last - copy;

2252

2253 if (used > 0 && used < len)

2255 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

2256 errmsg("invalid value \"%s\" for \"%s\"",

2258 errdetail("Field requires %d characters, but only %d could be parsed.",

2259 len, used),

2260 errhint("If your source string is not fixed-width, "

2261 "try using the \"FM\" modifier.")));

2262

2263 *src += used;

2264 }

2265

2266 if (*src == init)

2268 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

2269 errmsg("invalid value \"%s\" for \"%s\"",

2271 errdetail("Value must be an integer.")));

2272

2273 if (errno == ERANGE || result < INT_MIN || result > INT_MAX)

2275 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2276 errmsg("value for \"%s\" in source string is out of range",

2278 errdetail("Value must be in the range %d to %d.",

2279 INT_MIN, INT_MAX)));

2280

2281 if (dest != NULL)

2282 {

2284 return -1;

2285 }

2286

2287 return *src - init;

2288}

2289

2290

2291

2292

2293

2294

2295

2296

2297

2298

2299static int

2301 Node *escontext)

2302{

2304}

2305

2306

2307

2308

2309

2310

2311

2312

2313

2314

2315

2316

2317static int

2319{

2320 unsigned char firstc;

2321 const char *const *a;

2322

2323 *len = 0;

2324

2325

2327 return -1;

2328

2329

2331

2332 for (a = array; *a != NULL; a++)

2333 {

2334 const char *p;

2335 const char *n;

2336

2337

2339 continue;

2340

2341

2342 for (p = *a + 1, n = name + 1;; p++, n++)

2343 {

2344

2345 if (*p == '\0')

2346 {

2348 return a - array;

2349 }

2350

2351 if (*n == '\0')

2352 break;

2353

2356 break;

2357 }

2358 }

2359

2360 return -1;

2361}

2362

2363

2364

2365

2366

2367

2368

2369

2370

2371

2372

2373

2374static int

2376{

2377 char **a;

2378 char *upper_name;

2379 char *lower_name;

2380

2381 *len = 0;

2382

2383

2385 return -1;

2386

2387

2388

2389

2390

2391 for (a = array; *a != NULL; a++)

2392 {

2393 int element_len = strlen(*a);

2394

2395 if (strncmp(name, *a, element_len) == 0)

2396 {

2397 *len = element_len;

2398 return a - array;

2399 }

2400 }

2401

2402

2403

2404

2405

2407 lower_name = str_tolower(upper_name, strlen(upper_name), collid);

2408 pfree(upper_name);

2409

2410 for (a = array; *a != NULL; a++)

2411 {

2412 char *upper_element;

2413 char *lower_element;

2414 int element_len;

2415

2416

2418 lower_element = str_tolower(upper_element, strlen(upper_element),

2420 pfree(upper_element);

2421 element_len = strlen(lower_element);

2422

2423

2424 if (strncmp(lower_name, lower_element, element_len) == 0)

2425 {

2426 *len = element_len;

2427 pfree(lower_element);

2428 pfree(lower_name);

2429 return a - array;

2430 }

2431 pfree(lower_element);

2432 }

2433

2434 pfree(lower_name);

2435 return -1;

2436}

2437

2438

2439

2440

2441

2442

2443

2444

2445

2446

2447

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458static bool

2460 char **localized_array, Oid collid,

2462{

2463 int len;

2464

2465 if (localized_array == NULL)

2467 else

2469

2470 if (len <= 0)

2471 {

2472

2473

2474

2475

2476 char *copy = pstrdup(*src);

2477 char *c;

2478

2479 for (c = copy; *c; c++)

2480 {

2482 {

2483 *c = '\0';

2484 break;

2485 }

2486 }

2487

2488 ereturn(escontext, false,

2489 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

2490 errmsg("invalid value \"%s\" for \"%s\"",

2492 errdetail("The given value did not match any of "

2493 "the allowed values for this field.")));

2494 }

2495 *src += len;

2496 return true;

2497}

2498

2499

2500

2501

2502

2503

2504static void

2506{

2508 char *s;

2510 int i;

2511

2512

2514

2515 s = out;

2517 {

2519 {

2521 s += strlen(s);

2522 continue;

2523 }

2524

2525 switch (n->key->id)

2526 {

2531 s += strlen(s);

2532 break;

2537 s += strlen(s);

2538 break;

2543 s += strlen(s);

2544 break;

2549 s += strlen(s);

2550 break;

2553

2554

2555

2556

2557

2564 s += strlen(s);

2565 break;

2571 s += strlen(s);

2572 break;

2578 s += strlen(s);

2579 break;

2585 s += strlen(s);

2586 break;

2587

2588#define DCH_to_char_fsec(frac_fmt, frac_val) \

2589 sprintf(s, frac_fmt, (int) (frac_val)); \

2590 if (S_THth(n->suffix)) \

2591 str_numth(s, s, S_TH_TYPE(n->suffix)); \

2592 s += strlen(s)

2593

2594 case DCH_FF1:

2596 break;

2597 case DCH_FF2:

2599 break;

2601 case DCH_MS:

2603 break;

2604 case DCH_FF4:

2606 break;

2607 case DCH_FF5:

2609 break;

2611 case DCH_US:

2613 break;

2614#undef DCH_to_char_fsec

2622 s += strlen(s);

2623 break;

2627 {

2628

2630

2631 strcpy(s, p);

2633 s += strlen(s);

2634 }

2635 break;

2639 {

2641 s += strlen(s);

2642 }

2643 break;

2649 s += strlen(s);

2650 break;

2655 s += strlen(s);

2656 break;

2663 s += strlen(s);

2665 {

2668 s += strlen(s);

2669 }

2670 break;

2675 s += strlen(s);

2676 break;

2681 s += strlen(s);

2682 break;

2687 s += strlen(s);

2688 break;

2693 s += strlen(s);

2694 break;

2698 break;

2700 {

2702

2704 strcpy(s, str);

2705 else

2707 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2708 errmsg("localized string format value too long")));

2709 }

2710 else

2713 s += strlen(s);

2714 break;

2718 break;

2720 {

2722

2724 strcpy(s, str);

2725 else

2727 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2728 errmsg("localized string format value too long")));

2729 }

2730 else

2733 s += strlen(s);

2734 break;

2738 break;

2740 {

2742

2744 strcpy(s, str);

2745 else

2747 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2748 errmsg("localized string format value too long")));

2749 }

2750 else

2753 s += strlen(s);

2754 break;

2758 break;

2760 {

2762

2764 strcpy(s, str);

2765 else

2767 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2768 errmsg("localized string format value too long")));

2769 }

2770 else

2772 s += strlen(s);

2773 break;

2777 break;

2779 {

2781

2783 strcpy(s, str);

2784 else

2786 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2787 errmsg("localized string format value too long")));

2788 }

2789 else

2791 s += strlen(s);

2792 break;

2796 break;

2798 {

2800

2802 strcpy(s, str);

2803 else

2805 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2806 errmsg("localized string format value too long")));

2807 }

2808 else

2810 s += strlen(s);

2811 break;

2817 s += strlen(s);

2818 break;

2822 {

2824

2826 strcpy(s, str);

2827 else

2829 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2830 errmsg("localized string format value too long")));

2831 }

2832 else

2835 s += strlen(s);

2836 break;

2840 {

2842

2844 strcpy(s, str);

2845 else

2847 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2848 errmsg("localized string format value too long")));

2849 }

2850 else

2853 s += strlen(s);

2854 break;

2858 {

2860

2862 strcpy(s, str);

2863 else

2865 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2866 errmsg("localized string format value too long")));

2867 }

2868 else

2871 s += strlen(s);

2872 break;

2876 {

2878

2880 strcpy(s, str);

2881 else

2883 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2884 errmsg("localized string format value too long")));

2885 }

2886 else

2888 s += strlen(s);

2889 break;

2893 {

2895

2897 strcpy(s, str);

2898 else

2900 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2901 errmsg("localized string format value too long")));

2902 }

2903 else

2905 s += strlen(s);

2906 break;

2910 {

2912

2914 strcpy(s, str);

2915 else

2917 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

2918 errmsg("localized string format value too long")));

2919 }

2920 else

2922 s += strlen(s);

2923 break;

2932 s += strlen(s);

2933 break;

2938 s += strlen(s);

2939 break;

2945 s += strlen(s);

2946 break;

2952 s += strlen(s);

2953 break;

2959 s += strlen(s);

2960 break;

2966 s += strlen(s);

2967 break;

2970 break;

2974 s += strlen(s);

2975 break;

2977 if (is_interval)

2979 else

2980 {

2982

2984 else

2985

2987 }

2988 if (i <= 99 && i >= -99)

2990 else

2994 s += strlen(s);

2995 break;

3002 s += strlen(s);

3003 break;

3014 is_interval)));

3017 s += strlen(s);

3018 break;

3029 is_interval)) % 1000);

3032 s += strlen(s);

3033 break;

3044 is_interval)) % 100);

3047 s += strlen(s);

3048 break;

3057 is_interval)) % 10);

3060 s += strlen(s);

3061 break;

3063

3065

3066

3067

3068

3069

3071 break;

3072 else

3073 {

3074 int mon = 0;

3075 const char *const *months;

3076

3079 else

3081

3082

3083

3084

3085

3086

3088 {

3089

3090

3091

3092

3094 }

3096 {

3097

3098

3099

3100

3101

3102 mon = -1 * (tm->tm_mon + 1);

3103 }

3104 else

3105 {

3106

3107

3108

3109

3110

3112 }

3113

3116 s += strlen(s);

3117 }

3118 break;

3123 s += strlen(s);

3124 break;

3129 s += strlen(s);

3130 break;

3131 }

3132 }

3133

3134 *s = '\0';

3135}

3136

3137

3138

3139

3140

3141

3142

3143

3144

3145

3146

3147

3148

3149

3150

3151static void

3154{

3156 const char *s;

3157 int len,

3159 bool fx_mode = std;

3160

3161

3162 int extra_skip = 0;

3163

3164

3166

3167 for (n = node, s = in; n->type != NODE_TYPE_END && *s != '\0'; n++)

3168 {

3169

3170

3171

3172

3175 {

3176 while (*s != '\0' && isspace((unsigned char) *s))

3177 {

3178 s++;

3179 extra_skip++;

3180 }

3181 }

3182

3184 {

3185 if (std)

3186 {

3187

3188

3189

3190

3192

3194 s++;

3195 else

3197 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

3198 errmsg("unmatched format separator \"%c\"",

3200 }

3201 else if (!fx_mode)

3202 {

3203

3204

3205

3206

3207

3208

3209 extra_skip--;

3211 {

3212 s++;

3213 extra_skip++;

3214 }

3215 }

3216 else

3217 {

3218

3219

3220

3221

3222

3223

3225 }

3226 continue;

3227 }

3229 {

3230

3231

3232

3233

3234

3235 if (!fx_mode)

3236 {

3237

3238

3239

3240

3241

3242

3243 if (extra_skip > 0)

3244 extra_skip--;

3245 else

3247 }

3248 else

3249 {

3251

3252

3253

3254

3256 strncmp(s, n->character, chlen) != 0)

3258 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

3259 errmsg("unmatched format character \"%s\"",

3261

3262 s += chlen;

3263 }

3264 continue;

3265 }

3266

3268 return;

3269

3270 switch (n->key->id)

3271 {

3273 fx_mode = true;

3274 break;

3281 n, escontext))

3282 return;

3284 return;

3286 break;

3293 n, escontext))

3294 return;

3296 return;

3298 break;

3302 return;

3305 break;

3308 return;

3310 break;

3313 return;

3315 break;

3318 return;

3320 break;

3321 case DCH_MS:

3323 if (len < 0)

3324 return;

3325

3326

3327

3328

3329 out->ms *= len == 1 ? 100 :

3330 len == 2 ? 10 : 1;

3331

3333 break;

3341

3342 case DCH_US:

3345 out->ff, n, escontext);

3346 if (len < 0)

3347 return;

3348

3349 out->us *= len == 1 ? 100000 :

3350 len == 2 ? 10000 :

3351 len == 3 ? 1000 :

3352 len == 4 ? 100 :

3353 len == 5 ? 10 : 1;

3354

3356 break;

3359 return;

3361 break;

3364 {

3365 int tzlen;

3366

3369 &out->tzp);

3370 if (tzlen > 0)

3371 {

3373

3374 if (out->tzp)

3376 out->tzsign = 0;

3377 s += tzlen;

3378 break;

3379 }

3380 else if (isalpha((unsigned char) *s))

3381 {

3382

3383

3384

3385

3386

3387

3389 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

3390 errmsg("invalid value \"%s\" for \"%s\"",

3392 errdetail("Time zone abbreviation is not recognized.")));

3393 }

3394

3395 }

3396

3398

3399

3400 if (*s == '+' || *s == '-' || *s == ' ')

3401 {

3402 out->tzsign = *s == '-' ? -1 : +1;

3403 s++;

3404 }

3405 else

3406 {

3407 if (extra_skip > 0 && *(s - 1) == '-')

3409 else

3411 }

3413 return;

3414 if (*s == ':')

3415 {

3416 s++;

3418 escontext) < 0)

3419 return;

3420 }

3421 break;

3423

3424

3425

3426

3427

3428

3429

3430

3431 if (*s == '+' || *s == '-' || *s == ' ')

3432 {

3433 out->tzsign = *s == '-' ? -1 : +1;

3434 s++;

3435 }

3436 else

3437 {

3438 if (extra_skip > 0 && *(s - 1) == '-')

3440 else

3442 }

3443

3445 return;

3446 break;

3448

3452 return;

3453 break;

3460 n, escontext))

3461 return;

3463 return;

3464 break;

3471 n, escontext))

3472 return;

3474 return;

3475 break;

3482 n, escontext))

3483 return;

3485 return;

3486 break;

3493 n, escontext))

3494 return;

3496 return;

3497 break;

3500 return;

3502 break;

3509 n, escontext))

3510 return;

3512 return;

3513 out->d++;

3514 break;

3521 n, escontext))

3522 return;

3524 return;

3525 out->d++;

3526 break;

3529 return;

3531 break;

3534 return;

3536 break;

3539 return;

3541 break;

3544 return;

3546 break;

3549 return;

3550

3551 if (++out->d > 7)

3552 out->d = 1;

3554 break;

3558 return;

3560 break;

3562

3563

3564

3565

3566

3567

3568

3569

3570

3571

3572

3574 return;

3576 break;

3579 return;

3581 break;

3583 {

3584 int matched,

3585 years,

3586 millennia,

3587 nch;

3588

3589 matched = sscanf(s, "%d,%03d%n", &millennia, &years, &nch);

3590 if (matched < 2)

3592 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

3593 errmsg("invalid input string for \"Y,YYY\"")));

3594

3595

3599 (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),

3600 errmsg("value for \"Y,YYY\" in source string is out of range")));

3601

3603 return;

3604 out->yysz = 4;

3605 s += nch;

3607 }

3608 break;

3612 return;

3613 out->yysz = 4;

3615 break;

3619 if (len < 0)

3620 return;

3621 if (len < 4)

3623 out->yysz = 3;

3625 break;

3629 if (len < 0)

3630 return;

3631 if (len < 4)

3633 out->yysz = 2;

3635 break;

3639 if (len < 0)

3640 return;

3641 if (len < 4)

3643 out->yysz = 1;

3645 break;

3650 n, escontext))

3651 return;

3653 escontext))

3654 return;

3655 break;

3658 return;

3660 break;

3663 return;

3665 break;

3666 }

3667

3668

3669 if (!fx_mode)

3670 {

3671 extra_skip = 0;

3672 while (*s != '\0' && isspace((unsigned char) *s))

3673 {

3674 s++;

3675 extra_skip++;

3676 }

3677 }

3678 }

3679

3680

3681

3682

3683

3684 if (std)

3685 {

3688 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

3689 errmsg("input string is too short for datetime format")));

3690

3691 while (*s != '\0' && isspace((unsigned char) *s))

3692 s++;

3693

3694 if (*s != '\0')

3696 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

3697 errmsg("trailing characters remain in input string after datetime format")));

3698 }

3699}

3700

3701

3702

3703

3704

3705

3706

3707

3708static inline void

3710{

3712 {

3716 }

3717}

3718

3719

3720

3721

3722static int

3724{

3726 int flags = 0;

3727

3729 {

3731 continue;

3732

3733 switch (n->key->id)

3734 {

3736 break;

3750 case DCH_MS:

3751 case DCH_US:

3760 break;

3767 break;

3811 break;

3812 }

3813 }

3814

3815 return flags;

3816}

3817

3818

3821{

3823

3824

3826

3827

3828

3829

3831 {

3833

3834#ifdef DEBUG_TO_FROM_CHAR

3835 elog(DEBUG_elog_output, "cache is full (%d)", n_DCHCache);

3836#endif

3838 {

3840 {

3842 if (!ent->valid)

3843 {

3844 old = ent;

3845 break;

3846 }

3847 if (ent->age < old->age)

3848 old = ent;

3849 }

3850 }

3851#ifdef DEBUG_TO_FROM_CHAR

3852 elog(DEBUG_elog_output, "OLD: '%s' AGE: %d", old->str, old->age);

3853#endif

3854 old->valid = false;

3857

3858 return old;

3859 }

3860 else

3861 {

3862#ifdef DEBUG_TO_FROM_CHAR

3864#endif

3868 ent->valid = false;

3870 ent->std = std;

3872

3874 return ent;

3875 }

3876}

3877

3878

3881{

3882

3884

3886 {

3888

3889 if (ent->valid && strcmp(ent->str, str) == 0 && ent->std == std)

3890 {

3892 return ent;

3893 }

3894 }

3895

3896 return NULL;

3897}

3898

3899

3902{

3904

3906 {

3907

3908

3909

3910

3911

3913

3916

3917 ent->valid = true;

3918 }

3919 return ent;

3920}

3921

3922

3923

3924

3925

3926

3927static text *

3929{

3931 char *fmt_str,

3932 *result;

3933 bool incache;

3934 int fmt_len;

3936

3937

3938

3939

3941 fmt_len = strlen(fmt_str);

3942

3943

3944

3945

3947 *result = '\0';

3948

3950 {

3951

3952

3953

3954

3955 incache = false;

3956

3958

3961 }

3962 else

3963 {

3964

3965

3966

3968

3969 incache = true;

3971 }

3972

3973

3975

3976 if (!incache)

3978

3980

3981

3983

3985 return res;

3986}

3987

3988

3989

3990

3991

3992

3993

3994

3995

3998{

4001 *res;

4003 struct pg_tm tt;

4005 int thisdate;

4006

4009

4012

4015 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4016 errmsg("timestamp out of range")));

4017

4018

4020 tt.tm_wday = (thisdate + 1) % 7;

4022

4024

4027

4029}

4030

4033{

4036 *res;

4038 int tz;

4039 struct pg_tm tt;

4041 int thisdate;

4042

4045

4048

4051 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4052 errmsg("timestamp out of range")));

4053

4054

4056 tt.tm_wday = (thisdate + 1) % 7;

4058

4060

4063

4065}

4066

4067

4068

4069

4070

4071

4074{

4077 *res;

4081 *itm = &tt;

4082

4085

4088

4097

4098

4100

4103

4105}

4106

4107

4108

4109

4110

4111

4112

4113

4116{

4121 int tz;

4125 int fprec;

4126

4128 &tm, &fsec, &ftz, &fprec, NULL, NULL);

4129

4130

4133 else

4135

4138 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4139 errmsg("timestamp out of range")));

4140

4141

4142 if (fprec)

4144

4146}

4147

4148

4149

4150

4151

4152

4155{

4163

4165 &tm, &fsec, &ftz, NULL, NULL, NULL);

4166

4167

4170 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4171 errmsg("date out of range: \"%s\"",

4173

4175

4176

4179 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4180 errmsg("date out of range: \"%s\"",

4182

4184}

4185

4186

4187

4188

4189

4190

4191

4192

4193

4194

4195

4196

4197

4198

4199

4200

4203 Oid *typid, int32 *typmod, int *tz,

4204 Node *escontext)

4205{

4209 int fprec;

4211

4213 &tm, &fsec, &ftz, &fprec, &flags, escontext))

4214 return (Datum) 0;

4215

4216 *typmod = fprec ? fprec : -1;

4217

4219 {

4221 {

4223 {

4225

4227 {

4229 }

4230 else

4231 {

4232

4233

4234

4235

4236

4238

4240 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

4241 errmsg("missing time zone in input string for type timestamptz")));

4242 }

4243

4246 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4247 errmsg("timestamptz out of range")));

4248

4250

4251 *typid = TIMESTAMPTZOID;

4253 }

4254 else

4255 {

4257

4260 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4261 errmsg("timestamp out of range")));

4262

4264

4265 *typid = TIMESTAMPOID;

4267 }

4268 }

4269 else

4270 {

4272 {

4274 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

4275 errmsg("datetime format is zoned but not timed")));

4276 }

4277 else

4278 {

4280

4281

4284 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4285 errmsg("date out of range: \"%s\"",

4287

4290

4291

4294 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4295 errmsg("date out of range: \"%s\"",

4297

4298 *typid = DATEOID;

4300 }

4301 }

4302 }

4304 {

4306 {

4308

4310 {

4312 }

4313 else

4314 {

4315

4316

4317

4318

4319

4321

4323 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

4324 errmsg("missing time zone in input string for type timetz")));

4325 }

4326

4327 if (tm2timetz(&tm, fsec, *tz, result) != 0)

4329 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4330 errmsg("timetz out of range")));

4331

4333

4334 *typid = TIMETZOID;

4336 }

4337 else

4338 {

4340

4341 if (tm2time(&tm, fsec, &result) != 0)

4343 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),

4344 errmsg("time out of range")));

4345

4347

4348 *typid = TIMEOID;

4350 }

4351 }

4352 else

4353 {

4355 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

4356 errmsg("datetime format is not dated and not timed")));

4357 }

4358}

4359

4360

4361

4362

4363

4364bool

4366{

4367 bool incache;

4368 int fmt_len = strlen(fmt_str);

4369 int result;

4371

4373 {

4374

4375

4376

4377

4378 incache = false;

4379

4381

4384 }

4385 else

4386 {

4387

4388

4389

4391

4392 incache = true;

4394 }

4395

4397

4398 if (!incache)

4400

4402}

4403

4404

4405

4406

4407

4408

4409

4410

4411

4412

4413

4414

4415

4416

4417

4418

4419

4420

4421

4422

4423

4424

4425

4426

4427static bool

4430 int *fprec, uint32 *flags, Node *escontext)

4431{

4434 int fmt_len;

4435 char *date_str;

4436 int fmask;

4437 bool incache = false;

4438

4440 Assert(fsec != NULL);

4441

4443

4446 *fsec = 0;

4448 if (fprec)

4449 *fprec = 0;

4450 if (flags)

4451 *flags = 0;

4452 fmask = 0;

4453

4455

4456 if (fmt_len)

4457 {

4458 char *fmt_str;

4459

4461

4463 {

4464

4465

4466

4467

4469

4472 }

4473 else

4474 {

4475

4476

4477

4479

4480 incache = true;

4482 }

4483

4484#ifdef DEBUG_TO_FROM_CHAR

4485

4486

4487#endif

4488

4492 goto fail;

4493

4494 if (flags)

4496

4497 if (!incache)

4498 {

4501 }

4502 }

4503

4505

4506

4507

4508

4509 if (tmfc.ssss)

4510 {

4511 int x = tmfc.ssss;

4512

4518 }

4519

4520 if (tmfc.ss)

4522 if (tmfc.mi)

4524 if (tmfc.hh)

4526

4528 {

4530 {

4532 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

4533 errmsg("hour \"%d\" is invalid for the 12-hour clock",

4535 errhint("Use the 24-hour clock, or give an hour between 1 and 12.")));

4536 goto fail;

4537 }

4538

4543 }

4544

4545 if (tmfc.year)

4546 {

4547

4548

4549

4550

4551

4552

4553 if (tmfc.cc && tmfc.yysz <= 2)

4554 {

4555 if (tmfc.bc)

4556 tmfc.cc = -tmfc.cc;

4559 {

4560 int tmp;

4561

4562 if (tmfc.cc >= 0)

4563 {

4564

4565 tmp = tmfc.cc - 1;

4568 {

4571 escontext);

4572 goto fail;

4573 }

4574 }

4575 else

4576 {

4577

4578 tmp = tmfc.cc + 1;

4582 {

4585 escontext);

4586 goto fail;

4587 }

4588 }

4589 }

4590 else

4591 {

4592

4593 tm->tm_year = tmfc.cc * 100 + ((tmfc.cc >= 0) ? 0 : 1);

4594 }

4595 }

4596 else

4597 {

4598

4600 if (tmfc.bc)

4602

4605 }

4607 }

4608 else if (tmfc.cc)

4609 {

4610

4611 if (tmfc.bc)

4612 tmfc.cc = -tmfc.cc;

4613 if (tmfc.cc >= 0)

4614 {

4615

4616

4619 {

4622 escontext);

4623 goto fail;

4624 }

4625 }

4626 else

4627 {

4628

4629

4632 {

4635 escontext);

4636 goto fail;

4637 }

4638 }

4640 }

4641

4642 if (tmfc.j)

4643 {

4646 }

4647

4648 if (tmfc.ww)

4649 {

4651 {

4652

4653

4654

4655

4656 if (tmfc.d)

4658 else

4661 }

4662 else

4663 {

4664

4668 {

4670 date_str, "timestamp", escontext);

4671 goto fail;

4672 }

4673 }

4674 }

4675

4676 if (tmfc.w)

4677 {

4678

4682 {

4684 date_str, "timestamp", escontext);

4685 goto fail;

4686 }

4687 }

4688 if (tmfc.dd)

4689 {

4692 }

4693 if (tmfc.mm)

4694 {

4697 }

4698

4700 {

4701

4702

4703

4704

4705

4706

4707

4709 {

4711 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),

4712 errmsg("cannot calculate day of year without year information")));

4713 goto fail;

4714 }

4715

4717 {

4718 int j0;

4719

4721

4724 }

4725 else

4726 {

4727 const int *y;

4728 int i;

4729

4730 static const int ysum[2][13] = {

4731 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},

4732 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}};

4733

4735

4737 {

4738 if (tmfc.ddd <= y[i])

4739 break;

4740 }

4743

4746

4748 }

4749 }

4750

4751 if (tmfc.ms)

4752 {

4753 int tmp = 0;

4754

4755

4758 {

4760 date_str, "timestamp", escontext);

4761 goto fail;

4762 }

4763 }

4764 if (tmfc.us)

4765 *fsec += tmfc.us;

4766 if (fprec)

4767 *fprec = tmfc.ff;

4768

4769

4770 if (fmask != 0)

4771 {

4772

4773 int dterr = ValidateDate(fmask, true, false, false, tm);

4774

4775 if (dterr != 0)

4776 {

4777

4778

4779

4780

4781

4783 date_str, "timestamp", escontext);

4784 goto fail;

4785 }

4786 }

4787

4788

4793 {

4795 date_str, "timestamp", escontext);

4796 goto fail;

4797 }

4798

4799

4800

4801

4802

4803

4805 {

4806

4809 {

4811 date_str, "timestamp", escontext);

4812 goto fail;

4813 }

4814

4817

4818 if (tmfc.tzsign > 0)

4820 }

4821 else if (tmfc.has_tz)

4822 {

4823

4825 if (tmfc.tzp == NULL)

4826 {

4827

4829 }

4830 else

4831 {

4832

4834 tmfc.tzp);

4835 }

4836 }

4837

4839

4840 if (format && !incache)

4842 pfree(date_str);

4843

4844 return true;

4845

4846fail:

4847 if (format && !incache)

4849 pfree(date_str);

4850

4851 return false;

4852}

4853

4854

4855

4856

4857

4858

4859

4860static char *

4862{

4863 memset(str, c, max);

4864 *(str + max) = '\0';

4865 return str;

4866}

4867

4868#define zeroize_NUM(_n) \

4869do { \

4870 (_n)->flag = 0; \

4871 (_n)->lsign = 0; \

4872 (_n)->pre = 0; \

4873 (_n)->post = 0; \

4874 (_n)->pre_lsign_num = 0; \

4875 (_n)->need_locale = 0; \

4876 (_n)->multi = 0; \

4877 (_n)->zero_start = 0; \

4878 (_n)->zero_end = 0; \

4879} while(0)

4880

4881

4882static inline void

4884{

4886 {

4890 }

4891}

4892

4893

4896{

4898

4899

4901

4902

4903

4904

4906 {

4908

4909#ifdef DEBUG_TO_FROM_CHAR

4910 elog(DEBUG_elog_output, "Cache is full (%d)", n_NUMCache);

4911#endif

4913 {

4915 {

4917 if (!ent->valid)

4918 {

4919 old = ent;

4920 break;

4921 }

4922 if (ent->age < old->age)

4923 old = ent;

4924 }

4925 }

4926#ifdef DEBUG_TO_FROM_CHAR

4927 elog(DEBUG_elog_output, "OLD: \"%s\" AGE: %d", old->str, old->age);

4928#endif

4929 old->valid = false;

4932

4933 return old;

4934 }

4935 else

4936 {

4937#ifdef DEBUG_TO_FROM_CHAR

4939#endif

4943 ent->valid = false;

4946

4948 return ent;

4949 }

4950}

4951

4952

4955{

4956

4958

4960 {

4962

4963 if (ent->valid && strcmp(ent->str, str) == 0)

4964 {

4966 return ent;

4967 }

4968 }

4969

4970 return NULL;

4971}

4972

4973

4976{

4978

4980 {

4981

4982

4983

4984

4985

4987

4989

4992

4993 ent->valid = true;

4994 }

4995 return ent;

4996}

4997

4998

4999

5000

5001

5004{

5006 char *str;

5007

5009

5011 {

5012

5013

5014

5015

5017

5018 *shouldFree = true;

5019

5021

5024 }

5025 else

5026 {

5027

5028

5029

5031

5032 *shouldFree = false;

5033

5035

5036

5037

5038

5048 }

5049

5050#ifdef DEBUG_TO_FROM_CHAR

5051

5053#endif

5054

5057}

5058

5059

5060

5061

5062

5063

5064

5065static char *

5067{

5068 int len,

5069 num;

5070 char *p,

5071 *result,

5072 numstr[12];

5073

5075 *result = '\0';

5076

5077

5078

5079

5080

5081

5082 if (number > 3999 || number < 1)

5083 {

5085 return result;

5086 }

5087

5088

5089 len = snprintf(numstr, sizeof(numstr), "%d", number);

5091

5092 for (p = numstr; *p != '\0'; p++, --len)

5093 {

5094 num = *p - ('0' + 1);

5095 if (num < 0)

5096 continue;

5097

5098 switch (len)

5099 {

5100 case 4:

5101 while (num-- >= 0)

5102 strcat(result, "M");

5103 break;

5104 case 3:

5105 strcat(result, rm100[num]);

5106 break;

5107 case 2:

5108 strcat(result, rm10[num]);

5109 break;

5110 case 1:

5111 strcat(result, rm1[num]);

5112 break;

5113 }

5114 }

5115 return result;

5116}

5117

5118

5119

5120

5121

5122

5123

5124

5125static int

5127{

5128 int result = 0;

5129 int len;

5132 int repeatCount = 1;

5133 int vCount = 0,

5134 lCount = 0,

5135 dCount = 0;

5136 bool subtractionEncountered = false;

5137 int lastSubtractedValue = 0;

5138

5139

5140

5141

5142

5145

5146

5147

5148

5149

5150

5151

5153 {

5155 int currValue = ROMAN_VAL(currChar);

5156

5157 if (currValue == 0)

5158 break;

5159 romanChars[len] = currChar;

5160 romanValues[len] = currValue;

5162 }

5163

5164 if (len == 0)

5165 return -1;

5166

5167

5168 for (int i = 0; i < len; i++)

5169 {

5170 char currChar = romanChars[i];

5171 int currValue = romanValues[i];

5172

5173

5174

5175

5176

5177 if (subtractionEncountered && currValue >= lastSubtractedValue)

5178 return -1;

5179

5180

5181

5182

5183

5184 if ((vCount && currValue >= ROMAN_VAL('V')) ||

5185 (lCount && currValue >= ROMAN_VAL('L')) ||

5186 (dCount && currValue >= ROMAN_VAL('D')))

5187 return -1;

5188 if (currChar == 'V')

5189 vCount++;

5190 else if (currChar == 'L')

5191 lCount++;

5192 else if (currChar == 'D')

5193 dCount++;

5194

5195 if (i < len - 1)

5196 {

5197

5198 char nextChar = romanChars[i + 1];

5199 int nextValue = romanValues[i + 1];

5200

5201

5202

5203

5204

5205

5206 if (currValue < nextValue)

5207 {

5209 return -1;

5210

5211

5212

5213

5214

5215 if (repeatCount > 1)

5216 return -1;

5217

5218

5219

5220

5221

5222

5223 if ((vCount && nextValue >= ROMAN_VAL('V')) ||

5224 (lCount && nextValue >= ROMAN_VAL('L')) ||

5225 (dCount && nextValue >= ROMAN_VAL('D')))

5226 return -1;

5227 if (nextChar == 'V')

5228 vCount++;

5229 else if (nextChar == 'L')

5230 lCount++;

5231 else if (nextChar == 'D')

5232 dCount++;

5233

5234

5235

5236

5237

5238 i++;

5239

5240

5241 repeatCount = 1;

5242 subtractionEncountered = true;

5243 lastSubtractedValue = currValue;

5244 result += (nextValue - currValue);

5245 }

5246 else

5247 {

5248

5249 if (currChar == nextChar)

5250 {

5251 repeatCount++;

5252 if (repeatCount > 3)

5253 return -1;

5254 }

5255 else

5256 repeatCount = 1;

5257 result += currValue;

5258 }

5259 }

5260 else

5261 {

5262

5263 result += currValue;

5264 }

5265 }

5266

5267 return result;

5268}

5269

5270

5271

5272

5273

5274

5275static void

5277{

5279 {

5280 struct lconv *lconv;

5281

5282

5283

5284

5286

5287

5288

5289

5290 if (lconv->negative_sign && *lconv->negative_sign)

5292 else

5294

5295 if (lconv->positive_sign && *lconv->positive_sign)

5297 else

5299

5300

5301

5302

5303 if (lconv->decimal_point && *lconv->decimal_point)

5304 Np->decimal = lconv->decimal_point;

5305

5306 else

5308

5311

5312

5313

5314

5315

5316

5317

5318

5319 if (lconv->thousands_sep && *lconv->thousands_sep)

5321

5322 else if (strcmp(Np->decimal, ",") != 0)

5324 else

5326

5327

5328

5329

5330 if (lconv->currency_symbol && *lconv->currency_symbol)

5332 else

5334 }

5335 else

5336 {

5337

5338

5339

5343

5346 }

5347}

5348

5349

5350

5351

5352

5353

5354

5355

5356

5357static char *

5359{

5360 char *result,

5361 *p = strchr(num, '.');

5362

5363#ifdef DEBUG_TO_FROM_CHAR

5364 elog(DEBUG_elog_output, "get_last_relevant_decnum()");

5365#endif

5366

5367 if (!p)

5368 return NULL;

5369

5370 result = p;

5371

5372 while (*(++p))

5373 {

5374 if (*p != '0')

5375 result = p;

5376 }

5377

5378 return result;

5379}

5380

5381

5382

5383

5384

5385static void

5387{

5388 bool isread = false;

5389

5390#ifdef DEBUG_TO_FROM_CHAR

5391 elog(DEBUG_elog_output, " --- scan start --- id=%s",

5392 (id == NUM_0 || id == NUM_9) ? "NUM_0/9" : id == NUM_DEC ? "NUM_DEC" : "???");

5393#endif

5394

5396 return;

5397

5398 if (*Np->inout_p == ' ')

5400

5402 return;

5403

5404

5405

5406

5409 {

5410#ifdef DEBUG_TO_FROM_CHAR

5411 elog(DEBUG_elog_output, "Try read sign (%c), locale positive: %s, negative: %s",

5413#endif

5414

5415

5416

5417

5419 {

5420 int x = 0;

5421

5422#ifdef DEBUG_TO_FROM_CHAR

5423 elog(DEBUG_elog_output, "Try read locale pre-sign (%c)", *Np->inout_p);

5424#endif

5428 {

5431 }

5435 {

5438 }

5439 }

5440 else

5441 {

5442#ifdef DEBUG_TO_FROM_CHAR

5443 elog(DEBUG_elog_output, "Try read simple sign (%c)", *Np->inout_p);

5444#endif

5445

5446

5447

5448

5451 {

5452 *Np->number = '-';

5454 }

5455 else if (*Np->inout_p == '+')

5456 {

5457 *Np->number = '+';

5459 }

5460 }

5461 }

5462

5464 return;

5465

5466#ifdef DEBUG_TO_FROM_CHAR

5467 elog(DEBUG_elog_output, "Scan for numbers (%c), current number: '%s'", *Np->inout_p, Np->number);

5468#endif

5469

5470

5471

5472

5473 if (isdigit((unsigned char) *Np->inout_p))

5474 {

5476 return;

5477

5480

5483 else

5485

5486 isread = true;

5487

5488#ifdef DEBUG_TO_FROM_CHAR

5489 elog(DEBUG_elog_output, "Read digit (%c)", *Np->inout_p);

5490#endif

5491 }

5493 {

5494

5495

5496

5497

5498

5499 int x = strlen(Np->decimal);

5500

5501#ifdef DEBUG_TO_FROM_CHAR

5502 elog(DEBUG_elog_output, "Try read decimal point (%c)",

5504#endif

5506 {

5511 isread = true;

5512 }

5513 }

5514

5516 return;

5517

5518

5519

5520

5521

5522

5523

5524

5525

5526

5528 {

5529

5530

5531

5532

5533

5535 (Np->inout_p + 1) < Np->inout + input_len &&

5536 !isdigit((unsigned char) *(Np->inout_p + 1)))

5537 {

5538 int x;

5539 char *tmp = Np->inout_p++;

5540

5541#ifdef DEBUG_TO_FROM_CHAR

5542 elog(DEBUG_elog_output, "Try read locale post-sign (%c)", *Np->inout_p);

5543#endif

5547 {

5548 Np->inout_p += x - 1;

5550 }

5554 {

5555 Np->inout_p += x - 1;

5557 }

5558 if (*Np->number == ' ')

5559

5561 }

5562

5563

5564

5565

5566

5567

5568

5569

5570

5571

5572

5573 else if (isread == false && IS_LSIGN(Np->Num) == false &&

5575 {

5576#ifdef DEBUG_TO_FROM_CHAR

5577 elog(DEBUG_elog_output, "Try read simple post-sign (%c)", *Np->inout_p);

5578#endif

5579

5580

5581

5582

5584

5586 }

5587 }

5588}

5589

5590#define IS_PREDEC_SPACE(_n) \

5591 (IS_ZERO((_n)->Num)==false && \

5592 (_n)->number == (_n)->number_p && \

5593 *(_n)->number == '0' && \

5594 (_n)->Num->post != 0)

5595

5596

5597

5598

5599

5600static void

5602{

5603 int end;

5604

5606 return;

5607

5608

5609

5610#ifdef DEBUG_TO_FROM_CHAR

5611

5612

5613

5614

5615

5616 elog(DEBUG_elog_output,

5617 "SIGN_WROTE: %d, CURRENT: %d, NUMBER_P: \"%s\", INOUT: \"%s\"",

5622#endif

5624

5625

5626

5627

5628

5632 {

5634 {

5636 {

5637 if (Np->sign == '-')

5639 else

5643 }

5644 }

5646 {

5647 *Np->inout_p = Np->sign == '+' ? ' ' : '<';

5650 }

5651 else if (Np->sign == '+')

5652 {

5654 {

5655 *Np->inout_p = ' ';

5657 }

5659 }

5660 else if (Np->sign == '-')

5661 {

5665 }

5666 }

5667

5668

5669

5670

5671

5673 {

5676 {

5677

5678

5679

5681 {

5682 *Np->inout_p = ' ';

5684 }

5685 }

5689 {

5690

5691

5692

5693 *Np->inout_p = '0';

5696 }

5697 else

5698 {

5699

5700

5701

5703 {

5705 {

5708 }

5709

5710

5711

5712

5715 {

5718 }

5719 }

5720 else

5721 {

5722

5723

5724

5727 ;

5728

5729

5730

5731

5733 {

5735 {

5738 }

5739

5740

5741

5742

5744 {

5747 }

5748 }

5749 else

5750 {

5754 }

5755 }

5756

5759 }

5760

5762

5765

5766 if (Np->num_curr + 1 == end)

5767 {

5769 {

5770 *Np->inout_p = Np->sign == '+' ? ' ' : '>';

5772 }

5774 {

5775 if (Np->sign == '-')

5777 else

5780 }

5781 }

5782 }

5783

5785}

5786

5787

5788

5789

5790static void

5792{

5793 while (n-- > 0)

5794 {

5796 break;

5797 if (strchr("0123456789.,+-", *Np->inout_p) != NULL)

5798 break;

5800 }

5801}

5802

5803static char *

5805 char *number, int input_len, int to_char_out_pre_spaces,

5807{

5810 *Np = &_Np;

5811 const char *pattern;

5812 int pattern_len;

5813

5815

5816 Np->Num = Num;

5818 Np->number = number;

5819 Np->inout = inout;

5824

5827

5829 {

5832 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

5833 errmsg("\"EEEE\" not supported for input")));

5834 return strcpy(inout, number);

5835 }

5836

5837

5838

5839

5840 if (is_to_char)

5841 {

5843

5844

5846 {

5848 Np->sign_wrote = false;

5849 else

5850 Np->sign_wrote = true;

5851 }

5852 else

5853 {

5854 if (Np->sign != '-')

5855 {

5857 Np->Num->flag &= ~NUM_F_BRACKET;

5858 }

5859

5861 Np->sign_wrote = true;

5862 else

5863 Np->sign_wrote = false;

5864

5867 }

5868 }

5869 else

5870 Np->sign = false;

5871

5872

5873

5874

5876

5877 if (is_to_char)

5878 {

5880

5882 {

5884

5885

5886

5887

5888

5889

5890

5892 {

5893 int last_zero_pos;

5894 char *last_zero;

5895

5896

5897 last_zero_pos = strlen(Np->number) - 1;

5898 last_zero_pos = Min(last_zero_pos,

5900 last_zero = Np->number + last_zero_pos;

5903 }

5904 }

5905

5908 }

5909 else

5910 {

5912 *Np->number = ' ';

5913 *(Np->number + 1) = '\0';

5914 }

5915

5918

5919#ifdef DEBUG_TO_FROM_CHAR

5920 elog(DEBUG_elog_output,

5921 "\n\tSIGN: '%c'\n\tNUM: '%s'\n\tPRE: %d\n\tPOST: %d\n\tNUM_COUNT: %d\n\tNUM_PRE: %d\n\tSIGN_WROTE: %s\n\tZERO: %s\n\tZERO_START: %d\n\tZERO_END: %d\n\tLAST_RELEVANT: %s\n\tBRACKET: %s\n\tPLUS: %s\n\tMINUS: %s\n\tFILLMODE: %s\n\tROMAN: %s\n\tEEEE: %s",

5939 );

5940#endif

5941

5942

5943

5944

5946

5947

5948

5949

5952 else

5953 Np->number_p = Np->number + 1;

5954

5956 {

5958 {

5959

5960

5961

5962

5963

5965 break;

5966 }

5967

5968

5969

5970

5972 {

5973

5974

5975

5976

5977

5978

5979

5980

5981

5982

5983

5984

5985 switch (n->key->id)

5986 {

5992 {

5994 continue;

5995 }

5996 else

5997 {

5999 break;

6000 }

6001

6004 {

6006 {

6008 continue;

6009 else

6011 }

6012 else

6014 }

6015 else

6016 {

6018 {

6020 continue;

6021 }

6022 if (*Np->inout_p != ',')

6023 continue;

6024 }

6025 break;

6026

6029 pattern_len = strlen(pattern);

6031 {

6033 {

6035 continue;

6036 else

6037 {

6038

6040 memset(Np->inout_p, ' ', pattern_len);

6041 Np->inout_p += pattern_len - 1;

6042 }

6043 }

6044 else

6045 {

6046 strcpy(Np->inout_p, pattern);

6047 Np->inout_p += pattern_len - 1;

6048 }

6049 }

6050 else

6051 {

6053 {

6055 continue;

6056 }

6057

6058

6059

6060

6061

6062

6063

6065 strncmp(Np->inout_p, pattern, pattern_len) == 0)

6066 Np->inout_p += pattern_len - 1;

6067 else

6068 continue;

6069 }

6070 break;

6071

6075 {

6076 strcpy(Np->inout_p, pattern);

6077 Np->inout_p += strlen(pattern) - 1;

6078 }

6079 else

6080 {

6082 continue;

6083 }

6084 break;

6085

6089 {

6090 const char *number_p;

6091

6094 else

6097 strcpy(Np->inout_p, number_p);

6098 else

6101 }

6102 else

6103 {

6104 int roman_result = roman_to_int(Np, input_len);

6105 int numlen;

6106

6107 if (roman_result < 0)

6109 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),

6110 errmsg("invalid Roman numeral")));

6113 Np->Num->pre = numlen;

6115 continue;

6116 }

6117 break;

6118

6122 continue;

6123

6125 {

6128 }

6129 else

6130 {

6131

6133 continue;

6134 }

6135 break;

6136

6140 continue;

6141

6143 {

6146 }

6147 else

6148 {

6149

6151 continue;

6152 }

6153 break;

6154

6157 {

6158 if (Np->sign == '-')

6161 continue;

6162 else

6164 }

6165 else

6166 {

6167 if (*Np->inout_p == '-')

6169 else

6170 {

6172 continue;

6173 }

6174 }

6175 break;

6176

6179 {

6180 if (Np->sign == '+')

6183 continue;

6184 else

6186 }

6187 else

6188 {

6189 if (*Np->inout_p == '+')

6191 else

6192 {

6194 continue;

6195 }

6196 }

6197 break;

6198

6202 else

6203 {

6204 if (*Np->inout_p == '-')

6206 else if (*Np->inout_p == '+')

6208 else

6209 {

6211 continue;

6212 }

6213 }

6214 break;

6215

6216 default:

6217 continue;

6218 break;

6219 }

6220 }

6221 else

6222 {

6223

6224

6225

6226

6227

6228

6230 {

6233 }

6234 else

6235 {

6237 }

6238 continue;

6239 }

6241 }

6242

6244 {

6246 return Np->inout;

6247 }

6248 else

6249 {

6250 if (*(Np->number_p - 1) == '.')

6252 else

6254

6255

6256

6257

6259

6260#ifdef DEBUG_TO_FROM_CHAR

6261 elog(DEBUG_elog_output, "TO_NUMBER (number): '%s'", Np->number);

6262#endif

6264 }

6265}

6266

6267

6268

6269

6270

6271

6272#define NUM_TOCHAR_prepare \

6273do { \

6274 int len = VARSIZE_ANY_EXHDR(fmt); \

6275 if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ) \

6276 PG_RETURN_TEXT_P(cstring_to_text("")); \

6277 result = (text *) palloc0((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \

6278 format = NUM_cache(len, &Num, fmt, &shouldFree); \

6279} while (0)

6280

6281

6282

6283

6284

6285#define NUM_TOCHAR_finish \

6286do { \

6287 int len; \

6288 \

6289 NUM_processor(format, &Num, VARDATA(result), numstr, 0, out_pre_spaces, sign, true, PG_GET_COLLATION()); \

6290 \

6291 if (shouldFree) \

6292 pfree(format); \

6293 \

6294

6295

6296

6297

6298 \

6299 len = strlen(VARDATA(result)); \

6300 SET_VARSIZE(result, len + VARHDRSZ); \

6301} while (0)

6302

6303

6304

6305

6306

6309{

6315 char *numstr;

6316 bool shouldFree;

6317 int len = 0;

6319 precision;

6320

6322

6325

6327

6329

6332

6335

6336 if (shouldFree)

6338

6343

6345 {

6349

6354 result,

6356 }

6357

6359 return result;

6360}

6361

6362

6363

6364

6365

6368{

6373 text *result;

6374 bool shouldFree;

6375 int out_pre_spaces = 0,

6377 char *numstr,

6378 *orgnum,

6379 *p;

6380

6382

6383

6384

6385

6387 {

6389 bool err;

6390

6391

6393

6394 if (err)

6397 }

6399 {

6401

6402

6403

6404

6405

6406

6407

6408 if (strcmp(orgnum, "NaN") == 0 ||

6409 strcmp(orgnum, "Infinity") == 0 ||

6410 strcmp(orgnum, "-Infinity") == 0)

6411 {

6412

6413

6414

6415

6416 numstr = (char *) palloc(Num.pre + Num.post + 7);

6418 *numstr = ' ';

6419 *(numstr + Num.pre + 1) = '.';

6420 }

6421 else if (*orgnum != '-')

6422 {

6423 numstr = (char *) palloc(strlen(orgnum) + 2);

6424 *numstr = ' ';

6425 strcpy(numstr + 1, orgnum);

6426 }

6427 else

6428 {

6429 numstr = orgnum;

6430 }

6431 }

6432 else

6433 {

6434 int numstr_pre_len;

6437

6439 {

6442

6450 }

6451

6457

6458 if (*orgnum == '-')

6459 {

6461 numstr = orgnum + 1;

6462 }

6463 else

6464 {

6466 numstr = orgnum;

6467 }

6468

6469 if ((p = strchr(numstr, '.')))

6470 numstr_pre_len = p - numstr;

6471 else

6472 numstr_pre_len = strlen(numstr);

6473

6474

6475 if (numstr_pre_len < Num.pre)

6476 out_pre_spaces = Num.pre - numstr_pre_len;

6477

6478 else if (numstr_pre_len > Num.pre)

6479 {

6480 numstr = (char *) palloc(Num.pre + Num.post + 2);

6482 *(numstr + Num.pre) = '.';

6483 }

6484 }

6485

6488}

6489

6490

6491

6492

6493

6496{

6501 text *result;

6502 bool shouldFree;

6503 int out_pre_spaces = 0,

6505 char *numstr,

6506 *orgnum;

6507

6509

6510

6511

6512

6516 {

6517

6519

6521

6522

6523

6524

6525 if (*orgnum == '+')

6526 *orgnum = ' ';

6527

6528 numstr = orgnum;

6529 }

6530 else

6531 {

6532 int numstr_pre_len;

6533

6535 {

6539 }

6540 else

6541 {

6544 }

6545

6546 if (*orgnum == '-')

6547 {

6549 orgnum++;

6550 }

6551 else

6553

6554 numstr_pre_len = strlen(orgnum);

6555

6556

6557 if (Num.post)

6558 {

6559 numstr = (char *) palloc(numstr_pre_len + Num.post + 2);

6560 strcpy(numstr, orgnum);

6561 *(numstr + numstr_pre_len) = '.';

6562 memset(numstr + numstr_pre_len + 1, '0', Num.post);

6563 *(numstr + numstr_pre_len + Num.post + 1) = '\0';

6564 }

6565 else

6566 numstr = orgnum;

6567

6568

6569 if (numstr_pre_len < Num.pre)

6570 out_pre_spaces = Num.pre - numstr_pre_len;

6571

6572 else if (numstr_pre_len > Num.pre)

6573 {

6574 numstr = (char *) palloc(Num.pre + Num.post + 2);

6576 *(numstr + Num.pre) = '.';

6577 }

6578 }

6579

6582}

6583

6584

6585

6586

6587

6590{

6595 text *result;

6596 bool shouldFree;

6597 int out_pre_spaces = 0,

6599 char *numstr,

6600 *orgnum;

6601

6603

6604

6605

6606

6608 {

6610

6611

6612 if (value <= PG_INT32_MAX && value >= PG_INT32_MIN)

6614 else

6617 }

6619 {

6620

6623

6624

6625

6626

6627

6628

6629 if (*orgnum != '-')

6630 {

6631 numstr = (char *) palloc(strlen(orgnum) + 2);

6632 *numstr = ' ';

6633 strcpy(numstr + 1, orgnum);

6634 }

6635 else

6636 {

6637 numstr = orgnum;

6638 }

6639 }

6640 else

6641 {

6642 int numstr_pre_len;

6643

6645 {

6646 double multi = pow((double) 10, (double) Num.multi);

6647

6653 }

6654

6657

6658 if (*orgnum == '-')

6659 {

6661 orgnum++;

6662 }

6663 else

6665

6666 numstr_pre_len = strlen(orgnum);

6667

6668

6669 if (Num.post)

6670 {

6671 numstr = (char *) palloc(numstr_pre_len + Num.post + 2);

6672 strcpy(numstr, orgnum);

6673 *(numstr + numstr_pre_len) = '.';

6674 memset(numstr + numstr_pre_len + 1, '0', Num.post);

6675 *(numstr + numstr_pre_len + Num.post + 1) = '\0';

6676 }

6677 else

6678 numstr = orgnum;

6679

6680

6681 if (numstr_pre_len < Num.pre)

6682 out_pre_spaces = Num.pre - numstr_pre_len;

6683

6684 else if (numstr_pre_len > Num.pre)

6685 {

6686 numstr = (char *) palloc(Num.pre + Num.post + 2);

6688 *(numstr + Num.pre) = '.';

6689 }

6690 }

6691

6694}

6695

6696

6697

6698

6699

6702{

6707 text *result;

6708 bool shouldFree;

6709 int out_pre_spaces = 0,

6711 char *numstr,

6712 *p;

6713

6715

6717 {

6719

6720

6722

6725 else

6728 }

6730 {

6732 {

6733

6734

6735

6736

6737 numstr = (char *) palloc(Num.pre + Num.post + 7);

6739 *numstr = ' ';

6740 *(numstr + Num.pre + 1) = '.';

6741 }

6742 else

6743 {

6745

6746

6747

6748

6749 if (*numstr == '+')

6750 *numstr = ' ';

6751 }

6752 }

6753 else

6754 {

6756 char *orgnum;

6757 int numstr_pre_len;

6758

6760 {

6761 float multi = pow((double) 10, (double) Num.multi);

6762

6765 }

6766

6768 numstr_pre_len = strlen(orgnum);

6769

6770

6771 if (numstr_pre_len >= FLT_DIG)

6772 Num.post = 0;

6773 else if (numstr_pre_len + Num.post > FLT_DIG)

6774 Num.post = FLT_DIG - numstr_pre_len;

6776

6777 if (*orgnum == '-')

6778 {

6780 numstr = orgnum + 1;

6781 }

6782 else

6783 {

6785 numstr = orgnum;

6786 }

6787

6788 if ((p = strchr(numstr, '.')))

6789 numstr_pre_len = p - numstr;

6790 else

6791 numstr_pre_len = strlen(numstr);

6792

6793

6794 if (numstr_pre_len < Num.pre)

6795 out_pre_spaces = Num.pre - numstr_pre_len;

6796

6797 else if (numstr_pre_len > Num.pre)

6798 {

6799 numstr = (char *) palloc(Num.pre + Num.post + 2);

6801 *(numstr + Num.pre) = '.';

6802 }

6803 }

6804

6807}

6808

6809

6810

6811

6812

6815{

6820 text *result;

6821 bool shouldFree;

6822 int out_pre_spaces = 0,

6824 char *numstr,

6825 *p;

6826

6828

6830 {

6832

6833

6835

6838 else

6841 }

6843 {

6845 {

6846

6847

6848

6849

6850 numstr = (char *) palloc(Num.pre + Num.post + 7);

6852 *numstr = ' ';

6853 *(numstr + Num.pre + 1) = '.';

6854 }

6855 else

6856 {

6858

6859

6860

6861

6862 if (*numstr == '+')

6863 *numstr = ' ';

6864 }

6865 }

6866 else

6867 {

6869 char *orgnum;

6870 int numstr_pre_len;

6871

6873 {

6874 double multi = pow((double) 10, (double) Num.multi);

6875

6878 }

6879

6881 numstr_pre_len = strlen(orgnum);

6882

6883

6884 if (numstr_pre_len >= DBL_DIG)

6885 Num.post = 0;

6886 else if (numstr_pre_len + Num.post > DBL_DIG)

6887 Num.post = DBL_DIG - numstr_pre_len;

6889

6890 if (*orgnum == '-')

6891 {

6893 numstr = orgnum + 1;

6894 }

6895 else

6896 {

6898 numstr = orgnum;

6899 }

6900

6901 if ((p = strchr(numstr, '.')))

6902 numstr_pre_len = p - numstr;

6903 else

6904 numstr_pre_len = strlen(numstr);

6905

6906

6907 if (numstr_pre_len < Num.pre)

6908 out_pre_spaces = Num.pre - numstr_pre_len;

6909

6910 else if (numstr_pre_len > Num.pre)

6911 {

6912 numstr = (char *) palloc(Num.pre + Num.post + 2);

6914 *(numstr + Num.pre) = '.';

6915 }

6916 }

6917

6920}

int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)

void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)

int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)

void j2date(int jd, int *year, int *month, int *day)

const char *const months[]

int date2j(int year, int month, int day)

int DecodeTimezoneAbbrevPrefix(const char *str, int *offset, pg_tz **tz)

int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)

char * numeric_out_sci(Numeric num, int scale)

int32 numeric_int4_opt_error(Numeric num, bool *have_error)

Datum numeric_round(PG_FUNCTION_ARGS)

Numeric int64_to_numeric(int64 val)

Datum numeric_power(PG_FUNCTION_ARGS)

Datum numeric_out(PG_FUNCTION_ARGS)

Datum numeric_in(PG_FUNCTION_ARGS)

Datum numeric_mul(PG_FUNCTION_ARGS)

void isoweek2date(int woy, int *year, int *mon, int *mday)

int isoweek2j(int year, int week)

int date2isoweek(int year, int mon, int mday)

bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)

int date2isoyearday(int year, int mon, int mday)

int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)

void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)

int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)

void interval2itm(Interval span, struct pg_itm *itm)

int date2isoyear(int year, int mon, int mday)

#define FLOAT4_FITS_IN_INT32(num)

#define FLOAT8_FITS_IN_INT32(num)

#define MemSet(start, val, len)

#define OidIsValid(objectId)

#define INTERVAL_NOT_FINITE(i)

#define IS_VALID_JULIAN(y, m, d)

#define TIMESTAMP_NOT_FINITE(j)

#define POSTGRES_EPOCH_JDATE

int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)

int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)

void AdjustTimeForTypmod(TimeADT *time, int32 typmod)

static Datum DateADTGetDatum(DateADT X)

#define PG_RETURN_DATEADT(x)

static Datum TimeTzADTPGetDatum(const TimeTzADT *X)

static Datum TimeADTGetDatum(TimeADT X)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereturn(context, dummy_value,...)

#define errsave(context,...)

#define ereport(elevel,...)

void err(int eval, const char *fmt,...)

Datum Int64GetDatum(int64 X)

Datum Float8GetDatum(float8 X)

#define PG_GETARG_TEXT_PP(n)

#define DirectFunctionCall2(func, arg1, arg2)

#define PG_GETARG_FLOAT8(n)

#define DirectFunctionCall1(func, arg1)

#define PG_GETARG_INT64(n)

#define PG_RETURN_TEXT_P(x)

#define PG_GETARG_INT32(n)

#define PG_GETARG_FLOAT4(n)

#define DirectFunctionCall3(func, arg1, arg2, arg3)

#define PG_GET_COLLATION()

static void DCH_from_char(FormatNode *node, const char *in, TmFromChar *out, Oid collid, bool std, Node *escontext)

#define NUM_TOCHAR_prepare

Datum to_timestamp(PG_FUNCTION_ARGS)

static NUMCacheEntry * NUMCache[NUM_CACHE_ENTRIES]

static bool is_next_separator(FormatNode *n)

static const int DCH_index[KeyWord_INDEX_SIZE]

static char * fill_str(char *str, int c, int max)

static char * NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, int input_len, int to_char_out_pre_spaces, int sign, bool is_to_char, Oid collid)

#define SKIP_THth(ptr, _suf)

#define IS_VALID_SUB_COMB(curr, next)

char * str_initcap(const char *buff, size_t nbytes, Oid collid)

static bool do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std, struct pg_tm *tm, fsec_t *fsec, struct fmt_tz *tz, int *fprec, uint32 *flags, Node *escontext)

static bool from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode, Node *escontext)

static const KeyWord NUM_keywords[]

static char * str_numth(char *dest, char *num, int type)

static bool from_char_seq_search(int *dest, const char **src, const char *const *array, char **localized_array, Oid collid, FormatNode *node, Node *escontext)

static void parse_format(FormatNode *node, const char *str, const KeyWord *kw, const KeySuffix *suf, const int *index, uint32 flags, NUMDesc *Num)

#define DCH_to_char_fsec(frac_fmt, frac_val)

static void NUMDesc_prepare(NUMDesc *num, FormatNode *n)

static void DCH_prevent_counter_overflow(void)

static void NUM_numpart_to_char(NUMProc *Np, int id)

static int seq_search_localized(const char *name, char **array, int *len, Oid collid)

static void NUM_numpart_from_char(NUMProc *Np, int id, int input_len)

static NUMCacheEntry * NUM_cache_getnew(const char *str)

bool datetime_format_has_tz(const char *fmt_str)

static NUMCacheEntry * NUM_cache_fetch(const char *str)

Datum float4_to_char(PG_FUNCTION_ARGS)

#define NUM_CACHE_ENTRIES

#define ADJUST_YEAR(year, is_interval)

static int from_char_parse_int_len(int *dest, const char **src, const int len, FormatNode *node, Node *escontext)

static char * str_tolower_z(const char *buff, Oid collid)

#define NUM_TOCHAR_finish

static char * asc_toupper_z(const char *buff)

static DCHCacheEntry * DCH_cache_getnew(const char *str, bool std)

char * asc_initcap(const char *buff, size_t nbytes)

static const KeySuffix * suff_search(const char *str, const KeySuffix *suf, int type)

char * asc_toupper(const char *buff, size_t nbytes)

static int adjust_partial_year_to_2020(int year)

static char * get_last_relevant_decnum(char *num)

static const KeyWord * index_seq_search(const char *str, const KeyWord *kw, const int *index)

static const KeySuffix DCH_suff[]

@ FROM_CHAR_DATE_GREGORIAN

Datum to_date(PG_FUNCTION_ARGS)

static char * str_toupper_z(const char *buff, Oid collid)

static const char *const numth[]

char * str_casefold(const char *buff, size_t nbytes, Oid collid)

Datum timestamp_to_char(PG_FUNCTION_ARGS)

static int roman_to_int(NUMProc *Np, int input_len)

static void NUM_prevent_counter_overflow(void)

static const int NUM_index[KeyWord_INDEX_SIZE]

static const char *const rm100[]

static int seq_search_ascii(const char *name, const char *const *array, int *len)

Datum float8_to_char(PG_FUNCTION_ARGS)

static const char *const months_full[]

#define INVALID_FOR_INTERVAL

#define NODE_TYPE_SEPARATOR

char * asc_tolower(const char *buff, size_t nbytes)

Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, Node *escontext)

Datum numeric_to_char(PG_FUNCTION_ARGS)

static const char *const adbc_strings_long[]

Datum int4_to_char(PG_FUNCTION_ARGS)

static const char *const days_short[]

static void NUM_prepare_locale(NUMProc *Np)

static int DCH_datetime_type(FormatNode *node)

static const char *const rm10[]

static char * str_initcap_z(const char *buff, Oid collid)

#define KeyWord_INDEX_FILTER(_c)

static void NUM_eat_non_data_chars(NUMProc *Np, int n, int input_len)

static NUMCacheEntry * NUM_cache_search(const char *str)

Datum timestamptz_to_char(PG_FUNCTION_ARGS)

static const char *const ampm_strings[]

char * str_toupper(const char *buff, size_t nbytes, Oid collid)

#define KeyWord_INDEX_SIZE

static DCHCacheEntry * DCH_cache_search(const char *str, bool std)

static void DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid collid)

static bool from_char_set_int(int *dest, const int value, const FormatNode *node, Node *escontext)

static int strspace_len(const char *str)

Datum numeric_to_number(PG_FUNCTION_ARGS)

static DCHCacheEntry * DCHCache[DCH_CACHE_ENTRIES]

#define IS_PREDEC_SPACE(_n)

Datum int8_to_char(PG_FUNCTION_ARGS)

#define DCH_CACHE_ENTRIES

static FormatNode * NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree)

static const KeyWord DCH_keywords[]

static const char *const numTH[]

static const char *const rm1[]

static char * asc_tolower_z(const char *buff)

static const char *const rm_months_upper[]

static const char *const rm_months_lower[]

static const char * get_th(char *num, int type)

static const char *const adbc_strings[]

static char * int_to_roman(int number)

static int from_char_parse_int(int *dest, const char **src, FormatNode *node, Node *escontext)

static text * datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid)

static DCHCacheEntry * DCH_cache_fetch(const char *str, bool std)

#define COPY_tm(_DST, _SRC)

char * str_tolower(const char *buff, size_t nbytes, Oid collid)

static const char *const ampm_strings_long[]

Datum interval_to_char(PG_FUNCTION_ARGS)

static bool is_separator_char(const char *str)

Assert(PointerIsAligned(start, uint64))

#define DTERR_TZDISP_OVERFLOW

#define DTERR_FIELD_OVERFLOW

Datum int8out(PG_FUNCTION_ARGS)

Datum int8mul(PG_FUNCTION_ARGS)

Datum dtoi8(PG_FUNCTION_ARGS)

Datum int4out(PG_FUNCTION_ARGS)

static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)

static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)

static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)

if(TABLE==NULL||TABLE_index==NULL)

int GetDatabaseEncoding(void)

int pg_mbstrlen(const char *mbstr)

int pg_mblen(const char *mbstr)

void * MemoryContextAllocZero(MemoryContext context, Size size)

char * pstrdup(const char *in)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

MemoryContext TopMemoryContext

char * pnstrdup(const char *in, Size len)

#define SOFT_ERROR_OCCURRED(escontext)

static Numeric DatumGetNumeric(Datum X)

#define PG_GETARG_NUMERIC(n)

static Datum NumericGetDatum(Numeric X)

static PgChecksumMode mode

void cache_locale_time(void)

char * localized_full_months[12+1]

pg_locale_t pg_newlocale_from_collation(Oid collid)

size_t pg_strfold(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

size_t pg_strlower(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

struct lconv * PGLC_localeconv(void)

size_t pg_strtitle(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

char * localized_abbrev_months[12+1]

char * localized_full_days[7+1]

size_t pg_strupper(char *dst, size_t dstsize, const char *src, ssize_t srclen, pg_locale_t locale)

char * localized_abbrev_days[7+1]

#define MAX_MULTIBYTE_CHAR_LEN

PGDLLIMPORT pg_tz * session_timezone

unsigned char pg_ascii_tolower(unsigned char ch)

unsigned char pg_ascii_toupper(unsigned char ch)

size_t strlcpy(char *dst, const char *src, size_t siz)

static int64 DatumGetInt64(Datum X)

static Datum ObjectIdGetDatum(Oid X)

static char * DatumGetCString(Datum X)

static Datum CStringGetDatum(const char *X)

static Datum Int32GetDatum(int32 X)

char * psprintf(const char *fmt,...)

bool scanner_isspace(char ch)

FormatNode format[DCH_CACHE_SIZE+1]

char str[DCH_CACHE_SIZE+1]

char character[MAX_MULTIBYTE_CHAR_LEN+1]

FromCharDateMode date_mode

char str[NUM_CACHE_SIZE+1]

FormatNode format[NUM_CACHE_SIZE+1]

static Datum TimestampTzGetDatum(TimestampTz X)

static Datum TimestampGetDatum(Timestamp X)

#define PG_GETARG_TIMESTAMP(n)

#define PG_RETURN_TIMESTAMP(x)

#define PG_GETARG_INTERVAL_P(n)

#define VARSIZE_ANY_EXHDR(PTR)

text * cstring_to_text(const char *s)

char * text_to_cstring(const text *t)