PostgreSQL Source Code git master
Loading...
Searching...
No Matches
queryjumble.h File Reference
#include "nodes/parsenodes.h"
Include dependency graph for queryjumble.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  LocationLen
 
struct  JumbleState
 

Typedefs

typedef struct LocationLen LocationLen
 
typedef struct JumbleState JumbleState
 

Enumerations

enum  ComputeQueryIdType { COMPUTE_QUERY_ID_OFF , COMPUTE_QUERY_ID_ON , COMPUTE_QUERY_ID_AUTO , COMPUTE_QUERY_ID_REGRESS }
 

Functions

const charCleanQuerytext (const char *query, int *location, int *len)
 
LocationLenComputeConstantLengths (const JumbleState *jstate, const char *query, int query_loc)
 
JumbleStateJumbleQuery (Query *query)
 
void EnableQueryId (void)
 
static bool IsQueryIdEnabled (void)
 

Variables

PGDLLIMPORT int compute_query_id
 
PGDLLIMPORT bool query_id_enabled
 

Typedef Documentation

◆ JumbleState

◆ LocationLen

Enumeration Type Documentation

◆ ComputeQueryIdType

Enumerator
COMPUTE_QUERY_ID_OFF 
COMPUTE_QUERY_ID_ON 
COMPUTE_QUERY_ID_AUTO 
COMPUTE_QUERY_ID_REGRESS 

Definition at line 81 of file queryjumble.h.

82{
87};
@ COMPUTE_QUERY_ID_AUTO
Definition queryjumble.h:85
@ COMPUTE_QUERY_ID_REGRESS
Definition queryjumble.h:86
@ COMPUTE_QUERY_ID_ON
Definition queryjumble.h:84
@ COMPUTE_QUERY_ID_OFF
Definition queryjumble.h:83

Function Documentation

◆ CleanQuerytext()

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

Definition at line 88 of file queryjumblefuncs.c.

89{
90 int query_location = *location;
91 int query_len = *len;
92
93 /* First apply starting offset, unless it's -1 (unknown). */
94 if (query_location >= 0)
95 {
96 Assert(query_location <= strlen(query));
97 query += query_location;
98 /* Length of 0 (or -1) means "rest of string" */
99 if (query_len <= 0)
100 query_len = strlen(query);
101 else
102 Assert(query_len <= strlen(query));
103 }
104 else
105 {
106 /* If query location is unknown, distrust query_len as well */
107 query_location = 0;
108 query_len = strlen(query);
109 }
110
111 /*
112 * Discard leading and trailing whitespace, too. Use scanner_isspace()
113 * not libc's isspace(), because we want to match the lexer's behavior.
114 *
115 * Note: the parser now strips leading comments and whitespace from the
116 * reported stmt_location, so this first loop will only iterate in the
117 * unusual case that the location didn't propagate to here. But the
118 * statement length will extend to the end-of-string or terminating
119 * semicolon, so the second loop often does something useful.
120 */
121 while (query_len > 0 && scanner_isspace(query[0]))
122 query++, query_location++, query_len--;
123 while (query_len > 0 && scanner_isspace(query[query_len - 1]))
124 query_len--;
125
126 *location = query_location;
127 *len = query_len;
128
129 return query;
130}
#define Assert(condition)
Definition c.h:943
const void size_t len
static int fb(int x)
bool scanner_isspace(char ch)
Definition scansup.c:105

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

Referenced by pgss_store(), and script_error_callback().

◆ ComputeConstantLengths()

LocationLen * ComputeConstantLengths ( const JumbleState jstate,
const char query,
int  query_loc 
)
extern

Definition at line 822 of file queryjumblefuncs.c.

