PostgreSQL Source Code: src/backend/nodes/readfuncs.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

28

29#include <math.h>

30

34

35

36

37

38

39

40

41

42

43

44

45

46#define READ_LOCALS_NO_FIELDS(nodeTypeName) \

47 nodeTypeName *local_node = makeNode(nodeTypeName)

48

49

50#define READ_TEMP_LOCALS() \

51 const char *token; \

52 int length

53

54

55#define READ_LOCALS(nodeTypeName) \

56 READ_LOCALS_NO_FIELDS(nodeTypeName); \

57 READ_TEMP_LOCALS()

58

59

60#define READ_INT_FIELD(fldname) \

61 token = pg_strtok(&length); \

62 token = pg_strtok(&length); \

63 local_node->fldname = atoi(token)

64

65

66#define READ_UINT_FIELD(fldname) \

67 token = pg_strtok(&length); \

68 token = pg_strtok(&length); \

69 local_node->fldname = atoui(token)

70

71

72#define READ_UINT64_FIELD(fldname) \

73 token = pg_strtok(&length); \

74 token = pg_strtok(&length); \

75 local_node->fldname = strtou64(token, NULL, 10)

76

77

78#define READ_LONG_FIELD(fldname) \

79 token = pg_strtok(&length); \

80 token = pg_strtok(&length); \

81 local_node->fldname = atol(token)

82

83

84#define READ_OID_FIELD(fldname) \

85 token = pg_strtok(&length); \

86 token = pg_strtok(&length); \

87 local_node->fldname = atooid(token)

88

89

90#define READ_CHAR_FIELD(fldname) \

91 token = pg_strtok(&length); \

92 token = pg_strtok(&length); \

93 \

94 local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])

95

96

97#define READ_ENUM_FIELD(fldname, enumtype) \

98 token = pg_strtok(&length); \

99 token = pg_strtok(&length); \

100 local_node->fldname = (enumtype) atoi(token)

101

102

103#define READ_FLOAT_FIELD(fldname) \

104 token = pg_strtok(&length); \

105 token = pg_strtok(&length); \

106 local_node->fldname = atof(token)

107

108

109#define READ_BOOL_FIELD(fldname) \

110 token = pg_strtok(&length); \

111 token = pg_strtok(&length); \

112 local_node->fldname = strtobool(token)

113

114

115#define READ_STRING_FIELD(fldname) \

116 token = pg_strtok(&length); \

117 token = pg_strtok(&length); \

118 local_node->fldname = nullable_string(token, length)

119

120

121#ifdef DEBUG_NODE_TESTS_ENABLED

122#define READ_LOCATION_FIELD(fldname) \

123 token = pg_strtok(&length); \

124 token = pg_strtok(&length); \

125 local_node->fldname = restore_location_fields ? atoi(token) : -1

126#else

127#define READ_LOCATION_FIELD(fldname) \

128 token = pg_strtok(&length); \

129 token = pg_strtok(&length); \

130 (void) token; \

131 local_node->fldname = -1

132#endif

133

134

135#define READ_NODE_FIELD(fldname) \

136 token = pg_strtok(&length); \

137 (void) token; \

138 local_node->fldname = nodeRead(NULL, 0)

139

140

141#define READ_BITMAPSET_FIELD(fldname) \

142 token = pg_strtok(&length); \

143 (void) token; \

144 local_node->fldname = _readBitmapset()

145

146

147#define READ_ATTRNUMBER_ARRAY(fldname, len) \

148 token = pg_strtok(&length); \

149 local_node->fldname = readAttrNumberCols(len)

150

151

152#define READ_OID_ARRAY(fldname, len) \

153 token = pg_strtok(&length); \

154 local_node->fldname = readOidCols(len)

155

156

157#define READ_INT_ARRAY(fldname, len) \

158 token = pg_strtok(&length); \

159 local_node->fldname = readIntCols(len)

160

161

162#define READ_BOOL_ARRAY(fldname, len) \

163 token = pg_strtok(&length); \

164 local_node->fldname = readBoolCols(len)

165

166

167#define READ_DONE() \

168 return local_node

169

170

171

172

173

174

175

176

177#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))

178

