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

Cannot insert into or update timestamp(tz) column due to mismatching type #344

Closed
vaindil opened this issue Mar 17, 2018 · 17 comments
Closed

Comments

@vaindil
Copy link

vaindil commented Mar 17, 2018

I'm on 2.1.0-preview1. I'm unable to insert into any table I have that uses timestamp or timestamptz (I tested with both). My .NET type is DateTimeOffset. The relevant part of the log file is below. I don't know how to log any more than what's here, I can't seem to get the actual parameters that are being passed no matter what I try. I can provide any other info that's needed, I'm not sure what you'll need. The problem occurs on both nullable and non-nullable columns.

LOG:  statement: BEGIN
LOG:  statement: SET TRANSACTION ISOLATION LEVEL READ COMMITTED
ERROR:  column "first_offline_at" is of type timestamp with time zone but expression is of type text at character 246
HINT:  You will need to rewrite or cast the expression.
STATEMENT:  INSERT INTO "twitch_live_stream" ("twitch_user_id", "first_offline_at", "game_id", "game_name", "profile_image_url", "started_at", "thumbnail_url", "title", "twitch_display_name", "twitch_login", "twitch_stream_id", "viewer_count")
    VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
LOG:  statement: ROLLBACK
LOG:  statement: DISCARD ALL
@vaindil vaindil changed the title Cannot insert into or update tables with timestamp(tz) column due to mismatching type Cannot insert into or update nullable timestamp(tz) column due to mismatching type Mar 17, 2018
@vaindil vaindil changed the title Cannot insert into or update nullable timestamp(tz) column due to mismatching type Cannot insert into or update timestamp(tz) column due to mismatching type Mar 17, 2018
@vaindil
Copy link
Author

vaindil commented Mar 17, 2018

Sorry for the mess of editing above. Downgrading to 2.0.1 fixed the problem for me.

@jholovacs
Copy link

jholovacs commented Mar 19, 2018

I believe this is also related to my problem: it looks like when using the EF identity implementation with npgsql, there's also confusion on the DateTime parsing. Getting messages like:

42804: column "lockout_end" is of type timestamp with time zone but expression is of type text

For DateTime data types, the proper conversion should be timestamp without time zone. For DateTimeOffset data types the proper conversion should be timestamp with time zone.

@jholovacs
Copy link

Any motion on this? This is blocking me at this point.

@jholovacs
Copy link

Looks like it's related to #358

@roji
Copy link
Member

roji commented Apr 8, 2018

@jholovacs can you please post some code so I can see your issue?

It's probably not related to #358, which is about TimeSpan (which maps to PostgreSQL interval), not DateTimeOffset (which maps to PostgreSQL timestamp with time zone).

@jholovacs
Copy link

jholovacs commented Apr 8, 2018 via email

@jholovacs
Copy link

jholovacs commented Apr 8, 2018

Perhaps related to #303?

After looking at the debug log, I was able to get the following info out:

Failed executing DbCommand (17ms) [Parameters=[p0='?' (Size = 3000), p1='?', p2='?', p3='?', p4='?' (Size = 256), p5='?', p6='?' (Size = 35), p7='?' (Size = 150), p8='?' (Size = 150), p9='?' (Size = 150), p10='?', p11='?', p12='?', p13='?' (Size = 35), p14='?', p15='?' (Size = 48), p16='?' (Size = 256), p17='?' (Size = 256), p18='?', p19='?', p20='?', p21='?', p22='?', p23='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
      INSERT INTO "asp_net_users" ("about", "access_failed_count", "concurrency_stamp", "created_utc_timestamp", "email", "email_confirmed", "first_name", "image_url_large", "image_url_medium", "image_url_small", "is_site_admin", "last_modified_by", "last_modified_utc_timestamp", "last_name", "lockout_enabled", "lockout_end", "normalized_email", "normalized_user_name", "password_hash", "phone_number", "phone_number_confirmed", "security_stamp", "two_factor_enabled", "user_name")
      VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23)
      RETURNING "id";

@roji
Copy link
Member

roji commented Apr 8, 2018

@jholovacs I need a minimal code sample in order to investigate, even if it's just a minimal identity services sample. Just a bit of code that triggers the problem.

@jholovacs
Copy link

OK, I think I figured out what the problem is: lockout_end is a nullable DateTimeOffset, and that does not seem to be supported.

What I did to get around this is I changed the model builder for the property like so:

			builder.Entity<MyUser>()
				.Property(e => e.LockoutEnd)
				.HasColumnType("VARCHAR")
				.HasMaxLength(50)
				.IsRequired(false)
				.HasConversion(v => v == null ? null : v.Value.UtcDateTime.ToString("o"),
					c => c == null
						? null as DateTimeOffset?
						: new DateTimeOffset(DateTime.Parse(c, null, DateTimeStyles.RoundtripKind), TimeSpan.Zero));

I don't think this is an ideal solution, but apparently when a nullable DateTimeOffset is inserted into the database, it's sent as a null string, which causes all sorts of conversion issues. By making the column a VARCHAR, and performing an explicit conversion back and forth, the system is able to handle it.

@roji
Copy link
Member

roji commented Apr 8, 2018

@jholovacs, i'm still waiting for a minimal code sample... If the issue is with nullable Datetime offset, can you please write that up and post? It should be working.

@jholovacs
Copy link

jholovacs commented Apr 8, 2018

@roji As mentioned previously, I don't have a code sample. This is boilerplate stuff, built into EF Identity framework. There's no code I wrote to demonstrate this, beyond the standard UserManager<TUser>.CreateAsync(TUser user) and UserManager<TUser>.AddPasswordAsync(TUser user, string password).

I will add that this was working fine until recently, and then it stopped working.

@roji
Copy link
Member

roji commented Jun 10, 2018

Is this still not working with 2.1.0 RTM? If not, any chance I can get you to submit a code sample without ASP.NET, Identity or anything else (just a small console app)? My time is very limited and any help would be appreciated.

@jholovacs
Copy link

jholovacs commented Jun 10, 2018 via email

@roji
Copy link
Member

roji commented Jun 10, 2018

I'm sorry to hear it (although I'm not aware of any such breaking changes in the EF Core provider - unlike at the ADO level where there indeed are quite a few breaking changes).

