Skip to content

Commit 260647a

Browse files
committed
possibility to use pseudovariables @@id, @@name and @@Signature in ECHO pragma
1 parent 3170b35 commit 260647a

File tree

4 files changed

+89
-31
lines changed

4 files changed

+89
-31
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ Shorter syntax for pragma is supported too:
765765

766766
## Supported pragmas
767767

768-
* `echo:str` - print string (for testing)
768+
* `echo:str` - print string (for testing). Inside string, there can be used "variables": @@id, @@name, @@signature
769769

770770
* `status:check`,`status:tracer`, `status:other_warnings`, `status:performance_warnings`, `status:extra_warnings`,`status:security_warnings`
771771
This outputs the current value (e.g. other_warnings enabled)

src/parser.c

Lines changed: 86 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,31 @@ static const char *tagstr = "@plpgsql_check_options:";
5454
#define PRAGMA_TOKEN_NUMBER 130
5555
#define PRAGMA_TOKEN_STRING 131
5656

57+
#ifdef _MSC_VER
58+
59+
static void *
60+
memmem(const void *haystack, size_t haystack_len,
61+
const void * const needle, const size_t needle_len)
62+
{
63+
if (haystack == NULL) return NULL; // or assert(haystack != NULL);
64+
if (haystack_len == 0) return NULL;
65+
if (needle == NULL) return NULL; // or assert(needle != NULL);
66+
if (needle_len == 0) return NULL;
67+
68+
for (const char *h = haystack;
69+
haystack_len >= needle_len;
70+
++h, --haystack_len)
71+
{
72+
if (!memcmp(h, needle, needle_len))
73+
{
74+
return h;
75+
}
76+
}
77+
return NULL;
78+
}
79+
80+
#endif
81+
5782
/*
5883
* Is character a valid identifier start?
5984
* Must match scan.l's {ident_start} character class.
@@ -1207,6 +1232,63 @@ get_table_comment_option(TokenizerState *tstate, const char *name, plpgsql_check
12071232
name, cinfo->fn_oid);
12081233
}
12091234

1235+
static bool
1236+
is_keyword(char *str, size_t bytes, const char *keyword)
1237+
{
1238+
if (bytes != strlen(keyword))
1239+
return false;
1240+
1241+
if (strncasecmp(str, keyword, bytes) != 0)
1242+
return false;
1243+
1244+
return true;
1245+
}
1246+
1247+
char *
1248+
plpgsql_check_process_echo_string(char *str, plpgsql_check_info *cinfo)
1249+
{
1250+
StringInfoData sinfo;
1251+
1252+
initStringInfo(&sinfo);
1253+
1254+
while (*str)
1255+
{
1256+
if (*str == '@' && str[1] == '@')
1257+
{
1258+
char *start;
1259+
size_t bytes;
1260+
1261+
str += 2;
1262+
start = str;
1263+
1264+
while (*str && isalpha(*str))
1265+
{
1266+
str += 1;
1267+
}
1268+
1269+
bytes = str - start;
1270+
if (is_keyword(start, bytes, "id"))
1271+
{
1272+
appendStringInfo(&sinfo, "%u", cinfo->fn_oid);
1273+
}
1274+
else if (is_keyword(start, bytes, "name"))
1275+
{
1276+
appendStringInfoString(&sinfo, get_func_name(cinfo->fn_oid));
1277+
}
1278+
else if (is_keyword(start, bytes, "signature"))
1279+
{
1280+
appendStringInfoString(&sinfo, format_procedure(cinfo->fn_oid));
1281+
}
1282+
else
1283+
appendStringInfo(&sinfo, "@@%.*s", (int) bytes, start);
1284+
}
1285+
else
1286+
appendStringInfoChar(&sinfo, *str++);
1287+
}
1288+
1289+
return sinfo.data;
1290+
}
1291+
12101292
static void
12111293
comment_options_parser(char *str, plpgsql_check_info *cinfo)
12121294
{
@@ -1305,13 +1387,13 @@ comment_options_parser(char *str, plpgsql_check_info *cinfo)
13051387
}
13061388

13071389
if (_token->value == PRAGMA_TOKEN_IDENTIF)
1308-
elog(NOTICE, "comment option \"echo\" is %s", make_string(_token));
1390+
elog(NOTICE, "comment option \"echo\" is %s", plpgsql_check_process_echo_string(make_string(_token), cinfo));
13091391
else if (_token->value == PRAGMA_TOKEN_QIDENTIF)
1310-
elog(NOTICE, "comment option \"echo\" is \"%s\"", make_string(_token));
1392+
elog(NOTICE, "comment option \"echo\" is \"%s\"", plpgsql_check_process_echo_string(make_string(_token), cinfo));
13111393
else if (_token->value == PRAGMA_TOKEN_NUMBER)
1312-
elog(NOTICE, "comment option \"echo\" is %s", make_string(_token));
1394+
elog(NOTICE, "comment option \"echo\" is %s", plpgsql_check_process_echo_string(make_string(_token), cinfo));
13131395
else if (_token->value == PRAGMA_TOKEN_STRING)
1314-
elog(NOTICE, "comment option \"echo\" is '%s'", make_string(_token));
1396+
elog(NOTICE, "comment option \"echo\" is '%s'", plpgsql_check_process_echo_string(make_string(_token), cinfo));
13151397
else
13161398
elog(NOTICE, "comment option \"echo\" is '%c'", _token->value);
13171399
}
@@ -1330,30 +1412,6 @@ comment_options_parser(char *str, plpgsql_check_info *cinfo)
13301412
while (_token);
13311413
}
13321414

1333-
#ifdef _MSC_VER
1334-
1335-
static void *
1336-
memmem(const void *haystack, size_t haystack_len,
1337-
const void * const needle, const size_t needle_len)
1338-
{
1339-
if (haystack == NULL) return NULL; // or assert(haystack != NULL);
1340-
if (haystack_len == 0) return NULL;
1341-
if (needle == NULL) return NULL; // or assert(needle != NULL);
1342-
if (needle_len == 0) return NULL;
1343-
1344-
for (const char *h = haystack;
1345-
haystack_len >= needle_len;
1346-
++h, --haystack_len)
1347-
{
1348-
if (!memcmp(h, needle, needle_len))
1349-
{
1350-
return h;
1351-
}
1352-
}
1353-
return NULL;
1354-
}
1355-
1356-
#endif
13571415

13581416
static void
13591417
comment_options_parsecontent(char *str, size_t bytes, plpgsql_check_info *cinfo)

src/plpgsql_check.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ extern Oid plpgsql_check_parse_name_or_signature(char *name_or_signature);
319319
extern bool plpgsql_check_pragma_type(PLpgSQL_checkstate *cstate, const char *str, PLpgSQL_nsitem *ns, int lineno);
320320
extern bool plpgsql_check_pragma_table(PLpgSQL_checkstate *cstate, const char *str, int lineno);
321321
extern void plpgsql_check_search_comment_options(plpgsql_check_info *cinfo);
322+
extern char *plpgsql_check_process_echo_string(char *str, plpgsql_check_info *cinfo);
322323

323324
/*
324325
* functions from profiler.c

src/pragma.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ pragma_apply(PLpgSQL_checkstate *cstate,
4444
while (*pragma_str == ' ')
4545
pragma_str++;
4646

47-
4847
if (strncasecmp(pragma_str, "ECHO:", 5) == 0)
4948
{
50-
elog(NOTICE, "%s", pragma_str + 5);
49+
elog(NOTICE, "%s", plpgsql_check_process_echo_string(pragma_str + 5, cstate->cinfo));
5150
}
5251
else if (strncasecmp(pragma_str, "STATUS:", 7) == 0)
5352
{

0 commit comments

Comments
 (0)