179#define strtobool(x) ((*(x) == 't') ? true : false)

180

181static char *

183{

184

185 if (length == 0)

186 return NULL;

187

188 if (length == 2 && token[0] == '"' && token[1] == '"')

190

192}

193

194

195

196

197

198

199

200

201

204{

206

208

210 if (token == NULL)

211 elog(ERROR, "incomplete Bitmapset structure");

212 if (length != 1 || token[0] != '(')

213 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);

214

216 if (token == NULL)

217 elog(ERROR, "incomplete Bitmapset structure");

218 if (length != 1 || token[0] != 'b')

219 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);

220

221 for (;;)

222 {

224 char *endptr;

225

227 if (token == NULL)

228 elog(ERROR, "unterminated Bitmapset structure");

229 if (length == 1 && token[0] == ')')

230 break;

231 val = (int) strtol(token, &endptr, 10);

232 if (endptr != token + length)

233 elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);

235 }

236

237 return result;

238}

239

240

241

242

243

246{

248}

249

250#include "readfuncs.funcs.c"

251

252

253

254

255

256

257

260{

262

270

272 if (local_node->constisnull)

274 else

275 local_node->constvalue = readDatum(local_node->constbyval);

276

278}

279

282{

284

285

288 if (length == 3 && strncmp(token, "and", 3) == 0)

289 local_node->boolop = AND_EXPR;

290 else if (length == 2 && strncmp(token, "or", 2) == 0)

291 local_node->boolop = OR_EXPR;

292 else if (length == 3 && strncmp(token, "not", 3) == 0)

293 local_node->boolop = NOT_EXPR;

294 else

295 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);

296

299

301}

302

305{

307

308

310 if (length == 4 && strncmp(token, "NULL", 4) == 0)

311 local_node->isnull = true;

312 else

313 {

315

316

318 {

319 case T_Integer:

320 memcpy(&local_node->val, tmp, sizeof(Integer));

321 break;

322 case T_Float:

323 memcpy(&local_node->val, tmp, sizeof(Float));

324 break;

325 case T_Boolean:

326 memcpy(&local_node->val, tmp, sizeof(Boolean));

327 break;

328 case T_String:

329 memcpy(&local_node->val, tmp, sizeof(String));

330 break;

331 case T_BitString:

332 memcpy(&local_node->val, tmp, sizeof(BitString));

333 break;

334 default:

335 elog(ERROR, "unrecognized node type: %d",

337 break;

338 }

339 }

340

342

344}

345

348{

350

354

355 switch (local_node->rtekind)

356 {

364 break;

368

374 break;

382 break;

386 break;

389

390 if (local_node->tablefunc)

391 {

392 TableFunc *tf = local_node->tablefunc;

393

394 local_node->coltypes = tf->coltypes;

395 local_node->coltypmods = tf->coltypmods;

396 local_node->colcollations = tf->colcollations;

397 }

398 break;

404 break;

412 break;

419

421 break;

423

424 break;

427 break;

428 default:

429 elog(ERROR, "unrecognized RTE kind: %d",

430 (int) local_node->rtekind);

431 break;

432 }

433

437

439}

440

443{

445

447

448 if (length == 3 && strncmp(token, "ANY", 3) == 0)

449 {

452 }

453 else if (length == 3 && strncmp(token, "ALL", 3) == 0)

454 {

457 }

458 else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)

459 {

462 }

463 else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)

464 {

467 }

468 else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)

469 {

472 }

473 else if (length == 2 && strncmp(token, "IN", 2) == 0)

474 {

477 }

478 else if (length == 4 && strncmp(token, "LIKE", 4) == 0)

479 {

482 }

483 else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)

484 {

487 }

488 else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)

489 {

492 }

493 else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)

494 {

497 }

498 else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)

499 {

502 }

503 else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)

504 {

507 }

508 else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)

509 {

512 }

513 else if (length == 5 && strncmp(token, ":name", 5) == 0)

514 {

516 local_node->name = nodeRead(NULL, 0);

517 }

518 else

519 elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);

520

524

526}

527

530{

533 const char *extnodename;

534

536

539

541 if (!extnodename)

542 elog(ERROR, "extnodename has to be supplied");

544

546 T_ExtensibleNode);

548

549

550 methods->nodeRead(local_node);

551

553}

554

555

556

557

558

559

560

561

562

563

566{

568

569

571

573

574#define MATCH(tokname, namelen) \

575 (length == namelen && memcmp(token, tokname, namelen) == 0)

576

577#include "readfuncs.switch.c"

578

579 elog(ERROR, "badly formatted node string \"%.32s\"...", token);

580 return NULL;

581}

582

583

584

585

586

587

588

589

590

593{

595 i;

596 int tokenLength;

597 const char *token;

599 char *s;

600

601

602

603

606

608 if (token == NULL || token[0] != '[')

609 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",

611

612 if (typbyval)

613 {

614 if (length > (Size) sizeof(Datum))

615 elog(ERROR, "byval datum but length = %zu", length);

617 s = (char *) (&res);

619 {

621 s[i] = (char) atoi(token);

622 }

623 }

624 else if (length <= 0)

625 res = (Datum) NULL;

626 else

627 {

628 s = (char *) palloc(length);

629 for (i = 0; i < length; i++)

630 {

632 s[i] = (char) atoi(token);

633 }

635 }

636

638 if (token == NULL || token[0] != ']')

639 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",

641

642 return res;

643}

644

645

646

647

648

649

650

651

652

653#define READ_SCALAR_ARRAY(fnname, datatype, convfunc) \

654datatype * \

655fnname(int numCols) \

656{ \

657 datatype *vals; \

658 READ_TEMP_LOCALS(); \

659 token = pg_strtok(&length); \

660 if (token == NULL) \

661 elog(ERROR, "incomplete scalar array"); \

662 if (length == 0) \

663 return NULL; \

664 if (length != 1 || token[0] != '(') \

665 elog(ERROR, "unrecognized token: \"%.*s\"", length, token); \

666 vals = (datatype *) palloc(numCols * sizeof(datatype)); \

667 for (int i = 0; i < numCols; i++) \

668 { \

669 token = pg_strtok(&length); \

670 if (token == NULL || token[0] == ')') \

671 elog(ERROR, "incomplete scalar array"); \

672 vals[i] = convfunc(token); \

673 } \

674 token = pg_strtok(&length); \

675 if (token == NULL || length != 1 || token[0] != ')') \

676 elog(ERROR, "incomplete scalar array"); \

677 return vals; \

678}

679

680

681

682

683

686

687

Bitmapset * bms_add_member(Bitmapset *a, int x)

const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)

char * pstrdup(const char *in)

int * readIntCols(int numCols)

static Node * newNode(size_t size, NodeTag tag)

Oid * readOidCols(int numCols)

int16 * readAttrNumberCols(int numCols)

bool * readBoolCols(int numCols)

static Datum PointerGetDatum(const void *X)

char * debackslash(const char *token, int length)

void * nodeRead(const char *token, int tok_len)

const char * pg_strtok(int *length)

#define READ_INT_FIELD(fldname)

#define READ_UINT_FIELD(fldname)

#define READ_NODE_FIELD(fldname)

static ExtensibleNode * _readExtensibleNode(void)

#define READ_CHAR_FIELD(fldname)

static char * nullable_string(const char *token, int length)

#define READ_SCALAR_ARRAY(fnname, datatype, convfunc)

Node * parseNodeString(void)

#define READ_OID_FIELD(fldname)

#define READ_LOCATION_FIELD(fldname)

static Bitmapset * _readBitmapset(void)

static A_Const * _readA_Const(void)

static Const * _readConst(void)

#define READ_STRING_FIELD(fldname)

#define READ_FLOAT_FIELD(fldname)

Datum readDatum(bool typbyval)

#define READ_BOOL_FIELD(fldname)

static BoolExpr * _readBoolExpr(void)

#define READ_ENUM_FIELD(fldname, enumtype)

#define READ_TEMP_LOCALS()

static A_Expr * _readA_Expr(void)

Bitmapset * readBitmapset(void)

#define READ_LOCALS(nodeTypeName)

static RangeTblEntry * _readRangeTblEntry(void)

static const struct fns functions

void check_stack_depth(void)

void(* nodeRead)(struct ExtensibleNode *node)