Skip to content

Commit

Permalink
Optmize query denomalization(2)
Browse files Browse the repository at this point in the history
Avoid allocating an array of strings for extracting query argument
values, instead append the current parameter value directly in the
buffer used to store the denormalized query.

This avoids not only unnecessary memory allocations, but also copying
data between temporary memory and the buffer.
  • Loading branch information
darkfronza committed Aug 5, 2024
1 parent 31e4eba commit 442f055
Showing 1 changed file with 25 additions and 47 deletions.
72 changes: 25 additions & 47 deletions pg_stat_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,11 @@ static void pgsm_add_to_list(pgsmEntry * entry, char *query_text, int query_len)
static pgsmEntry * pgsm_get_entry_for_query(uint64 queryid, PlanInfo * plan_info, const char *query_text, int query_len, bool create);
static uint64 get_pgsm_query_id_hash(const char *norm_query, int len);

/* transform parameters value from datum to string*/
static char **get_params_text_list(const ParamListInfo paramlist);
/*
* extract parameter value (Datum) from plist->params[idx], cast it to string then
* append the resulting string to the buffer.
*/
static void get_param_value(const ParamListInfo plist, int idx, StringInfoData *buffer);

/* denormalize the query, replace placeholders with actual values */
static StringInfoData get_denormalized_query(const ParamListInfo paramlist, const char *query_text);
Expand Down Expand Up @@ -4014,72 +4017,50 @@ get_query_id(JumbleState *jstate, Query *query)
}
#endif

static char **
get_params_text_list(const ParamListInfo paramlist)
void
get_param_value(const ParamListInfo plist, int idx, StringInfoData *buffer)
{
StringInfoData buf;
int entry_num = paramlist->numParams;
int i;
char **params_text;

initStringInfo(&buf);
params_text = (char **)palloc0(sizeof(char *) * entry_num);
Oid typoutput;
bool typisvarlena;
char *pstring;
ParamExternData *param;

for(i = 0; i < entry_num; i++)
{
ParamExternData *param = &paramlist->params[i];
Assert(idx < plist->numParams);

if (param->isnull || !OidIsValid(param->ptype))
{
appendStringInfoString(&buf, "NULL");
}
else
{
Oid typoutput;
bool typisvarlena;
char *pstring;
param = &plist->params[idx];

getTypeOutputInfo(param->ptype, &typoutput, &typisvarlena);
pstring = OidOutputFunctionCall(typoutput, param->value);
appendStringInfo(&buf, "%s",pstring);
}

/* assign memory space and add terminate symbol at the end of string*/
params_text[i] = (char *)palloc0(sizeof(char) * (buf.len + 1));
memcpy(params_text[i], buf.data, buf.len);
memset(params_text[i] + sizeof(char) * buf.len,'\0',sizeof(char));

/*clean the temp buffer*/
resetStringInfo(&buf);
if (param->isnull || !OidIsValid(param->ptype))
{
appendStringInfoString(&buffer, "NULL");
return;
}

return params_text;
getTypeOutputInfo(param->ptype, &typoutput, &typisvarlena);
pstring = OidOutputFunctionCall(typoutput, param->value);
appendStringInfo(buffer, "%s", pstring);
}

StringInfoData
get_denormalized_query(const ParamListInfo paramlist, const char *query_text)
{
int current_param;
int param_num;
int i;
char **param_text;
const char *cursor_ori;
const char *cursor_curr;
StringInfoData result_buf;
ptrdiff_t len;

param_text = get_params_text_list(paramlist);
param_num = paramlist->numParams;
current_param = 0;
cursor_ori = query_text;
cursor_curr = cursor_ori;

initStringInfo(&result_buf);

do
{
// advance cursor until detecting a placeholder '$' start.
while (*cursor_ori && *cursor_ori != '$')
++cursor_ori;
++cursor_ori;

// calculate length of query text before placeholder.
len = cursor_ori - cursor_curr;
Expand Down Expand Up @@ -4109,14 +4090,11 @@ get_denormalized_query(const ParamListInfo paramlist, const char *query_text)
cursor_curr = cursor_ori;

/* replace the placeholder with actual value */
appendStringInfoString(&result_buf, param_text[current_param++]);
} while (*cursor_ori != '\0');
get_param_value(paramlist, current_param, &result_buf);

/* free the query text array*/
for(i = 0; i < param_num; i++)
pfree(param_text[i]);
++current_param;
} while (*cursor_ori != '\0');

pfree(param_text);

return result_buf;
}

0 comments on commit 442f055

Please sign in to comment.