Gabriel39 commented on code in PR #68631:
URL: https://github.com/apache/doris/pull/68631#discussion_r4132315508


##########
fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java:
##########
@@ -907,15 +921,24 @@ public void resetLoginTime() {
         this.loginTime = System.currentTimeMillis();
     }
 
-    public void addPreparedQuery(String preparedStatementId, String 
preparedQuery) {
-        preparedQuerys.put(preparedStatementId, preparedQuery);
+    public synchronized void addPreparedQuery(String preparedStatementId, 
String preparedQuery) {
+        preparedQuerys.put(preparedStatementId, new 
PreparedQuery(preparedQuery, getDefaultCatalog(), getDatabase()));
     }
 
-    public String getPreparedQuery(String preparedStatementId) {
-        return preparedQuerys.get(preparedStatementId);
+    public synchronized String getPreparedQuery(String preparedStatementId) {
+        PreparedQuery query = preparedQuerys.get(preparedStatementId);
+        if (query == null) {
+            return null;
+        }
+        // A handle must not execute unqualified SQL in a different namespace 
than its advertised schema.
+        if (!Objects.equals(query.catalog, getDefaultCatalog()) || 
!Objects.equals(query.database, getDatabase())) {

Review Comment:
   Confirmed and fixed in 37f71c9306c. Each handle now retains the schema 
advertised at Prepare. GetSchema and GetFlightInfo reanalyze under the session 
lock and reject/remove the handle with NOT_FOUND if the schema differs. This 
also covers result-affecting settings beyond sql_mode; a query_timeout change 
that preserves the schema keeps the handle valid. Added tests for both entry 
points and real Flight RPC coverage of the PIPES_AS_CONCAT example.



##########
fe/fe-core/src/main/java/org/apache/doris/service/arrowflight/FlightSqlQuerySchema.java:
##########
@@ -0,0 +1,301 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.service.arrowflight;
+
+import org.apache.doris.analysis.StatementBase;
+import org.apache.doris.catalog.AggStateType;
+import org.apache.doris.catalog.ArrayType;
+import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.MapType;
+import org.apache.doris.catalog.PrimitiveType;
+import org.apache.doris.catalog.ScalarType;
+import org.apache.doris.catalog.StructField;
+import org.apache.doris.catalog.StructType;
+import org.apache.doris.catalog.Type;
+import org.apache.doris.datasource.CatalogIf;
+import org.apache.doris.datasource.es.EsExternalCatalog;
+import org.apache.doris.mysql.MysqlCommand;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.nereids.CascadesContext;
+import org.apache.doris.nereids.StatementContext;
+import org.apache.doris.nereids.glue.LogicalPlanAdapter;
+import org.apache.doris.nereids.parser.NereidsParser;
+import org.apache.doris.nereids.parser.SqlDialectHelper;
+import org.apache.doris.nereids.rules.rewrite.CheckPrivileges;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.PrepareCommandPlanner;
+import org.apache.doris.nereids.trees.plans.commands.Command;
+import org.apache.doris.nereids.trees.plans.commands.DescribeCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowCreateTableCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowDataCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowPartitionsCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowProcCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowPythonPackagesCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowQueryStatsCommand;
+import org.apache.doris.nereids.trees.plans.commands.ShowTableCommand;
+import org.apache.doris.nereids.trees.plans.commands.use.SwitchCommand;
+import org.apache.doris.nereids.trees.plans.commands.use.UseCommand;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.QueryState;
+import org.apache.doris.qe.ResultSetMetaData;
+import org.apache.doris.qe.SessionVariable;
+import org.apache.doris.qe.StmtExecutor;
+import org.apache.doris.qe.VariableMgr;
+
+import org.apache.arrow.flight.CallStatus;
+import org.apache.arrow.util.AutoCloseables;
+import org.apache.arrow.vector.types.pojo.ArrowType;
+import org.apache.arrow.vector.types.pojo.Field;
+import org.apache.arrow.vector.types.pojo.FieldType;
+import org.apache.arrow.vector.types.pojo.Schema;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Resolves result metadata without scheduling fragments or evaluating query 
expressions. */
+final class FlightSqlQuerySchema {
+    private FlightSqlQuerySchema() {
+    }
+
+    static Schema analyze(ConnectContext context, String query) throws 
Exception {
+        synchronized (context) {
+            ConnectContext previousThreadContext = ConnectContext.get();
+            StatementContext previousStatement = context.getStatementContext();
+            SessionVariable previousSession = context.getSessionVariable();
+            QueryState previousState = context.getState();
+            StmtExecutor previousExecutor = context.getExecutor();
+            String previousCatalog = context.getDefaultCatalog();
+            String previousDatabase = context.getDatabase();
+            List<StatementBase> statements = Collections.emptyList();
+            try {
+                context.setThreadLocalInfo();
+                context.setCommand(MysqlCommand.COM_QUERY);
+                // Parsing SET_VAR hints already mutates session variables. 
Isolate them even when parsing fails.
+                
context.setSessionVariable(VariableMgr.cloneSessionVariable(previousSession));
+                context.setState(new QueryState());
+                context.setExecutor(null);
+                context.setStatementContext(null);
+                // Match execution's HTTP/plugin conversion before the dialect 
parser sees the SQL.
+                String converted = SqlDialectHelper.convertSqlByDialect(query, 
context.getSessionVariable());
+                statements = new NereidsParser().parseSQL(converted, 
context.getSessionVariable());

Review Comment:
   Confirmed and fixed in 37f71c9306c. Schema discovery now retries the 
original SQL after a converted-text parse failure only when 
retry_origin_sql_on_convert_fail is enabled and the texts differ. The failed 
parser context is closed inside the existing isolated session scope. Added a 
test covering enabled/disabled fallback and session restoration.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowProcCommand.java:
##########
@@ -74,6 +74,15 @@ public ShowResultSetMetaData getMetaData() {
         return ShowResultSetMetaData.builder().build();
     }
 
+    /** Resolve a proc node's header with the same privilege checks as SHOW 
PROC. */
+    public ShowResultSetMetaData getMetaData(ConnectContext ctx) throws 
AnalysisException {
+        // PROC headers belong to the resolved node and require the same 
privilege as reading it.
+        if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ctx, 
PrivPredicate.ADMIN_OR_NODE)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"ADMIN");
+        }
+        return getMetaData(ProcService.getInstance().open(path));

Review Comment:
   Confirmed and fixed in 37f71c9306c. Schema discovery uses static headers for 
/ and /current_queries without calling ProcService.open or fetchResult. Other 
PROC paths return UNIMPLEMENTED before node traversal, which can itself perform 
remote work. The new test verifies no interactions with the proc service or 
node; the existing SHOW PROC execution path is unchanged.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to