824{
826 core_yyscan_t yyscanner;
830
831 if (jstate->clocations_count == 0)
832 return NULL;
833
834 /* Copy constant locations to avoid modifying jstate */
835 locs = palloc_array(LocationLen, jstate->clocations_count);
836 memcpy(locs, jstate->clocations, jstate->clocations_count * sizeof(LocationLen));
837
838 /*
839 * Sort the records by location so that we can process them in order while
840 * scanning the query text.
841 */
842 if (jstate->clocations_count > 1)
843 qsort(locs, jstate->clocations_count,
844 sizeof(LocationLen), CompLocation);
845
846 /* initialize the flex scanner --- should match raw_parser() */
847 yyscanner = scanner_init(query,
848 &yyextra,
851
852 /* Search for each constant, in sequence */
853 for (int i = 0; i < jstate->clocations_count; i++)
854 {
855 int loc;
856 int tok;
857
858 /* Ignore constants after the first one in the same location */
859 if (i > 0 && locs[i].location == locs[i - 1].location)
860 {
861 locs[i].length = -1;
862 continue;
863 }
864
865 if (locs[i].squashed)
866 continue; /* squashable list, ignore */
867
868 /*
869 * Adjust the constant's location using the provided starting location
870 * of the current statement. This allows us to avoid scanning a
871 * multi-statement string from the beginning.
872 */
873 loc = locs[i].location - query_loc;
874 Assert(loc >= 0);
875
876 /*
877 * We have a valid location for a constant that's not a dupe. Lex
878 * tokens until we find the desired constant.
879 */
880 for (;;)
881 {
882 tok = core_yylex(&yylval, &yylloc, yyscanner);
883
884 /* We should not hit end-of-string, but if we do, behave sanely */
885 if (tok == 0)
886 break; /* out of inner for-loop */
887
888 /*
889 * We should find the token position exactly, but if we somehow
890 * run past it, work with that.
891 */
892 if (yylloc >= loc)
893 {
894 if (query[loc] == '-')
895 {
896 /*
897 * It's a negative value - this is the one and only case
898 * where we replace more than a single token.
899 *
900 * Do not compensate for the special-case adjustment of
901 * location to that of the leading '-' operator in the
902 * event of a negative constant (see doNegate() in
903 * gram.y). It is also useful for our purposes to start
904 * from the minus symbol. In this way, queries like
905 * "select * from foo where bar = 1" and "select * from
906 * foo where bar = -2" can be treated similarly.
907 */
908 tok = core_yylex(&yylval, &yylloc, yyscanner);
909 if (tok == 0)
910 break; /* out of inner for-loop */
911 }
912
913 /*
914 * We now rely on the assumption that flex has placed a zero
915 * byte after the text of the current token in scanbuf.
916 */
917 locs[i].length = strlen(yyextra.scanbuf + loc);
918 break; /* out of inner for-loop */
919 }
920 }
921
922 /* If we hit end-of-string, give up, leaving remaining lengths -1 */
923 if (tok == 0)
924 break;
925 }
926
927 scanner_finish(yyscanner);
928
929 return locs;
930}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define palloc_array(type, count)
Definition fe_memutils.h:76
int i
Definition isn.c:77
PGDLLIMPORT const ScanKeywordList ScanKeywords
#define qsort(a, b, c, d)
Definition port.h:495
const char * YYLTYPE
static int CompLocation(const void *a, const void *b)
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeywordList *keywordlist, const uint16 *keyword_tokens)
Definition scan.l:1233
#define yylloc
Definition scan.l:1106
void scanner_finish(core_yyscan_t yyscanner)
Definition scan.l:1273
#define yyextra
Definition scan.l:1102
const uint16 ScanKeywordTokens[]
Definition scan.l:80
void * core_yyscan_t
Definition scanner.h:118
int core_yylex(core_YYSTYPE *yylval_param, YYLTYPE *yylloc_param, core_yyscan_t yyscanner)

References Assert, CompLocation(), core_yylex(), fb(), i, memcpy(), palloc_array, qsort, ScanKeywords, ScanKeywordTokens, scanner_finish(), scanner_init(), yyextra, and yylloc.

Referenced by generate_normalized_query().

◆ EnableQueryId()

void EnableQueryId ( void  )
extern

Definition at line 171 of file queryjumblefuncs.c.

172{
174 query_id_enabled = true;
175}
bool query_id_enabled
int compute_query_id

References compute_query_id, COMPUTE_QUERY_ID_OFF, and query_id_enabled.

Referenced by _PG_init().

◆ IsQueryIdEnabled()

static bool IsQueryIdEnabled ( void  )
inlinestatic

◆ JumbleQuery()

JumbleState * JumbleQuery ( Query query)
extern

Definition at line 139 of file queryjumblefuncs.c.

140{
142
144
145 jstate = InitJumble();
146
147 query->queryId = DoJumble(jstate, (Node *) query);
148
149 /*
150 * If we are unlucky enough to get a hash of zero, use 1 instead for
151 * normal statements and 2 for utility queries.
152 */
153 if (query->queryId == INT64CONST(0))
154 {
155 if (query->utilityStmt)
156 query->queryId = INT64CONST(2);
157 else
158 query->queryId = INT64CONST(1);
159 }
160
161 return jstate;
162}
#define INT64CONST(x)
Definition c.h:630
static bool IsQueryIdEnabled(void)
static int64 DoJumble(JumbleState *jstate, Node *node)
static JumbleState * InitJumble(void)
Definition nodes.h:135
Node * utilityStmt
Definition parsenodes.h:141

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

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

Variable Documentation

◆ compute_query_id

PGDLLIMPORT int compute_query_id
extern

Definition at line 54 of file queryjumblefuncs.c.

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

◆ query_id_enabled

PGDLLIMPORT bool query_id_enabled
extern

Definition at line 63 of file queryjumblefuncs.c.

Referenced by EnableQueryId(), and IsQueryIdEnabled().