PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
queryjumblefuncs.c File Reference
#include "postgres.h"
#include "access/transam.h"
#include "catalog/pg_proc.h"
#include "common/hashfn.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "nodes/queryjumble.h"
#include "utils/lsyscache.h"
#include "parser/scansup.h"
#include "queryjumblefuncs.funcs.c"
#include "queryjumblefuncs.switch.c"
Include dependency graph for queryjumblefuncs.c:

Go to the source code of this file.

Macros

#define JUMBLE_SIZE   1024 /* query serialization buffer size */
 
#define JUMBLE_NODE(item)    _jumbleNode(jstate, (Node *) expr->item)
 
#define JUMBLE_ELEMENTS(list)    _jumbleElements(jstate, (List *) expr->list)
 
#define JUMBLE_LOCATION(location)    RecordConstLocation(jstate, expr->location, false)
 
#define JUMBLE_FIELD(item)
 
#define JUMBLE_STRING(str)
 
#define JUMBLE_CUSTOM(nodetype, item)    _jumble##nodetype##_##item(jstate, expr, expr->item)
 

Functions

static JumbleStateInitJumble (void)
 
static uint64 DoJumble (JumbleState *jstate, Node *node)
 
static void AppendJumble (JumbleState *jstate, const unsigned char *value, Size size)
 
static void FlushPendingNulls (JumbleState *jstate)
 
static void RecordConstLocation (JumbleState *jstate, int location, bool squashed)
 
static void _jumbleNode (JumbleState *jstate, Node *node)
 
static void _jumbleElements (JumbleState *jstate, List *elements)
 
static void _jumbleA_Const (JumbleState *jstate, Node *node)
 
static void _jumbleList (JumbleState *jstate, Node *node)
 
static void _jumbleVariableSetStmt (JumbleState *jstate, Node *node)
 
static void _jumbleRangeTblEntry_eref (JumbleState *jstate, RangeTblEntry *rte, Alias *expr)
 
const char * CleanQuerytext (const char *query, int *location, int *len)
 
JumbleStateJumbleQuery (Query *query)
 
void EnableQueryId (void)
 
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)
 
static pg_noinline void AppendJumble16 (JumbleState *jstate, const unsigned char *value)
 
static pg_noinline void AppendJumble32 (JumbleState *jstate, const unsigned char *value)
 
static pg_noinline void AppendJumble64 (JumbleState *jstate, const unsigned char *value)
 
static bool IsSquashableConst (Node *element)
 
static bool IsSquashableConstList (List *elements, Node **firstExpr, Node **lastExpr)
 

Variables

int compute_query_id = COMPUTE_QUERY_ID_AUTO
 
bool query_id_enabled = false
 

Macro Definition Documentation

◆ JUMBLE_CUSTOM

#define JUMBLE_CUSTOM (   nodetype,
  item 
)     _jumble##nodetype##_##item(jstate, expr, expr->item)

Definition at line 514 of file queryjumblefuncs.c.

◆ JUMBLE_ELEMENTS

#define JUMBLE_ELEMENTS (   list)     _jumbleElements(jstate, (List *) expr->list)

Definition at line 489 of file queryjumblefuncs.c.

◆ JUMBLE_FIELD

#define JUMBLE_FIELD (   item)
Value:
do { \
if (sizeof(expr->item) == 8) \
AppendJumble64(jstate, (const unsigned char *) &(expr->item)); \
else if (sizeof(expr->item) == 4) \
AppendJumble32(jstate, (const unsigned char *) &(expr->item)); \
else if (sizeof(expr->item) == 2) \
AppendJumble16(jstate, (const unsigned char *) &(expr->item)); \
else if (sizeof(expr->item) == 1) \
AppendJumble8(jstate, (const unsigned char *) &(expr->item)); \
AppendJumble(jstate, (const unsigned char *) &(expr->item), sizeof(expr->item)); \
} while (0)
static void AppendJumble(JumbleState *jstate, const unsigned char *value, Size size)

Definition at line 493 of file queryjumblefuncs.c.

◆ JUMBLE_LOCATION

#define JUMBLE_LOCATION (   location)     RecordConstLocation(jstate, expr->location, false)

Definition at line 491 of file queryjumblefuncs.c.

◆ JUMBLE_NODE

#define JUMBLE_NODE (   item)     _jumbleNode(jstate, (Node *) expr->item)

Definition at line 487 of file queryjumblefuncs.c.

◆ JUMBLE_SIZE

#define JUMBLE_SIZE   1024 /* query serialization buffer size */

Definition at line 44 of file queryjumblefuncs.c.

◆ JUMBLE_STRING

#define JUMBLE_STRING (   str)
Value:
do { \
if (expr->str) \
AppendJumble(jstate, (const unsigned char *) (expr->str), strlen(expr->str) + 1); \
} while(0)
static pg_attribute_always_inline void AppendJumbleNull(JumbleState *jstate)

Definition at line 506 of file queryjumblefuncs.c.

Function Documentation

◆ _jumbleA_Const()

static void _jumbleA_Const ( JumbleState jstate,
Node node 
)
static

Definition at line 652 of file queryjumblefuncs.c.

653{
654 A_Const *expr = (A_Const *) node;
655
656 JUMBLE_FIELD(isnull);
657 if (!expr->isnull)
658 {
659 JUMBLE_FIELD(val.node.type);
660 switch (nodeTag(&expr->val))
661 {
662 case T_Integer:
663 JUMBLE_FIELD(val.ival.ival);
664 break;
665 case T_Float:
666 JUMBLE_STRING(val.fval.fval);
667 break;
668 case T_Boolean:
669 JUMBLE_FIELD(val.boolval.boolval);
670 break;
671 case T_String:
672 JUMBLE_STRING(val.sval.sval);
673 break;
674 case T_BitString:
675 JUMBLE_STRING(val.bsval.bsval);
676 break;
677 default:
678 elog(ERROR, "unrecognized node type: %d",
679 (int) nodeTag(&expr->val));
680 break;
681 }
682 }
683}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
long val
Definition: informix.c:689
#define nodeTag(nodeptr)
Definition: nodes.h:139
#define JUMBLE_STRING(str)
#define JUMBLE_FIELD(item)
bool isnull
Definition: parsenodes.h:374
union ValUnion val
Definition: parsenodes.h:373

References elog, ERROR, A_Const::isnull, JUMBLE_FIELD, JUMBLE_STRING, nodeTag, A_Const::val, and val.

◆ _jumbleElements()

static void _jumbleElements ( JumbleState jstate,
List elements 
)
static

Definition at line 526 of file queryjumblefuncs.c.

527{
528 Node *first,
529 *last;
530
531 if (IsSquashableConstList(elements, &first, &last))
532 {
533 /*
534 * If this list of elements is squashable, keep track of the location
535 * of its first and last elements. When reading back the locations
536 * array, we'll see two consecutive locations with ->squashed set to
537 * true, indicating the location of initial and final elements of this
538 * list.
539 *
540 * For the limited set of cases we support now (implicit coerce via
541 * FuncExpr, Const) it's fine to use exprLocation of the 'last'
542 * expression, but if more complex composite expressions are to be
543 * supported (e.g., OpExpr or FuncExpr as an explicit call), more
544 * sophisticated tracking will be needed.
545 */
546 RecordConstLocation(jstate, exprLocation(first), true);
547 RecordConstLocation(jstate, exprLocation(last), true);
548 }
549 else
550 {
551 _jumbleNode(jstate, (Node *) elements);
552 }
553}
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1388
static void _jumbleNode(JumbleState *jstate, Node *node)
static void RecordConstLocation(JumbleState *jstate, int location, bool squashed)
static bool IsSquashableConstList(List *elements, Node **firstExpr, Node **lastExpr)
Definition: nodes.h:135

References _jumbleNode(), exprLocation(), IsSquashableConstList(), and RecordConstLocation().

◆ _jumbleList()

static void _jumbleList ( JumbleState jstate,
Node node 
)
static

Definition at line 621 of file queryjumblefuncs.c.

