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_INT64_FIELD(fldname) \

73 token = pg_strtok(&length); \

74 token = pg_strtok(&length); \

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

76

77

78#define READ_UINT64_FIELD(fldname) \

79 token = pg_strtok(&length); \

80 token = pg_strtok(&length); \

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

82

83

84#define READ_LONG_FIELD(fldname) \

85 token = pg_strtok(&length); \

86 token = pg_strtok(&length); \

87 local_node->fldname = atol(token)

88

89

90#define READ_OID_FIELD(fldname) \

91 token = pg_strtok(&length); \

92 token = pg_strtok(&length); \

93 local_node->fldname = atooid(token)

94

95

96#define READ_CHAR_FIELD(fldname) \

97 token = pg_strtok(&length); \

98 token = pg_strtok(&length); \

99 \

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

101

102

103#define READ_ENUM_FIELD(fldname, enumtype) \

104 token = pg_strtok(&length); \

105 token = pg_strtok(&length); \

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

107

108

109#define READ_FLOAT_FIELD(fldname) \

110 token = pg_strtok(&length); \

111 token = pg_strtok(&length); \

112 local_node->fldname = atof(token)

113

114

115#define READ_BOOL_FIELD(fldname) \

116 token = pg_strtok(&length); \

117 token = pg_strtok(&length); \

118 local_node->fldname = strtobool(token)

119

120

121#define READ_STRING_FIELD(fldname) \

122 token = pg_strtok(&length); \

123 token = pg_strtok(&length); \

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

125

126

127#ifdef DEBUG_NODE_TESTS_ENABLED

128#define READ_LOCATION_FIELD(fldname) \

129 token = pg_strtok(&length); \

130 token = pg_strtok(&length); \

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

132#else

133#define READ_LOCATION_FIELD(fldname) \

134 token = pg_strtok(&length); \

135 token = pg_strtok(&length); \

136 (void) token; \

137 local_node->fldname = -1

138#endif

139

140

141#define READ_NODE_FIELD(fldname) \

142 token = pg_strtok(&length); \

143 (void) token; \

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

145

146

147#define READ_BITMAPSET_FIELD(fldname) \

148 token = pg_strtok(&length); \

149 (void) token; \

150 local_node->fldname = _readBitmapset()

151

152

153#define READ_ATTRNUMBER_ARRAY(fldname, len) \

154 token = pg_strtok(&length); \

155 local_node->fldname = readAttrNumberCols(len)

156

157

158#define READ_OID_ARRAY(fldname, len) \

159 token = pg_strtok(&length); \

160 local_node->fldname = readOidCols(len)

161

162

163#define READ_INT_ARRAY(fldname, len) \

164 token = pg_strtok(&length); \

165 local_node->fldname = readIntCols(len)

166

167

168#define READ_BOOL_ARRAY(fldname, len) \

169 token = pg_strtok(&length); \

170 local_node->fldname = readBoolCols(len)

171

172

173#define READ_DONE() \

174 return local_node

175

176

177

178

179

180

181

182

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

184

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

186

187static char *

189{

190

191 if (length == 0)

192 return NULL;

193

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

196

198}

199

200

201

202

203

204

205

206

207

210{

212

214

216 if (token == NULL)

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

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

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

220

222 if (token == NULL)

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

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

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

226

227 for (;;)

228 {

230 char *endptr;

231

233 if (token == NULL)

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

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

236 break;

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

238 if (endptr != token + length)

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

241 }

242

243 return result;

244}

245

246

247

248

249

252{

254}

255

256#include "readfuncs.funcs.c"

257

258

259

260

261

262

263

266{

268

276

278 if (local_node->constisnull)

280 else

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

282

284}

285

288{

290

291

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

295 local_node->boolop = AND_EXPR;

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

297 local_node->boolop = OR_EXPR;

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

299 local_node->boolop = NOT_EXPR;

300 else

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

302

305

307}

308

311{

313

314

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

317 local_node->isnull = true;

318 else

319 {

321

322

324 {

325 case T_Integer:

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

327 break;

328 case T_Float:

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

330 break;

331 case T_Boolean:

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

333 break;

334 case T_String:

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

336 break;

337 case T_BitString:

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

339 break;

340 default:

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

343 break;

344 }

345 }

346

348

350}

351

354{

356

360

361 switch (local_node->rtekind)

362 {

370 break;

374

380 break;

388 break;

392 break;

395

396 if (local_node->tablefunc)

397 {

398 TableFunc *tf = local_node->tablefunc;

399

400 local_node->coltypes = tf->coltypes;

401 local_node->coltypmods = tf->coltypmods;

402 local_node->colcollations = tf->colcollations;

403 }

404 break;

410 break;

418 break;

425

427 break;

429

430 break;

433 break;

434 default:

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

436 (int) local_node->rtekind);

437 break;

438 }

439

443

445}

446

449{

451

453

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

455 {

458 }

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

460 {

463 }

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

465 {

468 }

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

470 {

473 }

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

475 {

478 }

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

480 {

483 }

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

485 {

488 }

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

490 {

493 }

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

495 {

498 }

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

500 {

503 }

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

505 {

508 }

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

510 {

513 }

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

515 {

518 }

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

520 {

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

523 }

524 else

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

526

532

534}

535

538{

541 const char *extnodename;

542

544

547

549 if (!extnodename)

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

552

554 T_ExtensibleNode);

556

557

558 methods->nodeRead(local_node);

559

561}

562

563

564

565

566

567

568

569

570

571

574{

576

577

579

581

582#define MATCH(tokname, namelen) \

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

584

585#include "readfuncs.switch.c"

586

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

588 return NULL;

589}

590

591

592

593

594

595

596

597

598

601{

603 int tokenLength;

604 const char *token;

606 char *s;

607

608

609

610

613

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

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

618

619 if (typbyval)

620 {

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

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

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

626 {

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

629 }

630 }

631 else if (length <= 0)

633 else

634 {

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

636 for (Size i = 0; i < length; i++)

637 {

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

640 }

642 }

643

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

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

648

649 return res;

650}

651

652

653

654

655

656

657

658

659

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

661datatype * \

662fnname(int numCols) \

663{ \

664 datatype *vals; \

665 READ_TEMP_LOCALS(); \

666 token = pg_strtok(&length); \

667 if (token == NULL) \

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

669 if (length == 0) \

670 return NULL; \

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

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

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

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

675 { \

676 token = pg_strtok(&length); \

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

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

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

680 } \

681 token = pg_strtok(&length); \

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

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

684 return vals; \

685}

686

687

688

689

690

693

694

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)