summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2016-03-03 09:31:06 +0000
committerPavan Deolasee2016-10-18 10:00:18 +0000
commit89388618074bd57888e0ff838479f7e971d05e47 (patch)
treead6cb8abe74d48541c2ad4cb52e9df8295863105
parent455ff923454e78d80b77639a381db9b05c776577 (diff)
Avoid repeated palloc for query strings while handling multi-statement SQLs
We now only pass pointers until we have the complete query string. At that point, we only required bytes and copy the query string
-rw-r--r--src/backend/parser/gram.y18
-rw-r--r--src/backend/parser/scan.l4
-rw-r--r--src/backend/tcop/postgres.c2
3 files changed, 13 insertions, 11 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index bf55f5060b..e912f0a87d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -779,7 +779,8 @@ stmtmulti: stmtmulti ';' stmt
{
if ($3 != NULL)
{
- char *query = scanner_get_query(@3, -1, yyscanner);
+ char *query;
+ ListCell *last;
/*
* Because of the way multi-commands are parsed by the
* parser, when the earlier command was parsed and
@@ -788,12 +789,16 @@ stmtmulti: stmtmulti ';' stmt
* the ';' token, add '\0' at the corresponding offset
* to get a separated command.
*/
- if ($1->lastQuery)
- $1->lastQuery[@2 - $1->offset] = '\0';
+ last = list_tail($1->queries);
+ query = palloc(@2 - $1->offset + 1);
+ memcpy(query, lfirst(last), @2 - $1->offset);
+ query[@2 - $1->offset] = '\0';
+
+ lfirst(last) = query;
+ query = scanner_get_query(@3, -1, yyscanner);
$1->offset = @2;
$1->parsetrees = lappend($1->parsetrees, $3);
- $1->queries = lappend($1->queries, makeString(query));
- $1->lastQuery = query;
+ $1->queries = lappend($1->queries, query);
$$ = $1;
}
else
@@ -805,7 +810,6 @@ stmtmulti: stmtmulti ';' stmt
{
StmtMulti *n = (StmtMulti *) palloc0(sizeof (StmtMulti));
char *query = scanner_get_query(@1, -1, yyscanner);
- n->lastQuery = query;
/*
* Keep track of the offset where $1 started. We don't
@@ -826,7 +830,7 @@ stmtmulti: stmtmulti ';' stmt
* that resulted in the parsetree
*/
n->parsetrees = list_make1($1);
- n->queries = list_make1(makeString(query));
+ n->queries = list_make1(query);
$$ = n;
}
else
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 0d36717f4e..359ec9ca89 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -1557,8 +1557,6 @@ scanner_get_query(int start, int len, core_yyscan_t yyscanner)
else if (len + start > strlen(yyextra->query))
return NULL;
- query = palloc0(len + 1);
- memcpy(query, yyextra->query + start, len);
- query[len] = '\0';
+ query = yyextra->query + start;
return query;
}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 6ffe015136..36e07dfcf8 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -1176,7 +1176,7 @@ exec_simple_query(const char *query_string)
forboth(parsetree_item, parsetree_list, querysource_item, querysource_list)
{
Node *parsetree = (Node *) lfirst(parsetree_item);
- char *querysource = ((Value *) lfirst(querysource_item))->val.str;
+ char *querysource = (char *) lfirst(querysource_item);
bool snapshot_set = false;
const char *commandTag;
char completionTag[COMPLETION_TAG_BUFSIZE];