void CreateModel(CreateModelStmt *stmt,const char *queryString, DestReceiver *dest, char *completionTag) { List *query_list; List *planned_list; const char *commandTag; Portal portal; DestReceiver *tupledest; // create command Tag commandTag = CreateCommandTag(stmt->algorithmclause->trainingdata); // Rewrite the already analyzed Select query for the training data query_list = pg_rewrite_query((Query *)stmt->algorithmclause->trainingdata); // plan the query planned_list = pg_plan_queries(query_list,0,NULL); // results should be send to the ModelReceiver tupledest = CreateModelDestReceiver(stmt->modelname, (TargetEntry *)stmt->outputcolumn, stmt->timecolumns, ((Query *)stmt->algorithmclause->trainingdata)->jointree->quals, queryString,stmt->algorithmclause->algorithmname, ((AlgorithmClause *)copyObject(stmt->algorithmclause))->algorithmparameter, 0); // Create a new portal to run the query in portal = CreateNewPortal(); //Don't display the portal in pg_cursors, it is for internal use only portal->visible = false; PortalDefineQuery(portal, NULL, queryString, commandTag, planned_list, NULL); // Start the portal. No parameters here. PortalStart(portal, NULL, InvalidSnapshot); (void) PortalRun(portal, FETCH_ALL, false, tupledest, tupledest, completionTag); // Drop portal and receiver (*tupledest->rDestroy) (tupledest); PortalDrop(portal, false); }
/* * Implements the 'EXECUTE' utility statement. */ void ExecuteQuery(ExecuteStmt *stmt, ParamListInfo params, DestReceiver *dest, char *completionTag) { PreparedStatement *entry; char *query_string; List *query_list, *plan_list; MemoryContext qcontext; ParamListInfo paramLI = NULL; EState *estate = NULL; Portal portal; /* Look it up in the hash table */ entry = FetchPreparedStatement(stmt->name, true); query_string = entry->query_string; query_list = entry->query_list; plan_list = entry->plan_list; qcontext = entry->context; Assert(list_length(query_list) == list_length(plan_list)); /* Evaluate parameters, if any */ if (entry->argtype_list != NIL) { /* * Need an EState to evaluate parameters; must not delete it till end * of query, in case parameters are pass-by-reference. */ estate = CreateExecutorState(); estate->es_param_list_info = params; paramLI = EvaluateParams(estate, stmt->params, entry->argtype_list); } /* Create a new portal to run the query in */ portal = CreateNewPortal(); /* Don't display the portal in pg_cursors, it is for internal use only */ portal->visible = false; /* * For CREATE TABLE / AS EXECUTE, make a copy of the stored query so that * we can modify its destination (yech, but this has always been ugly). * For regular EXECUTE we can just use the stored query where it sits, * since the executor is read-only. */ if (stmt->into) { MemoryContext oldContext; Query *query; oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); if (query_string) query_string = pstrdup(query_string); query_list = copyObject(query_list); plan_list = copyObject(plan_list); qcontext = PortalGetHeapMemory(portal); if (list_length(query_list) != 1) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("prepared statement is not a SELECT"))); query = (Query *) linitial(query_list); if (query->commandType != CMD_SELECT) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("prepared statement is not a SELECT"))); query->into = copyObject(stmt->into); query->intoOptions = copyObject(stmt->intoOptions); query->intoOnCommit = stmt->into_on_commit; if (stmt->into_tbl_space) query->intoTableSpaceName = pstrdup(stmt->into_tbl_space); MemoryContextSwitchTo(oldContext); } PortalDefineQuery(portal, NULL, query_string, entry->commandTag, query_list, plan_list, qcontext); /* * Run the portal to completion. */ PortalStart(portal, paramLI, ActiveSnapshot); (void) PortalRun(portal, FETCH_ALL, dest, dest, completionTag); PortalDrop(portal, false); if (estate) FreeExecutorState(estate); /* No need to pfree other memory, MemoryContext will be reset */ }
/* * Implements the 'EXECUTE' utility statement. * * Note: this is one of very few places in the code that needs to deal with * two query strings at once. The passed-in queryString is that of the * EXECUTE, which we might need for error reporting while processing the * parameter expressions. The query_string that we copy from the plan * source is that of the original PREPARE. */ void ExecuteQuery(ExecuteStmt *stmt, const char *queryString, ParamListInfo params, DestReceiver *dest, char *completionTag) { PreparedStatement *entry; List *stmt_list; MemoryContext qcontext; ParamListInfo paramLI = NULL; EState *estate = NULL; Portal portal; /* Look it up in the hash table */ entry = FetchPreparedStatement(stmt->name, true); qcontext = entry->context; /* Evaluate parameters, if any */ if (entry->argtype_list != NIL) { /* * Need an EState to evaluate parameters; must not delete it till end * of query, in case parameters are pass-by-reference. */ estate = CreateExecutorState(); estate->es_param_list_info = params; paramLI = EvaluateParams(estate, stmt->params, entry->argtype_list); } /* Create a new portal to run the query in */ portal = CreateNewPortal(); /* Don't display the portal in pg_cursors, it is for internal use only */ portal->visible = false; /* Plan the query. If this is a CTAS, copy the "into" information into * the query so that we construct the plan correctly. Else the table * might not be created on the segments. (MPP-8135) */ { List *query_list = copyObject(entry->query_list); /* planner scribbles on query tree :( */ if ( stmt->into ) { Query *query = (Query*)linitial(query_list); Assert(IsA(query, Query) && query->intoClause == NULL); query->intoClause = copyObject(stmt->into); } stmt_list = pg_plan_queries(query_list, paramLI, false, QRL_ONCE); } /* * For CREATE TABLE / AS EXECUTE, make a copy of the stored query so that * we can modify its destination (yech, but this has always been ugly). * For regular EXECUTE we can just use the stored query where it sits, * since the executor is read-only. */ if (stmt->into) { MemoryContext oldContext; PlannedStmt *pstmt; if (list_length(stmt_list) != 1) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("prepared statement is not a SELECT"))); oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); stmt_list = copyObject(stmt_list); qcontext = PortalGetHeapMemory(portal); pstmt = (PlannedStmt *) linitial(stmt_list); pstmt->qdContext = qcontext; if (pstmt->commandType != CMD_SELECT) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("prepared statement is not a SELECT"), errOmitLocation(true))); pstmt->intoClause = copyObject(stmt->into); /* XXX Is it legitimate to assign a constant default policy without * even checking the relation? */ pstmt->intoPolicy = palloc0(sizeof(GpPolicy)- sizeof(pstmt->intoPolicy->attrs) + 255 * sizeof(pstmt->intoPolicy->attrs[0])); pstmt->intoPolicy->nattrs = 0; pstmt->intoPolicy->ptype = POLICYTYPE_PARTITIONED; pstmt->intoPolicy->bucketnum = GetRelOpt_bucket_num_fromRangeVar(stmt->into->rel, GetRandomDistPartitionNum()); MemoryContextSwitchTo(oldContext); } /* Copy the plan's saved query string into the portal's memory */ Assert(entry->query_string != NULL); char *query_string = MemoryContextStrdup(PortalGetHeapMemory(portal), entry->query_string); PortalDefineQuery(portal, NULL, query_string, entry->sourceTag, entry->commandTag, stmt_list, qcontext); create_filesystem_credentials(portal); /* * Run the portal to completion. */ PortalStart(portal, paramLI, ActiveSnapshot, savedSeqServerHost, savedSeqServerPort); (void) PortalRun(portal, FETCH_ALL, true, /* Effectively always top level. */ dest, dest, completionTag); PortalDrop(portal, false); if (estate) FreeExecutorState(estate); /* No need to pfree other memory, MemoryContext will be reset */ }