622{
623 List *expr = (List *) node;
624 ListCell *l;
625
626 switch (expr->type)
627 {
628 case T_List:
629 foreach(l, expr)
630 _jumbleNode(jstate, lfirst(l));
631 break;
632 case T_IntList:
633 foreach(l, expr)
634 AppendJumble32(jstate, (const unsigned char *) &lfirst_int(l));
635 break;
636 case T_OidList:
637 foreach(l, expr)
638 AppendJumble32(jstate, (const unsigned char *) &lfirst_oid(l));
639 break;
640 case T_XidList:
641 foreach(l, expr)
642 AppendJumble32(jstate, (const unsigned char *) &lfirst_xid(l));
643 break;
644 default:
645 elog(ERROR, "unrecognized list node type: %d",
646 (int) expr->type);
647 return;
648 }
649}
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_int(lc)
Definition: pg_list.h:173
#define lfirst_oid(lc)
Definition: pg_list.h:174
#define lfirst_xid(lc)
Definition: pg_list.h:175
static pg_noinline void AppendJumble32(JumbleState *jstate, const unsigned char *value)
Definition: pg_list.h:54
NodeTag type
Definition: pg_list.h:55

References _jumbleNode(), AppendJumble32(), elog, ERROR, lfirst, lfirst_int, lfirst_oid, lfirst_xid, and List::type.

Referenced by _jumbleNode().

◆ _jumbleNode()

static void _jumbleNode ( JumbleState jstate,
Node node 
)
static

Definition at line 556 of file queryjumblefuncs.c.

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 {
565 AppendJumbleNull(jstate);
566 return;
567 }
568
569 /* Guard against stack overflow due to overly complex expressions */
571
572 /*
573 * We always emit the node's NodeTag, then any additional fields that are
574 * considered significant, and then we recurse to any child nodes.
575 */
577
578 switch (nodeTag(expr))
579 {
580#include "queryjumblefuncs.switch.c"
581
582 case T_List:
583 case T_IntList:
584 case T_OidList:
585 case T_XidList:
586 _jumbleList(jstate, expr);
587 break;
588
589 default:
590 /* Only a warning, since we can stumble along anyway */
591 elog(WARNING, "unrecognized node type: %d",
592 (int) nodeTag(expr));
593 break;
594 }
595
596 /* Special cases to handle outside the automated code */
597 switch (nodeTag(expr))
598 {
599 case T_Param:
600 {
601 Param *p = (Param *) node;
602
603 /*
604 * Update the highest Param id seen, in order to start
605 * normalization correctly.
606 */
607 if (p->paramkind == PARAM_EXTERN &&
608 p->paramid > jstate->highest_extern_param_id)
609 jstate->highest_extern_param_id = p->paramid;
610 }
611 break;
612 default:
613 break;
614 }
615
616 /* Ensure we added something to the jumble buffer */
617 Assert(jstate->total_jumble_len > prev_jumble_len);
618}
size_t Size
Definition: c.h:576
#define WARNING
Definition: elog.h:36
Assert(PointerIsAligned(start, uint64))
@ PARAM_EXTERN
Definition: primnodes.h:384
static void _jumbleList(JumbleState *jstate, Node *node)
void check_stack_depth(void)
Definition: stack_depth.c:95
int highest_extern_param_id
Definition: queryjumble.h:56
int paramid
Definition: primnodes.h:394
ParamKind paramkind
Definition: primnodes.h:393
const char * type

References _jumbleList(), AppendJumbleNull(), Assert(), check_stack_depth(), elog, JumbleState::highest_extern_param_id, JUMBLE_FIELD, nodeTag, PARAM_EXTERN, Param::paramid, Param::paramkind, type, and WARNING.

Referenced by _jumbleElements(), _jumbleList(), and DoJumble().

◆ _jumbleRangeTblEntry_eref()

static void _jumbleRangeTblEntry_eref ( JumbleState jstate,
RangeTblEntry rte,
Alias expr 
)
static

Definition at line 707 of file queryjumblefuncs.c.

710{
712
713 /*
714 * This includes only the table name, the list of column names is ignored.
715 */
716 JUMBLE_STRING(aliasname);
717}

References JUMBLE_FIELD, JUMBLE_STRING, and type.

◆ _jumbleVariableSetStmt()

