Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostgresException is throw when executing query with Thai culture #1508

Closed
ultimaweapon opened this issue Sep 19, 2020 · 7 comments
Closed

Comments

@ultimaweapon
Copy link

After some investigation, found out it is caused when trying to select some data when CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture is th-TH. I did not try with other cultures. If current culture is CultureInfo.InvariantCulture it will select success without error. Here is the line that caused this error: https://github.com/dotnet/aspnetcore/blob/master/src/Identity/EntityFrameworkCore/src/UserStore.cs#L239

I also already tried to select with SingleOrDefaultAsync but no luck. Here is my current workaround:

public override async Task<ApplicationUser> FindByIdAsync(
    string userId,
    CancellationToken cancellationToken = default)
{
    var culture = CultureInfo.CurrentCulture;
    var ui = CultureInfo.CurrentUICulture;

    CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
    CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture;

    try
    {
        return await base.FindByIdAsync(userId, cancellationToken);
    }
    finally
    {
        CultureInfo.CurrentCulture = culture;
        CultureInfo.CurrentUICulture = culture;
    }
}

Here is the full stack trace:

Npgsql.PostgresException (0x80004005): 42703: column "__p_0" does not exist
   at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming)
   at Npgsql.NpgsqlCommand.ExecuteReaderAsync(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Ultima.IdentityProvider.Controllers.ProfileController.IndexAsync(CancellationToken cancellationToken) in SOURCE_PATH
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
  Exception data:
    Severity: ERROR
    SqlState: 42703
    MessageText: column "__p_0" does not exist
    Position: 327
    File: parse_relation.c
    Line: 3359
    Routine: errorMissingColumn

This occurred on Npgsql.EntityFrameworkCore.PostgreSQL with version 3.1.4 on Linux.

@roji
Copy link
Member

roji commented Sep 19, 2020

@ultimaweapon I'm having trouble reproducing this, see my attempt here: https://github.com/roji/Test/tree/ThaiCulture. Can you please post a repro for this, or tweak my sample project so that it fails?

@ultimaweapon
Copy link
Author

@roji I will invite you to my private project. It just a personal project but if you are uncomfortable just don't accept the invitation and let me know so I will try to reproduce it with your repository. Before launching the project you need to replace src/Ultima.IdentityProvider/Controllers/HomeController.cs with the following content:

namespace Ultima.IdentityProvider.Controllers
{
    using System.Diagnostics;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Ultima.IdentityProvider.Models;

    [Route("")]
    public sealed class HomeController : Controller
    {
        private readonly UserManager<ApplicationUser> userManager;

        public HomeController(UserManager<ApplicationUser> userManager)
        {
            this.userManager = userManager;
        }

        [HttpGet]
        public async Task<IActionResult> Index()
        {
            await this.userManager.GetUserAsync(this.User);

            return this.View();
        }

        [Route("error")]
        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return this.View(new Error { RequestId = Activity.Current?.Id ?? this.HttpContext.TraceIdentifier });
        }
    }
}

Here are the steps to reproduce:

  1. Sign up a new identity then sign in with it.
  2. Restart the server.
  3. Launch http://localhost:5000/?culture=th-TH.

You need to launch this URL as a first request; otherwise, it will not trigger the bug. Once it triggered it will always error regardless of the request culture until you restart the server and issue the first request without culture=th-TH.

@ultimaweapon
Copy link
Author

@roji I was tried to change your project to netcoreapp3.1 and it needs some efforts to make it build success so I created a new one: https://github.com/ultimaweapon/npgsql-test

I already set up everything with th-TH as default and only available cultures so what you need to do is just spinup an instance of PostgreSQL and run migrations. Then try to sign up a new account. It should error immediately after submit the sign up form.

@roji
Copy link
Member

roji commented Oct 17, 2020

Duplicate of dotnet/efcore#18831

@roji roji marked this as a duplicate of dotnet/efcore#18831 Oct 17, 2020
@roji
Copy link
Member

roji commented Oct 17, 2020

@ultimaweapon thanks for the repro, it helped me track this down.

This issue has already been resolved for 5.0, but 3.1 still has it. Please see #18831 for how to work around it, we'll discuss again with the team about patching this.

@roji roji closed this as completed Oct 17, 2020
@roji
Copy link
Member

roji commented Oct 17, 2020

Another option - even more recommended - is to switch to 5.0.0-rc2, which is go-live ready and very stable. That version does not contain the bug.

@ultimaweapon
Copy link
Author

Okay. Thank you for information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants