* parse_analyze() or the rewriter, but instead we need to pass them
* through parse_utilcmd.c to make them ready for execution.
*/
- raw_parsetree_list = raw_parser(cmd, NULL);
+ raw_parsetree_list = raw_parser(cmd);
querytree_list = NIL;
foreach(list_item, raw_parsetree_list)
{
List *table_names;
} ImportQual;
-typedef struct StmtMulti
-{
- List *parsetrees;
- List *queries;
- int offset;
- char *lastQuery;
-} StmtMulti;
-
/* ConstraintAttributeSpec yields an integer bitmask of these flags: */
#define CAS_NOT_DEFERRABLE 0x01
#define CAS_DEFERRABLE 0x02
InsertStmt *istmt;
VariableSetStmt *vsetstmt;
/* PGXC_BEGIN */
- struct StmtMulti *stmtmulti;
DistributeBy *distby;
PGXCSubCluster *subclus;
/* PGXC_END */
%type <ival> import_qualification_type
%type <importqual> import_qualification
-%type <stmtmulti> stmtmulti
-%type <list> stmtblock
+%type <list> stmtblock stmtmulti
OptTableElementList TableElementList OptInherit definition
OptTypedTableElementList TypedTableElementList
reloptions opt_reloptions
*/
stmtblock: stmtmulti
{
- pg_yyget_extra(yyscanner)->parsetree = $1 ? $1->parsetrees : NIL;
- pg_yyget_extra(yyscanner)->queries = $1 ? $1->queries : NIL;
+ pg_yyget_extra(yyscanner)->parsetree = $1;
}
;
*/
stmtmulti: stmtmulti ';' stmt
{
- /*
- * XXX PG10MERGE: Looks like support for obtaining raw
- * query string for individual commands is added in PG10.
- * If so, we can make use of the same infrastructure.
- *
- * XXX The following gives a compilation WARNING because
- * stmtmulti is defined as a List in PG10, but we have our
- * own definition.
- */
if ($1 != NIL)
{
/* update length of previous stmt */
updateRawStmtEnd(llast_node(RawStmt, $1), @2);
}
- if ($3 != NULL)
- {
- char *query;
- ListCell *last;
- /*
- * Because of the way multi-commands are parsed by the
- * parser, when the earlier command was parsed and
- * reduced to a 'stmtmulti', we did not have the
- * end-of-the-query marker. But now that we have seen
- * the ';' token, add '\0' at the corresponding offset
- * to get a separated command.
- */
- if ($1 != NULL)
- {
- 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, query);
- $$ = $1;
- }
- /*
- *
- * If the earlier statements were all null, then we
- * must initialise the StmtMulti structure and make
- * singleton lists
- */
- else
- {
- StmtMulti *n = (StmtMulti *) palloc0(sizeof (StmtMulti));
- query = scanner_get_query(@3, -1, yyscanner);
- n->offset = @2;
- n->parsetrees = list_make1($3);
- n->queries = list_make1(query);
- $$ = n;
- }
- }
if ($3 != NULL)
$$ = lappend($1, makeRawStmt($3, @2 + 1));
else
}
| stmt
{
- if ($1 != NULL)
- {
- StmtMulti *n = (StmtMulti *) palloc0(sizeof (StmtMulti));
- char *query = scanner_get_query(@1, -1, yyscanner);
-
- /*
- * Keep track of the offset where $1 started. We don't
- * have the offset where it ends so we copy the entire
- * query to the end. If later, we find a ';' followed
- * by another command, we'll add the '\0' at the
- * appropriate offset
- *
- * XXX May be there is a better way to get the matching
- * portion of the query string, but this does the trick
- * for regression as well as the problem we are trying
- * to solve with multi-command queries
- */
- n->offset = @1;
-
- /*
- * Collect both parsetree as well as the original query
- * that resulted in the parsetree
- */
- n->parsetrees = list_make1($1);
- n->queries = list_make1(query);
- $$ = n;
- }
if ($1 != NULL)
$$ = list_make1(makeRawStmt($1, 0));
else
- $$ = NULL;
+ $$ = NIL;
}
;
ptserrcontext.previous = error_context_stack;
error_context_stack = &ptserrcontext;
- raw_parsetree_list = raw_parser(buf.data, NULL);
+ raw_parsetree_list = raw_parser(buf.data);
error_context_stack = ptserrcontext.previous;
* of the list are always RawStmt nodes.
*/
List *
-raw_parser(const char *str, List **queries)
+raw_parser(const char *str)
{
core_yyscan_t yyscanner;
base_yy_extra_type yyextra;
if (yyresult) /* error */
return NIL;
- if (queries)
- *queries = yyextra.queries;
-
return yyextra.parsetree;
}
yyext->keywords = keywords;
yyext->num_keywords = num_keywords;
-#ifdef XCP
- yyext->query = pstrdup(str);
-#endif
-
yyext->backslash_quote = backslash_quote;
yyext->escape_string_warning = escape_string_warning;
yyext->standard_conforming_strings = standard_conforming_strings;
if (ptr)
pfree(ptr);
}
-
-/*
- * Return a copy of a substring of the original query string, starting at
- * 'start' offset and 'len' bytes long, Be mindful of the invalid arguments
- * being passed by the caller
- */
-char *
-scanner_get_query(int start, int len, core_yyscan_t yyscanner)
-{
- char *query;
-
- /*
- * If the caller passes a wrong offset, just assume 0
- */
- if (start == -1)
- start = 0;
- if (start > strlen(yyextra->query))
- return NULL;
- /*
- * Similarly, if the passed-in length is more than remaining
- * bytes in the string, just return whatever is available
- */
- if (len == -1)
- len = strlen(yyextra->query) - start;
- else if (len + start > strlen(yyextra->query))
- return NULL;
-
- query = yyextra->query + start;
- return query;
-}
* we've seen a COMMIT or ABORT command; when we are in abort state, other
* commands are not processed any further than the raw parse stage.
*/
-static List *
-pg_parse_query_internal(const char *query_string, List **querysource_list)
+List *
+pg_parse_query(const char *query_string)
{
List *raw_parsetree_list;
if (log_parser_stats)
ResetUsage();
- raw_parsetree_list = raw_parser(query_string, querysource_list);
+ raw_parsetree_list = raw_parser(query_string);
if (log_parser_stats)
ShowUsage("PARSER STATISTICS");
return raw_parsetree_list;
}
-List *
-pg_parse_query(const char *query_string)
-{
- return pg_parse_query_internal(query_string, NULL);
-}
-
-List *
-pg_parse_query_get_source(const char *query_string, List **querysource_list)
-{
- return pg_parse_query_internal(query_string, querysource_list);
-}
-
/*
* Given a raw parsetree (gram.y output), and optionally information about
* types of parameter symbols ($n), perform parse analysis and rule rewriting.
MemoryContext oldcontext;
List *parsetree_list;
ListCell *parsetree_item;
- List *querysource_list;
- ListCell *querysource_item;
bool save_log_statement_stats = log_statement_stats;
bool was_logged = false;
bool isTopLevel;
* Do basic parsing of the query or queries (this should be safe even if
* we are in aborted transaction state!)
*/
- parsetree_list = pg_parse_query_get_source(query_string, &querysource_list);
+ parsetree_list = pg_parse_query(query_string);
#ifdef XCP
if (IS_PGXC_LOCAL_COORDINATOR && list_length(parsetree_list) > 1)
/*
* Run through the raw parsetree(s) and process each one.
*/
- forboth(parsetree_item, parsetree_list, querysource_item, querysource_list)
+ foreach(parsetree_item, parsetree_list)
{
RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item);
- char *querysource = (char *) lfirst(querysource_item);
bool snapshot_set = false;
const char *commandTag;
char completionTag[COMPLETION_TAG_BUFSIZE];
* We don't have to copy anything into the portal, because everything
* we are passing here is in MessageContext, which will outlive the
* portal anyway.
- *
- * The query_string may contain multiple commands separated by ';' and
- * we have a separate parsetree corresponding to each such command.
- * Since we later may send down the query to the remote nodes
- * (especially for utility queries), using the query_string is a
- * problem because the same query will be sent out multiple times, one
- * for each command processed. So we taught the parser to return the
- * portion of the query_string along with the parsetree and use that
- * while defining a portal below.
- *
- * XXX Since the portal expects to see a valid query_string, if the
- * substring is available, use the original query_string. Not elegant,
- * but far better than what we were doing earlier
*/
PortalDefineQuery(portal,
NULL,
- querysource ? querysource : query_string,
+ query_string,
commandTag,
plantree_list,
NULL);
* State variables that belong to the grammar.
*/
List *parsetree; /* final parse result is delivered here */
- List *queries;
} base_yy_extra_type;
/*
/* Primary entry point for the raw parsing functions */
-extern List *raw_parser(const char *str, List **queries);
+extern List *raw_parser(const char *str);
/* Utility functions exported by gram.y (perhaps these should be elsewhere) */
extern List *SystemFuncName(char *name);
char *scanbuf;
Size scanbuflen;
-#ifdef XCP
- /*
- * Pointer to the original query string
- */
- char *query;
-#endif
-
/*
* The keyword list to use.
*/
core_yyscan_t yyscanner);
extern int scanner_errposition(int location, core_yyscan_t yyscanner);
extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) pg_attribute_noreturn();
-extern char *scanner_get_query(int start, int len, core_yyscan_t yyscanner);
#endif /* SCANNER_H */
extern int log_statement;
extern List *pg_parse_query(const char *query_string);
-extern List *pg_parse_query_get_source(const char *query_string, List **queries);
extern List *pg_analyze_and_rewrite(RawStmt *parsetree,
const char *query_string,
Oid *paramTypes, int numParams,
error_context_stack = &syntax_errcontext;
oldCxt = MemoryContextSwitchTo(plpgsql_compile_tmp_cxt);
- (void) raw_parser(stmt, NULL);
+ (void) raw_parser(stmt);
MemoryContextSwitchTo(oldCxt);
/* Restore former ereport callback */