static void _jumbleVariableSetStmt ( JumbleState jstate,
Node node 
)
static

Definition at line 686 of file queryjumblefuncs.c.

687{
688 VariableSetStmt *expr = (VariableSetStmt *) node;
689
690 JUMBLE_FIELD(kind);
692
693 /*
694 * Account for the list of arguments in query jumbling only if told by the
695 * parser.
696 */
697 if (expr->jumble_args)
699 JUMBLE_FIELD(is_local);
700 JUMBLE_LOCATION(location);
701}
#define JUMBLE_NODE(item)
#define JUMBLE_LOCATION(location)
const char * name

References generate_unaccent_rules::args, VariableSetStmt::jumble_args, JUMBLE_FIELD, JUMBLE_LOCATION, JUMBLE_NODE, JUMBLE_STRING, and name.

◆ AppendJumble()

static pg_noinline void AppendJumble ( JumbleState jstate,
const unsigned char *  value,
Size  size 
)
static

Definition at line 285 of file queryjumblefuncs.c.

286{
287 if (jstate->pending_nulls > 0)
288 FlushPendingNulls(jstate);
289
290 AppendJumbleInternal(jstate, value, size);
291}
static struct @165 value
static pg_attribute_always_inline void AppendJumbleInternal(JumbleState *jstate, const unsigned char *item, Size size)
static void FlushPendingNulls(JumbleState *jstate)
unsigned int pending_nulls
Definition: queryjumble.h:63

References AppendJumbleInternal(), FlushPendingNulls(), JumbleState::pending_nulls, and value.

◆ AppendJumble16()

static pg_noinline void AppendJumble16 ( JumbleState jstate,
const unsigned char *  value 
)
static

Definition at line 322 of file queryjumblefuncs.c.

323{
324 if (jstate->pending_nulls > 0)
325 FlushPendingNulls(jstate);
326
327 AppendJumbleInternal(jstate, value, 2);
328}

References AppendJumbleInternal(), FlushPendingNulls(), JumbleState::pending_nulls, and value.

◆ AppendJumble32()

static pg_noinline void AppendJumble32 ( JumbleState jstate,
const unsigned char *  value 
)
static

Definition at line 336 of file queryjumblefuncs.c.

337{
338 if (jstate->pending_nulls > 0)
339 FlushPendingNulls(jstate);
340
341 AppendJumbleInternal(jstate, value, 4);
342}

References AppendJumbleInternal(), FlushPendingNulls(), JumbleState::pending_nulls, and value.

Referenced by _jumbleList().

◆ AppendJumble64()

static pg_noinline void AppendJumble64 ( JumbleState jstate,
const unsigned char *  value 
)
static

Definition at line 350 of file queryjumblefuncs.c.

351{
352 if (jstate->pending_nulls > 0)
353 FlushPendingNulls(jstate);
354
355 AppendJumbleInternal(jstate, value, 8);
356}

References AppendJumbleInternal(), FlushPendingNulls(), JumbleState::pending_nulls, and value.

◆ AppendJumble8()

static pg_noinline void AppendJumble8 ( JumbleState jstate,
const unsigned char *  value 
)
static

Definition at line 308 of file queryjumblefuncs.c.

309{
310 if (jstate->pending_nulls > 0)
311 FlushPendingNulls(jstate);
312
313 AppendJumbleInternal(jstate, value, 1);
314}

References AppendJumbleInternal(), FlushPendingNulls(), JumbleState::pending_nulls, and value.

◆ AppendJumbleInternal()

static pg_attribute_always_inline void AppendJumbleInternal ( JumbleState jstate,
const unsigned char *  item,
Size  size 
)
static

Definition at line 222 of file queryjumblefuncs.c.

