From: Pavan Deolasee Date: Thu, 3 Mar 2016 09:31:06 +0000 (+0530) Subject: Avoid repeated palloc for query strings while handling multi-statement SQLs X-Git-Tag: XL9_5_R1BETA2~41 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=8ea0a7aa1d0c4480517da7486c5bb5f95868c41a;p=postgres-xl.git 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 --- diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 4593316fb9..c42e59a437 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -778,7 +778,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 @@ -787,12 +788,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 @@ -804,7 +809,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 @@ -825,7 +829,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 52dd180877..a7ee658a5d 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];