Skip to content

Add TempTableDefinitions and TableVarMapping #278

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

Closed
wants to merge 18 commits into from

Conversation

davidtme
Copy link

@davidtme davidtme commented Nov 16, 2017

See #277 and #263 (comment)

This allows you to add temp tables via the TempTableDefinitions parameter and table var types via the TableVarMapping parameter

@davidtme davidtme changed the title [WIP] Add TempTableDefinitions and TableVarMapping Add TempTableDefinitions and TableVarMapping Nov 16, 2017
@smoothdeveloper
Copy link
Collaborator

The features of this PR are interesting, I'd like to see those two changes:

  • trim the changes not related to the PR (project files, fsharp.core, config file changes)
  • add comments describing the implementation details
  • possibly, add few unit tests to cover the string parsing logic of the implementation details, will help if we encounter bugs / corner cases in the future

Does the TVP type generated for the command unifies with the ones exposed in SqlProgrammabilityProvider's user defined types?

@vasily-kirichenko
Copy link
Contributor

@davidtme I agree with @smoothdeveloper, could you please remove all unrelated changes, after which we could merge it? Thanks!

@@ -104,13 +109,19 @@ type SqlCommandProvider(config : TypeProviderConfig) as this =
conn.CheckVersion()
conn.LoadDataTypesMap()