224{
225 unsigned char *jumble = jstate->jumble;
226 Size jumble_len = jstate->jumble_len;
227
228 /* Ensure the caller didn't mess up */
229 Assert(size > 0);
230
231 /*
232 * Fast path for when there's enough space left in the buffer. This is
233 * worthwhile as means the memcpy can be inlined into very efficient code
234 * when 'size' is a compile-time constant.
235 */
236 if (likely(size <= JUMBLE_SIZE - jumble_len))
237 {
238 memcpy(jumble + jumble_len, item, size);
239 jstate->jumble_len += size;
240
241#ifdef USE_ASSERT_CHECKING
242 jstate->total_jumble_len += size;
243#endif
244
245 return;
246 }
247
248 /*
249 * Whenever the jumble buffer is full, we hash the current contents and
250 * reset the buffer to contain just that hash value, thus relying on the
251 * hash to summarize everything so far.
252 */
253 do
254 {
255 Size part_size;
256
257 if (unlikely(jumble_len >= JUMBLE_SIZE))
258 {
259 uint64 start_hash;
260
261 start_hash = DatumGetUInt64(hash_any_extended(jumble,
262 JUMBLE_SIZE, 0));
263 memcpy(jumble, &start_hash, sizeof(start_hash));
264 jumble_len = sizeof(start_hash);
265 }
266 part_size = Min(size, JUMBLE_SIZE - jumble_len);
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
277 jstate->jumble_len = jumble_len;
278}
#define Min(x, y)
Definition: c.h:975
#define likely(x)
Definition: c.h:346
uint64_t uint64
Definition: c.h:503
#define unlikely(x)
Definition: c.h:347
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37
static uint64 DatumGetUInt64(Datum X)
Definition: postgres.h:424
#define JUMBLE_SIZE
unsigned char * jumble
Definition: queryjumble.h:41
Size jumble_len
Definition: queryjumble.h:44

References Assert(), DatumGetUInt64(), hash_any_extended(), JumbleState::jumble, JumbleState::jumble_len, JUMBLE_SIZE, likely, Min, and unlikely.

Referenced by AppendJumble(), AppendJumble16(), AppendJumble32(), AppendJumble64(), AppendJumble8(), and FlushPendingNulls().

◆ AppendJumbleNull()

static pg_attribute_always_inline void AppendJumbleNull ( JumbleState jstate)
static

Definition at line 298 of file queryjumblefuncs.c.

299{
300 jstate->pending_nulls++;
301}

References JumbleState::pending_nulls.

Referenced by _jumbleNode().

◆ CleanQuerytext()

const char * CleanQuerytext ( const char *  query,
int *  location,
int *  len 
)

Definition at line 79 of file queryjumblefuncs.c.

80{
81 int query_location = *location;
82 int query_len = *len;
83
84 /* First apply starting offset, unless it's -1 (unknown). */
85 if (query_location >= 0)
86 {
87 Assert(query_location <= strlen(query));
88 query += query_location;
89 /* Length of 0 (or -1) means "rest of string" */
90 if (query_len <= 0)
91 query_len = strlen(query);
92 else
93 Assert(query_len <= strlen(query));
94 }
95 else
96 {
97 /* If query location is unknown, distrust query_len as well */
98 query_location = 0;
99 query_len = strlen(query);
100 }
101
102 /*
103 * Discard leading and trailing whitespace, too. Use scanner_isspace()
104 * not libc's isspace(), because we want to match the lexer's behavior.
105 *
106 * Note: the parser now strips leading comments and whitespace from the
107 * reported stmt_location, so this first loop will only iterate in the
108 * unusual case that the location didn't propagate to here. But the
109 * statement length will extend to the end-of-string or terminating
110 * semicolon, so the second loop often does something useful.
111 */
112 while (query_len > 0 && scanner_isspace(query[0]))
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}
const void size_t len
bool scanner_isspace(char ch)
Definition: scansup.c:117

References Assert(), len, and scanner_isspace().

Referenced by pgss_store(), and script_error_callback().

◆ DoJumble()

static uint64 DoJumble ( JumbleState jstate,
Node node 
)
static

Definition at line 201 of file queryjumblefuncs.c.

202{
203 /* Jumble the given node */
204 _jumbleNode(jstate, node);
205
206 /* Flush any pending NULLs before doing the final hash */
207 if (jstate->pending_nulls > 0)
208 FlushPendingNulls(jstate);
209
210 /* Process the jumble buffer and produce the hash value */
212 jstate->jumble_len,
213 0));
214}

