PostgreSQL pgbench : 冒号处理
背景
pgbench 的自定义测试脚本中,冒号有特殊的含义,可以用于变量名的前面,表示这个位置使用变?刻婊弧?
/*----------
* Join arguments with whitespace separators. Arguments starting with
* exactly one colon are treated as variables:
* name - append a string "name"
* :var - append a variable named 'var'
* ::name - append a string ":name"
*----------
*/
for (i = 0; i < argc; i++)
{
char *arg;
int arglen;
if (argv[i][0] != ':')
{
arg = argv[i]; /* a string literal */
}
else if (argv[i][1] == ':')
{
arg = argv[i] + 1; /* a string literal starting
with colons */
}
else if ((arg = getVariable(st, argv[i] + 1)) == NULL)
{
fprintf(stderr, "%s: undefined variable \"%s\"\n",
argv[0], argv[i]);
return false;
}
arglen = strlen(arg);
if (len + arglen + (i > 0 ? 1 : 0) >= SHELL_COMMAND_SIZE - 1)
{
fprintf(stderr, "%s: shell command is too long\n",
argv[0]);
return false;
}
if (i > 0)
command[len++] = ' ';
memcpy(command + len, arg, arglen);
len += arglen;
}
例如,
1、以下ab为变量名,:ab表示这个地方用变量替换。
vi test.sql
\set ab random(1,100000)
select * from tbl where id=:ab;
2、如果要输入一个冒号开头的常量,可以输入两个冒号。
::name表示:name常量。
3、如果在字符中间输入,两个冒号,直接输入两个冒号即可。
4、
如果要在字符串中间使用冒号,怎么写呢?
vi test.sql
select * from tbl where ts > '2017-01-01 10:10:10';
这样不行,会将:10和:10都翻译成变量10的值。
这样也不行,字符串中两个冒号就是两个冒号,不会变成一个。
vi test.sql
select * from tbl where ts > '2017-01-01 10::10::10';
冒号作为字符串中的内容
1、使用-D参数,适合所有无法正常解析customer script的场景。
使用pgbench -D参数,输入的变量,不需要过customer script的parser ,所以可以避免问题。
vi test.sql
select now() > :a::timestamp;
pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120 -D a="1999-1-
1 10:1:1"
达到的效果是
select now() > '1999-1-1 10:1:1'::timestamp;
2、使用格式化函数,适合某些场景。
前面那条SQL可以改成
vi test.sql
select now() > to_timestamp('2017-01-01 10::10::10','yyyy-mm-dd hh24::mi::ss')
;
pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120
参考
https://www.postgresql.org/docs/10/static/pgbench.html