let parameters = DesignTime.ExtractParameters(conn, sqlStatement, allParametersOptional)
let designTimeSqlStatement, tempTableNames =
let sql, tempTableNames = DesignTime.SubstituteTempTables(conn, sqlStatement, tempTableDefinitions)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidtme we need a conditional to not go in that codepath if tempTableDefinitions is null or empty, because without that conditional, we are at risk of not having a workaround if SubstituteTempTables alters the statement in unexpected ways (SQL statements can have # in them, you can have that frequently in strings and dynamical statement).

I'd like the new codepaths to only be active when the parameter is actually defined by the user.

@smoothdeveloper smoothdeveloper mentioned this pull request May 12, 2018
@davidtme
Copy link
Author

I'll let #291 get in first then I'll go about making the changes suggested.

@vasily-kirichenko
Copy link
Contributor

@davidtme OK. However, I'm stuck with #291, so no ETA.

@vasily-kirichenko
Copy link
Contributor

@davidtme I'm not sure I'll finish the netstandard branch anytime soon (if ever), I think we should merge this PR. So, let's make the requested changes and we'll merge it.

@davidtme
Copy link
Author

@smoothdeveloper The type(s) create to load data in to the temp tables live inside the command so are access like:

use cmd = new TempTable(conn)
cmd.LoadTempTables([ TempTable.Temp(Id = 1, Name = Some "monkey") ])

As for TVP, no types are create by my code just the design time sql is changed:

SELECT myId, myName from @input

Becomes something like (off the top of my head):

DECLARE @SQLCOMMANDPROVIDER_input dbo.MyTableType = @input
SELECT myId, myName from @SQLCOMMANDPROVIDER_input

@davidtme
Copy link
Author

I'm not sure how get travis-ci to build the project, maybe it's a mono/old f# core thing as it complaining about

The module/namespace 'System.Collections.Generic' from compilation unit 'mscorlib' did not contain the namespace, module or type 'IReadOnlyCollection`1'

but it builds on windows:

FSharp.Data.TVPTests.UsingTVPInQuery [SKIP]
   Fails at runtime :(

FSharp.Data.TVPTests.InputIsEnumeratedExactlyOnce [SKIP]
   Flucky

FSharp.Data.TypeProviderTest.ConcurrentReaders [SKIP]
   Thread safe execution is not supported yet

FSharp.Data.TypeProviderTest.CommandTimeout [SKIP]
   Don't execute for usual runs. Too slow.

144 total, 0 failed, 4 skipped, took 3.531 seconds
Finished Target: RunTests
Starting Target: All (==> RunTests)
Finished Target: All

---------------------------------------------------------------------
Build Time Report
---------------------------------------------------------------------
Target            Duration
------            --------
Clean             00:00:00.0390081
RestorePackages   00:00:03.1203044
AssemblyInfo      00:00:00.0088544
Build             00:00:12.4519448
DeployTestDB      00:00:00.2427771
BuildTests        00:00:09.0156047
RunTests          00:00:04.2975552
All               00:00:00.0000459
Total:            00:00:29.2397542
Status:           Ok
---------------------------------------------------------------------

@vasily-kirichenko
Copy link
Contributor

I'm not sure how get travis-ci to build the project

Pin FAKE to version ~> 4.

@vasily-kirichenko
Copy link
Contributor

OK, it does not help. The good news, I remembered the right way: reference FSharp.Core via NuGet. The version should be 4.0.0.1 I believe.

@smoothdeveloper what version should we reference?

@vasily-kirichenko
Copy link
Contributor

vasily-kirichenko commented May 18, 2018

@davidtme But we must test it in VS 2015 after such change.

@davidtme
Copy link
Author

@vasily-kirichenko I did originally have 4.0.0.1 in there (a85d2b8) but I removed it as part of the "clean up" and was hoped merging from master would sort it out... never mind it's a fine line between fixing to much and creating clutter in a PR so it's all good. Sadly (not really) I no longer have VS2015 so I can't test that part.

@davidtme
Copy link
Author

davidtme commented May 18, 2018

I've moved the build on a but

2) FS0039: /home/travis/build/fsprojects/FSharp.Data.SqlClient/src/SqlClient/ISqlCommand.fs(190,179): The type 'SqlDataRecord' is not defined in 'Microsoft.SqlServer.Server'.

Looks like this was in issue in the past #49 so maybe pinning to 4.0.0.1 has resurrected this some how?

@vasily-kirichenko
Copy link
Contributor

@davidtme I've built it from master branch and looked at FSharp.Core.dll in bin folder:

image

Try 4.1.18

@vasily-kirichenko
Copy link
Contributor

No, it does not work. It seems the only way to make it compilable on Mac is upgrading to .net 4.5. Do we want to do it right now?

I think it's ok to have green build on windows for now.

@vasily-kirichenko
Copy link
Contributor

I've built nuget package and testing in VS 2017:

image

@vasily-kirichenko
Copy link
Contributor

OK, I have the same error with package built from master as well o_O

let designTimeSqlStatement, tempTableTypes =
let sql, types = DesignTime.SubstituteTempTables(conn, sqlStatement, tempTableDefinitions)
DesignTime.SubstituteTableVar(sql, tableVarMapping), types
let connectionId = Guid.NewGuid().ToString().Substring(0, 8)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have explanation on why we need this? it seems to be used for the provided type name of the table, maybe better to pick something deterministic, or to remove it from here and internal only to the place it is used.

What would be the problem to just use the whole connection string instead?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe the GetHashCode on the connection string, this way we can probably avoid passing a parameter and keep it as implementation detail of the substitution code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases parallel msbuild or msbuild and visual studio can both be building the type provider at the same time so you end up with both trying to create, use and drop the same temp table which creates build errors. Adding a Guid in there stops them from fighting.

@davidtme
Copy link
Author

Build is green :D I'm sure there is a cleaner way but could be a quick work around.

Copy link
Collaborator

@smoothdeveloper smoothdeveloper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding nice tests, and the conditional to avoid the new code path if the extra parameters aren't given.

Some more extra changes should be removed before this go in, the only non related change we should keep:

  • fix for mono reflection when dealing with TVP
  • fix to build.sh

@@ -40,7 +41,52 @@ module internal SharedLogic =
// add .Table
returnType.Single |> cmdProvidedType.AddMember

type DesignTime private() =
module Prefixes =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to keep new members in this file internal.

type TempTableLoader(fieldCount, items: obj seq) =
let enumerator = items.GetEnumerator()

interface IDataReader with
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a small note about why we have to implement our own datareader and why those few members are enough?

@@ -51,8 +51,8 @@
<OtherFlags>--warnon:1182</OtherFlags>
</PropertyGroup>
<ItemGroup>
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
<Reference Include="FSharp.Core">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now we should revert changes to project files, you can keep them local and eventually we will make the solution work better outside of VS2015, but it is easier to know we don't break things without those changes.

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FSharp.Core" version="4.0.0.1" targetFramework="net40" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, let's put that aside for now, you can keep it in your local repository.

@@ -7,7 +7,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.3.1.0" />
<bindingRedirect oldVersion="0.0.0.0-4.4.0.0" newVersion="4.4.0.0" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't touch this for now.

@smoothdeveloper
Copy link
Collaborator

@davidtme I think some of your changes for Mono are good but require more testing to verify we don't break existing runtime environments.

I'm working on changes to bring up paket in master, I hope to submit a working PR this weekend, this should make dealing with fsharp.core and binding redirects easier.

@vasily-kirichenko
Copy link
Contributor

Closed-reopen it to kick AppVeyor.

@vasily-kirichenko
Copy link
Contributor

I've merged master into your branch and opened new PR #302

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

Successfully merging this pull request may close these issues.

4 participants