diff options
author | Pavan Deolasee | 2016-03-03 09:31:06 +0000 |
---|---|---|
committer | Pavan Deolasee | 2016-10-18 10:00:18 +0000 |
commit | 89388618074bd57888e0ff838479f7e971d05e47 (patch) | |
tree | ad6cb8abe74d48541c2ad4cb52e9df8295863105 | |
parent | 455ff923454e78d80b77639a381db9b05c776577 (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.y | 18 | ||||
-rw-r--r-- | src/backend/parser/scan.l | 4 | ||||
-rw-r--r-- | src/backend/tcop/postgres.c | 2 |
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]; |