diff --git a/Snowflake.Data/Client/SnowflakeDbAsynchronousQueryHelper.cs b/Snowflake.Data/Client/SnowflakeDbAsynchronousQueryHelper.cs index a44312b5c..0f9e4860d 100644 --- a/Snowflake.Data/Client/SnowflakeDbAsynchronousQueryHelper.cs +++ b/Snowflake.Data/Client/SnowflakeDbAsynchronousQueryHelper.cs @@ -55,18 +55,6 @@ public static SnowflakeQueryStatus GetQueryStatus(SnowflakeDbConnection conn, st return GetQueryStatusAsync(conn, queryId, CancellationToken.None).Result; } - /// - /// Use to determine which method to use to get query status. Use as a toggle for testing different features. - /// - private static StatusModes StatusMode = StatusModes.RestApi; - - private enum StatusModes - { - HistoryFunction, - HistoryView, - RestApi, - } - /// /// Use to get the status of a query to determine if you can fetch the result. /// @@ -77,63 +65,7 @@ private enum StatusModes public static async Task GetQueryStatusAsync(SnowflakeDbConnection conn, string queryId, CancellationToken cancellationToken) { - switch (StatusMode) - { - case StatusModes.HistoryFunction: - return await GetStatusUsingFunctionAsync(conn, queryId, cancellationToken).ConfigureAwait(false); - case StatusModes.HistoryView: - return await GetStatusUsingViewAsync(conn, queryId, cancellationToken).ConfigureAwait(false); - case StatusModes.RestApi: - return await GetStatusUsingRestApiAsync(conn, queryId, cancellationToken).ConfigureAwait(false); - default: - throw new Exception("Unexpected status mode"); - } - - } - - private static async Task GetStatusUsingFunctionAsync(SnowflakeDbConnection conn, string queryId, CancellationToken cancellationToken) - { - // this method has severe problems because of the query_history function. This function has a limit to the number - // of rows it returns, so there is no guarantee that it will return the desired query, if the system has had - // a high number of queries run. Also, this function is extremely slow. - - using (var cmd = conn.CreateCommand()) - { - - cmd.CommandType = System.Data.CommandType.Text; - - // https://docs.snowflake.com/en/sql-reference/functions/query_history.html - // RESULT_LIMIT defaults to 100, so need to set it to the max possible value - cmd.CommandText = "select top 1 EXECUTION_STATUS from table(information_schema.query_history(RESULT_LIMIT => 10000)) where query_id = ?;"; - - var p = (SnowflakeDbParameter)cmd.CreateParameter(); - p.ParameterName = "1"; - p.DbType = System.Data.DbType.String; - p.Value = queryId; - cmd.Parameters.Add(p); - - using (var r = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) - { - if (!r.Read()) - { - throw new Exception($"No status found for query '{queryId}'"); - } - var status = (string)r["EXECUTION_STATUS"]; - - if (status.StartsWith("success", StringComparison.OrdinalIgnoreCase)) - { - return new SnowflakeQueryStatus(queryId, true, true); - } - else if (status.StartsWith("failed", StringComparison.OrdinalIgnoreCase)) - { - return new SnowflakeQueryStatus(queryId, true, false); - } - else - { - return new SnowflakeQueryStatus(queryId, false, false); - } - } - } + return await GetStatusUsingRestApiAsync(conn, queryId, cancellationToken).ConfigureAwait(false); } private static async Task GetStatusUsingRestApiAsync(SnowflakeDbConnection conn, string queryId, CancellationToken cancellationToken) @@ -144,51 +76,6 @@ private static async Task GetStatusUsingRestApiAsync(Snowf return r; } - private static async Task GetStatusUsingViewAsync(SnowflakeDbConnection conn, string queryId, CancellationToken cancellationToken) - { - using (var cmd = conn.CreateCommand()) - { - - cmd.CommandType = System.Data.CommandType.Text; - - // https://docs.snowflake.com/en/sql-reference/account-usage/query_history.html - // Execution status for the query: success, fail, incident. - // Statement end time (in the UTC time zone), or NULL if the statement is still running. - cmd.CommandText = "select top 1 EXECUTION_STATUS, END_TIME from SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY where query_id = ?;"; - - var p = (SnowflakeDbParameter)cmd.CreateParameter(); - p.ParameterName = "1"; - p.DbType = System.Data.DbType.String; - p.Value = queryId; - cmd.Parameters.Add(p); - - using (var r = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) - { - if (!r.Read()) - { - // because QUERY_HISTORY view has such a long lag, a missing record might just mean that - // the query has not shown up yet in the view, so return status assuming that is the case. - // if can find something more real time, should throw an exception when no record found. - return new SnowflakeQueryStatus(queryId, false, false); - // throw new Exception($"No status found for query '{queryId}'"); - } - var status = (string)r["EXECUTION_STATUS"]; - var endTime = r["END_TIME"]; - bool isDone = true; - if ((endTime == null) || (endTime == DBNull.Value)) - { - isDone = false; - } - bool isSuccess = false; - if (isDone) - { - isSuccess = string.Equals("success", status, StringComparison.OrdinalIgnoreCase); - } - return new SnowflakeQueryStatus(queryId, isDone, isSuccess); - } - } - } - /// /// Can use the resulting to fetch the results of the query. /// @@ -197,16 +84,7 @@ private static async Task GetStatusUsingViewAsync(Snowflak /// public static SnowflakeDbCommand CreateQueryResultsCommand(SnowflakeDbConnection conn, string queryId) { - var useLegacyRestApi = true; - if (useLegacyRestApi) - { - return CreateQueryResultsCommandForRestApi(conn, queryId); - } - else - { - return CreateQueryResultsCommandForResultScan(conn, queryId); - } - + return CreateQueryResultsCommandForRestApi(conn, queryId); } private static SnowflakeDbCommand CreateQueryResultsCommandForRestApi(SnowflakeDbConnection conn, string queryId) @@ -216,33 +94,5 @@ private static SnowflakeDbCommand CreateQueryResultsCommandForRestApi(SnowflakeD cmd.CommandText = queryId; return cmd; } - - private static SnowflakeDbCommand CreateQueryResultsCommandForResultScan(SnowflakeDbConnection conn, string queryId) - { - var cmd = conn.CreateCommand(); - - cmd.CommandType = System.Data.CommandType.Text; - - // todo: HELP! For some reason I get this exception when I try to pass the queryId in using a parameter, - // but it works fine when I pass the queryId in as part of the query text - // SQL compilation error: argument needs to be a string: '1' - // https://stackoverflow.com/questions/68289534/using-java-and-snowflake-how-do-you-query-using-the-queryid-in-a-prepared-state - - if (!Guid.TryParse(queryId, out var parsedQueryId)) - { - // since cannot use parameter, need to make sure queryId is a valid guid to avoid sql injection - throw new Exception($"Invalid queryId provided. '{queryId}'"); - } - cmd.CommandText = $"select * from table(result_scan('{parsedQueryId.ToString()}'));"; - //cmd.CommandText = "select * from table(result_scan(?));"; - - //var p = (SnowflakeDbParameter)cmd.CreateParameter(); - //p.ParameterName = "1"; - //p.DbType = System.Data.DbType.String; - //p.Value = queryId; - //cmd.Parameters.Add(p); - - return (SnowflakeDbCommand)cmd; - } } }