PostgreSQL Source Code: src/backend/nodes/queryjumblefuncs.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
34
43
44#define JUMBLE_SIZE 1024
45
46
48
49
50
51
52
53
54
55
57
61 const unsigned char *value, Size size);
64 int location, bool squashed);
73
74
75
76
77
78const char *
80{
81 int query_location = *location;
82 int query_len = *len;
83
84
85 if (query_location >= 0)
86 {
87 Assert(query_location <= strlen(query));
88 query += query_location;
89
90 if (query_len <= 0)
91 query_len = strlen(query);
92 else
93 Assert(query_len <= strlen(query));
94 }
95 else
96 {
97
98 query_location = 0;
99 query_len = strlen(query);
100 }
101
102
103
104
105
106
107
108
109
110
111
113 query++, query_location++, query_len--;
114 while (query_len > 0 && scanner_isspace(query[query_len - 1]))
115 query_len--;
116
117 *location = query_location;
118 *len = query_len;
119
120 return query;
121}
122
123
124
125
126
127
128
131{
133
135
137
138 query->queryId = DoJumble(jstate, (Node *) query);
139
140
141
142
143
145 {
148 else
150 }
151
152 return jstate;
153}
154
155
156
157
158
159
160
161void
163{
166}
167
168
169
170
171
174{
176
178
179
188#ifdef USE_ASSERT_CHECKING
189 jstate->total_jumble_len = 0;
190#endif
191
192 return jstate;
193}
194
195
196
197
198
199
202{
203
205
206
209
210
213 0));
214}
215
216
217
218
219
220
224{
225 unsigned char *jumble = jstate->jumble;
227
228
230
231
232
233
234
235
237 {
238 memcpy(jumble + jumble_len, item, size);
240
241#ifdef USE_ASSERT_CHECKING
242 jstate->total_jumble_len += size;
243#endif
244
245 return;
246 }
247
248
249
250
251
252
253 do
254 {
255 Size part_size;
256
258 {
260
263 memcpy(jumble, &start_hash, sizeof(start_hash));
264 jumble_len = sizeof(start_hash);
265 }
267 memcpy(jumble + jumble_len, item, part_size);
268 jumble_len += part_size;
269 item += part_size;
270 size -= part_size;
271
272#ifdef USE_ASSERT_CHECKING
273 jstate->total_jumble_len += part_size;
274#endif
275 } while (size > 0);
276
278}
279
280
281
282
283
286{
289
291}
292
293
294
295
296
299{
301}
302
303
304
305
306
309{
312
314}
315
316
317
318
319
320
323{
326
328}
329
330
331
332
333
334
337{
340
342}
343
344
345
346
347
348
351{
354
356}
357
358
359
360
361
362
363
366{
368
370 (const unsigned char *) &jstate->pending_nulls, 4);
372}
373
374
375
376
377
378
379
380
381
382
383static void
385{
386
387 if (location >= 0)
388 {
389
391 {
397 }
399
403 }
404}
405
406
407
408
409
410
411
412
413
414
415static bool
417{
420
423
425 {
428
431 return false;
432
434 return false;
435
436 foreach(temp, func->args)
437 {
439
441 return false;
442 }
443
444 return true;
445 }
446
448 return false;
449
450 return true;
451}
452
453
454
455
456
457
458
459
460
461
462
463static bool
465{
467
468
469
470
471
473 return false;
474
475 foreach(temp, elements)
476 {
478 return false;
479 }
480
481 *firstExpr = linitial(elements);
482 *lastExpr = llast(elements);
483
484 return true;
485}
486
487#define JUMBLE_NODE(item) \
488 _jumbleNode(jstate, (Node *) expr->item)
489#define JUMBLE_ELEMENTS(list) \
490 _jumbleElements(jstate, (List *) expr->list)
491#define JUMBLE_LOCATION(location) \
492 RecordConstLocation(jstate, expr->location, false)
493#define JUMBLE_FIELD(item) \
494do { \
495 if (sizeof(expr->item) == 8) \
496 AppendJumble64(jstate, (const unsigned char *) &(expr->item)); \
497 else if (sizeof(expr->item) == 4) \
498 AppendJumble32(jstate, (const unsigned char *) &(expr->item)); \
499 else if (sizeof(expr->item) == 2) \
500 AppendJumble16(jstate, (const unsigned char *) &(expr->item)); \
501 else if (sizeof(expr->item) == 1) \
502 AppendJumble8(jstate, (const unsigned char *) &(expr->item)); \
503 else \
504 AppendJumble(jstate, (const unsigned char *) &(expr->item), sizeof(expr->item)); \
505} while (0)
506#define JUMBLE_STRING(str) \
507do { \
508 if (expr->str) \
509 AppendJumble(jstate, (const unsigned char *) (expr->str), strlen(expr->str) + 1); \
510 else \
511 AppendJumbleNull(jstate); \
512} while(0)
513
514#define JUMBLE_CUSTOM(nodetype, item) \
515 _jumble##nodetype##_##item(jstate, expr, expr->item)
516
517#include "queryjumblefuncs.funcs.c"
518
519
520
521
522
523
524
525static void
527{
529 *last;
530
532 {
533
534
535
536
537
538
539
540
541
542
543
544
545
548 }
549 else
550 {
552 }
553}
554
555static void
557{
558 Node *expr = node;
559#ifdef USE_ASSERT_CHECKING
560 Size prev_jumble_len = jstate->total_jumble_len;
561#endif
562
563 if (expr == NULL)
564 {
566 return;
567 }
568
569
571
572
573
574
575
577
579 {
580#include "queryjumblefuncs.switch.c"
581
582 case T_List:
583 case T_IntList:
584 case T_OidList:
585 case T_XidList:
587 break;
588
589 default:
590
591 elog(WARNING, "unrecognized node type: %d",
593 break;
594 }
595
596
598 {
599 case T_Param:
600 {
602
603
604
605
606
610 }
611 break;
612 default:
613 break;
614 }
615
616
617 Assert(jstate->total_jumble_len > prev_jumble_len);
618}
619
620static void
622{
625
626 switch (expr->type)
627 {
628 case T_List:
629 foreach(l, expr)
631 break;
632 case T_IntList:
633 foreach(l, expr)
635 break;
636 case T_OidList:
637 foreach(l, expr)
639 break;
640 case T_XidList:
641 foreach(l, expr)
643 break;
644 default:
645 elog(ERROR, "unrecognized list node type: %d",
646 (int) expr->type);
647 return;
648 }
649}
650
651static void
653{
655
658 {
661 {
662 case T_Integer:
664 break;
665 case T_Float:
667 break;
668 case T_Boolean:
670 break;
671 case T_String:
673 break;
674 case T_BitString:
676 break;
677 default:
678 elog(ERROR, "unrecognized node type: %d",
680 break;
681 }
682 }
683}
684
685static void
687{
689
692
693
694
695
696
701}
702
703
704
705
706static void
710{
712
713
714
715
717}
#define pg_attribute_always_inline
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Assert(PointerIsAligned(start, uint64))
void * repalloc(void *pointer, Size size)
int exprLocation(const Node *expr)
#define IsA(nodeptr, _type_)
static int list_length(const List *l)
static uint64 DatumGetUInt64(Datum X)
static bool IsQueryIdEnabled(void)
#define JUMBLE_NODE(item)
JumbleState * JumbleQuery(Query *query)
static void _jumbleNode(JumbleState *jstate, Node *node)
static void _jumbleVariableSetStmt(JumbleState *jstate, Node *node)
static pg_attribute_always_inline void AppendJumbleInternal(JumbleState *jstate, const unsigned char *item, Size size)
static pg_attribute_always_inline void AppendJumbleNull(JumbleState *jstate)
static pg_noinline void AppendJumble8(JumbleState *jstate, const unsigned char *value)
#define JUMBLE_LOCATION(location)
static bool IsSquashableConst(Node *element)
const char * CleanQuerytext(const char *query, int *location, int *len)
static uint64 DoJumble(JumbleState *jstate, Node *node)
static void _jumbleList(JumbleState *jstate, Node *node)
static void FlushPendingNulls(JumbleState *jstate)
static void RecordConstLocation(JumbleState *jstate, int location, bool squashed)
static void _jumbleElements(JumbleState *jstate, List *elements)
#define JUMBLE_STRING(str)
static pg_noinline void AppendJumble32(JumbleState *jstate, const unsigned char *value)
static pg_noinline void AppendJumble64(JumbleState *jstate, const unsigned char *value)
static void _jumbleA_Const(JumbleState *jstate, Node *node)
static void AppendJumble(JumbleState *jstate, const unsigned char *value, Size size)
static pg_noinline void AppendJumble16(JumbleState *jstate, const unsigned char *value)
static void _jumbleRangeTblEntry_eref(JumbleState *jstate, RangeTblEntry *rte, Alias *expr)
static bool IsSquashableConstList(List *elements, Node **firstExpr, Node **lastExpr)
static JumbleState * InitJumble(void)
#define JUMBLE_FIELD(item)
static chr element(struct vars *v, const chr *startp, const chr *endp)
bool scanner_isspace(char ch)
void check_stack_depth(void)
unsigned int pending_nulls
int highest_extern_param_id
#define FirstGenbkiObjectId