The provider has several tests where DateTimeOffset is written and read, and to make extra sure I've just successfully roundtripped some DateTimeOffsets in a test program. My guess is that there's something going on in the application or in the Identity code itself which is triggering your issue, but I need to be able to see the error via a test project or code sample.

Another thought is that there were some date/time mapping changes in Npgsql 4.0.0 which could also have affected 2.1.0 - there's a chance this will just work now.

I'm going to close this for now as I don't have anything to work on, but I'm interested in fixing this if it's a bug in Npgsql and will reopen as soon as more info is provided.

@roji roji closed this as completed Jun 10, 2018
@sarath22
Copy link

sarath22 commented Sep 6, 2018

Hi,

I'm also getting the same issue:

My table:

CREATE TABLE public."TestingDetails"
(
"TestID" integer NOT NULL,
"TestName" text,
"TesterName" text,
"TotalCount" integer,
"SuccessCount" integer,
"FailureCount" integer,
"EndDate" timestamp without time zone,
"StartDate" timestamp without time zone,
CONSTRAINT "TestingDetails_pkey" PRIMARY KEY ("TestID"),
CONSTRAINT "TestingDetails_TestID_key" UNIQUE ("TestID")
)
WITH (
OIDS=FALSE
);
ALTER TABLE public."TestingDetails"
OWNER TO postgres;

Code:

string connstring = "Server=localhost;Port=5432;Database=test;User Id=postgres;Password=sync1694";
// Making connection with Npgsql provider
NpgsqlConnection conn = new NpgsqlConnection(connstring);
conn.Open();
if (conn.State == System.Data.ConnectionState.Open)
{
string sql = "SELECT * FROM public."TestingDetails" ";
// data adapter making request from our connection
NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
ds.Reset();
// filling DataSet with result from NpgsqlDataAdapter
da.Fill(ds);
// since it C# DataSet can handle multiple tables, we will select first
int _TestID=0;
string _TestName = "test";
string _TesterName = "demo";
DateTime _EndDate = DateTime.Now;
DateTime _StartDate = DateTime.Now;
int _TotalCount = 10;
int _SuccessCount = 5;
int _FailureCount = 5;
if (ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
_TestID = dt.Rows.Count + 1;
}
//new NpgsqlDateTime()
//dt.
//NpgsqlCommand command = new NpgsqlCommand("insert into public."TestingDetails" (TestID, TestName, TesterName, TotalCount, SuccessCount, FailureCount) values(" + _TestID + ",'" + _TestName + "','" + _TesterName + "'," +_TotalCount + "," + _SuccessCount + "," + _FailureCount + ")", conn);
NpgsqlCommand command = new NpgsqlCommand("insert into public."TestingDetails" values(:_TestID , :_TestName , :_TesterName , :_TotalCount , :_SuccessCount, :_FailureCount, :_StartDate)", conn);
command.Parameters.Add(new NpgsqlParameter("_TestID", _TestID));
command.Parameters.Add(new NpgsqlParameter("_TestName", _TestName));
command.Parameters.Add(new NpgsqlParameter("_TesterName", _TesterName));
command.Parameters.Add(new NpgsqlParameter("_StartDate", _StartDate));
command.Parameters.Add(new NpgsqlParameter("_TotalCount", _TotalCount));
command.Parameters.Add(new NpgsqlParameter("_SuccessCount", _SuccessCount));
command.Parameters.Add(new NpgsqlParameter("_FailureCount", _FailureCount));
command.Parameters.Add(new NpgsqlParameter("_EndDate", _EndDate));
command.ExecuteNonQuery();
}

@roji
Copy link
Member

roji commented Sep 6, 2018

@sarath22 you're describing a different issue. This repo is for Entity Framework Core, while you're just using the ADO.NET provider. Please open a new issue in http://github.com/npgsql/npgsql with the exact exception message and stack trace.

@sarath22
Copy link

sarath22 commented Sep 6, 2018

#630 - please look

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

4 participants