References _jumbleNode(), DatumGetUInt64(), FlushPendingNulls(), hash_any_extended(), JumbleState::jumble, JumbleState::jumble_len, and JumbleState::pending_nulls.

Referenced by JumbleQuery().

◆ EnableQueryId()

void EnableQueryId ( void  )

Definition at line 162 of file queryjumblefuncs.c.

163{
165 query_id_enabled = true;
166}
@ COMPUTE_QUERY_ID_OFF
Definition: queryjumble.h:74
bool query_id_enabled
int compute_query_id

References compute_query_id, COMPUTE_QUERY_ID_OFF, and query_id_enabled.

Referenced by _PG_init().

◆ FlushPendingNulls()

static pg_attribute_always_inline void FlushPendingNulls ( JumbleState jstate)
static

Definition at line 365 of file queryjumblefuncs.c.

366{
367 Assert(jstate->pending_nulls > 0);
368
370 (const unsigned char *) &jstate->pending_nulls, 4);
371 jstate->pending_nulls = 0;
372}

References AppendJumbleInternal(), Assert(), and JumbleState::pending_nulls.

Referenced by AppendJumble(), AppendJumble16(), AppendJumble32(), AppendJumble64(), AppendJumble8(), and DoJumble().

◆ InitJumble()

static JumbleState * InitJumble ( void  )
static

Definition at line 173 of file queryjumblefuncs.c.

174{
175 JumbleState *jstate;
176
177 jstate = (JumbleState *) palloc(sizeof(JumbleState));
178
179 /* Set up workspace for query jumbling */
180 jstate->jumble = (unsigned char *) palloc(JUMBLE_SIZE);
181 jstate->jumble_len = 0;
182 jstate->clocations_buf_size = 32;
183 jstate->clocations = (LocationLen *) palloc(jstate->clocations_buf_size *
184 sizeof(LocationLen));
185 jstate->clocations_count = 0;
186 jstate->highest_extern_param_id = 0;
187 jstate->pending_nulls = 0;
188#ifdef USE_ASSERT_CHECKING
189 jstate->total_jumble_len = 0;
190#endif
191
192 return jstate;
193}
void * palloc(Size size)
Definition: mcxt.c:1943
int clocations_buf_size
Definition: queryjumble.h:50
LocationLen * clocations
Definition: queryjumble.h:47
int clocations_count
Definition: queryjumble.h:53

References JumbleState::clocations, JumbleState::clocations_buf_size, JumbleState::clocations_count, JumbleState::highest_extern_param_id, JumbleState::jumble, JumbleState::jumble_len, JUMBLE_SIZE, palloc(), and JumbleState::pending_nulls.

Referenced by JumbleQuery().

◆ IsSquashableConst()

static bool IsSquashableConst ( Node element)
static

Definition at line 416 of file queryjumblefuncs.c.

417{
418 if (IsA(element, RelabelType))
419 element = (Node *) ((RelabelType *) element)->arg;
420
421 if (IsA(element, CoerceViaIO))
422 element = (Node *) ((CoerceViaIO *) element)->arg;
423
424 if (IsA(element, FuncExpr))
425 {
426 FuncExpr *func = (FuncExpr *) element;
427 ListCell *temp;
428
429 if (func->funcformat != COERCE_IMPLICIT_CAST &&
430 func->funcformat != COERCE_EXPLICIT_CAST)
431 return false;
432
433 if (func->funcid > FirstGenbkiObjectId)
434 return false;
435
436 foreach(temp, func->args)
437 {
438 Node *arg = lfirst(temp);
439
440 if (!IsA(arg, Const)) /* XXX we could recurse here instead */
441 return false;
442 }
443
444 return true;
445 }
446
447 if (!IsA(element, Const))
448 return false;
449
450 return true;
451}
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
void * arg
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:753
@ COERCE_EXPLICIT_CAST
Definition: primnodes.h:752
static chr element(struct vars *v, const chr *startp, const chr *endp)
Definition: regc_locale.c:376
Oid funcid
Definition: primnodes.h:767
List * args
Definition: primnodes.h:785
#define FirstGenbkiObjectId
Definition: transam.h:195

References arg, FuncExpr::args, COERCE_EXPLICIT_CAST, COERCE_IMPLICIT_CAST, element(), FirstGenbkiObjectId, FuncExpr::funcid, IsA, and lfirst.

Referenced by IsSquashableConstList().

◆ IsSquashableConstList()

static bool IsSquashableConstList ( List elements,
Node **  firstExpr,
Node **  lastExpr 
)
static

Definition at line 464 of file queryjumblefuncs.c.

465{
466 ListCell *temp;
467
468 /*
469 * If squashing is disabled, or the list is too short, we don't try to
470 * squash it.
471 */
472 if (list_length(elements) < 2)
473 return false;
474
475 foreach(temp, elements)
476 {
477 if (!IsSquashableConst(lfirst(temp)))
478 return false;
479 }
480
481 *firstExpr = linitial(elements);
482 *lastExpr = llast(elements);
483
484 return true;
485}
#define llast(l)
Definition: pg_list.h:198
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
static bool IsSquashableConst(Node *element)

References IsSquashableConst(), lfirst, linitial, list_length(), and llast.

Referenced by _jumbleElements().

◆ JumbleQuery()

JumbleState * JumbleQuery ( Query query)

Definition at line 130 of file queryjumblefuncs.c.

131{
132 JumbleState *jstate;
133
135
136 jstate = InitJumble();
137
138 query->queryId = DoJumble(jstate, (Node *) query);
139
140 /*
141 * If we are unlucky enough to get a hash of zero, use 1 instead for
142 * normal statements and 2 for utility queries.
143 */
144 if (query->queryId == UINT64CONST(0))
145 {
146 if (query->utilityStmt)
147 query->queryId = UINT64CONST(2);
148 else
149 query->queryId = UINT64CONST(1);
150 }
151
152 return jstate;
153}
#define UINT64CONST(x)
Definition: c.h:517
static bool IsQueryIdEnabled(void)
Definition: queryjumble.h:95
static uint64 DoJumble(JumbleState *jstate, Node *node)
static JumbleState * InitJumble(void)
Node * utilityStmt
Definition: parsenodes.h:136

References Assert(), DoJumble(), InitJumble(), IsQueryIdEnabled(), UINT64CONST, and Query::utilityStmt.

Referenced by ExecCreateTableAs(), ExplainOneUtility(), ExplainQuery(), parse_analyze_fixedparams(), parse_analyze_varparams(), parse_analyze_withcb(), and PerformCursorOpen().

◆ RecordConstLocation()

static void RecordConstLocation ( JumbleState jstate,
int  location,
bool  squashed 
)
static

Definition at line 384 of file queryjumblefuncs.c.

385{
386 /* -1 indicates unknown or undefined location */
387 if (location >= 0)
388 {
389 /* enlarge array if needed */
390 if (jstate->clocations_count >= jstate->clocations_buf_size)
391 {
392 jstate->clocations_buf_size *= 2;
393 jstate->clocations = (LocationLen *)
394 repalloc(jstate->clocations,
395 jstate->clocations_buf_size *
396 sizeof(LocationLen));
397 }
398 jstate->clocations[jstate->clocations_count].location = location;
399 /* initialize lengths to -1 to simplify third-party module usage */
400 jstate->clocations[jstate->clocations_count].squashed = squashed;
401 jstate->clocations[jstate->clocations_count].length = -1;
402 jstate->clocations_count++;
403 }
404}
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2170
bool squashed
Definition: queryjumble.h:31

References JumbleState::clocations, JumbleState::clocations_buf_size, JumbleState::clocations_count, LocationLen::length, LocationLen::location, repalloc(), and LocationLen::squashed.

Referenced by _jumbleElements().

Variable Documentation

◆ compute_query_id

int compute_query_id = COMPUTE_QUERY_ID_AUTO

Definition at line 47 of file queryjumblefuncs.c.

Referenced by EnableQueryId(), ExplainPrintPlan(), and IsQueryIdEnabled().

◆ query_id_enabled

bool query_id_enabled = false

Definition at line 56 of file queryjumblefuncs.c.

Referenced by EnableQueryId(), and IsQueryIdEnabled().