@@ -2281,14 +2281,23 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj,
22812281 {
22822282 return false ;
22832283 }
2284-
2285- // give the parser the new collation values in case parameters don't specify one
2284+
2285+ // Give the parser the new collation values in case parameters don't specify one
22862286 _defaultCollation = env . newCollation ;
2287- int newCodePage = GetCodePage ( env . newCollation , stateObj ) ;
2288- if ( newCodePage != _defaultCodePage )
2287+
2288+ // UTF8 collation
2289+ if ( ( env . newCollation . info & TdsEnums . UTF8_IN_TDSCOLLATION ) == TdsEnums . UTF8_IN_TDSCOLLATION )
22892290 {
2290- _defaultCodePage = newCodePage ;
2291- _defaultEncoding = System . Text . Encoding . GetEncoding ( _defaultCodePage ) ;
2291+ _defaultEncoding = Encoding . UTF8 ;
2292+ }
2293+ else
2294+ {
2295+ int newCodePage = GetCodePage ( env . newCollation , stateObj ) ;
2296+ if ( newCodePage != _defaultCodePage )
2297+ {
2298+ _defaultCodePage = newCodePage ;
2299+ _defaultEncoding = System . Text . Encoding . GetEncoding ( _defaultCodePage ) ;
2300+ }
22922301 }
22932302 _defaultLCID = env . newCollation . LCID ;
22942303 }
@@ -3245,18 +3254,26 @@ internal bool TryProcessReturnValue(int length, TdsParserStateObject stateObj, o
32453254 return false ;
32463255 }
32473256
3248- int codePage = GetCodePage ( rec . collation , stateObj ) ;
3249-
3250- // if the column lcid is the same as the default, use the default encoder
3251- if ( codePage == _defaultCodePage )
3257+ // UTF8 collation
3258+ if ( ( rec . collation . info & TdsEnums . UTF8_IN_TDSCOLLATION ) == TdsEnums . UTF8_IN_TDSCOLLATION )
32523259 {
3253- rec . codePage = _defaultCodePage ;
3254- rec . encoding = _defaultEncoding ;
3260+ rec . encoding = Encoding . UTF8 ;
32553261 }
32563262 else
32573263 {
3258- rec . codePage = codePage ;
3259- rec . encoding = System . Text . Encoding . GetEncoding ( rec . codePage ) ;
3264+ int codePage = GetCodePage ( rec . collation , stateObj ) ;
3265+
3266+ // If the column lcid is the same as the default, use the default encoder
3267+ if ( codePage == _defaultCodePage )
3268+ {
3269+ rec . codePage = _defaultCodePage ;
3270+ rec . encoding = _defaultEncoding ;
3271+ }
3272+ else
3273+ {
3274+ rec . codePage = codePage ;
3275+ rec . encoding = System . Text . Encoding . GetEncoding ( rec . codePage ) ;
3276+ }
32603277 }
32613278 }
32623279
@@ -3755,17 +3772,25 @@ private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaDat
37553772 return false ;
37563773 }
37573774
3758- int codePage = GetCodePage ( col . collation , stateObj ) ;
3759-
3760- if ( codePage == _defaultCodePage )
3775+ // UTF8 collation
3776+ if ( ( col . collation . info & TdsEnums . UTF8_IN_TDSCOLLATION ) == TdsEnums . UTF8_IN_TDSCOLLATION )
37613777 {
3762- col . codePage = _defaultCodePage ;
3763- col . encoding = _defaultEncoding ;
3778+ col . encoding = Encoding . UTF8 ;
37643779 }
37653780 else
37663781 {
3767- col . codePage = codePage ;
3768- col . encoding = System . Text . Encoding . GetEncoding ( col . codePage ) ;
3782+ int codePage = GetCodePage ( col . collation , stateObj ) ;
3783+
3784+ if ( codePage == _defaultCodePage )
3785+ {
3786+ col . codePage = _defaultCodePage ;
3787+ col . encoding = _defaultEncoding ;
3788+ }
3789+ else
3790+ {
3791+ col . codePage = codePage ;
3792+ col . encoding = System . Text . Encoding . GetEncoding ( col . codePage ) ;
3793+ }
37693794 }
37703795 }
37713796
@@ -6067,6 +6092,19 @@ internal int WriteFedAuthFeatureRequest(FederatedAuthenticationFeatureExtensionD
60676092
60686093 return len ;
60696094 }
6095+ internal int WriteUTF8SupportFeatureRequest ( bool write /* if false just calculates the length */ )
6096+ {
6097+ int len = 5 ; // 1byte = featureID, 4bytes = featureData length, sizeof(DWORD)
6098+
6099+ if ( write )
6100+ {
6101+ // Write Feature ID
6102+ _physicalStateObj . WriteByte ( TdsEnums . FEATUREEXT_UTF8SUPPORT ) ;
6103+ WriteInt ( 0 , _physicalStateObj ) ; // we don't send any data
6104+ }
6105+
6106+ return len ;
6107+ }
60706108
60716109 internal void TdsLogin ( SqlLogin rec , TdsEnums . FeatureExtension requestedFeatures , SessionData recoverySessionData , FederatedAuthenticationFeatureExtensionData ? fedAuthFeatureExtensionData )
60726110 {
@@ -6201,15 +6239,20 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures
62016239 {
62026240 length += WriteSessionRecoveryFeatureRequest ( recoverySessionData , false ) ;
62036241 }
6242+ if ( ( requestedFeatures & TdsEnums . FeatureExtension . FedAuth ) != 0 )
6243+ {
6244+ Debug . Assert ( fedAuthFeatureExtensionData != null , "fedAuthFeatureExtensionData should not null." ) ;
6245+ length += WriteFedAuthFeatureRequest ( fedAuthFeatureExtensionData . Value , write : false ) ;
6246+ }
62046247 if ( ( requestedFeatures & TdsEnums . FeatureExtension . GlobalTransactions ) != 0 )
62056248 {
62066249 length += WriteGlobalTransactionsFeatureRequest ( false ) ;
62076250 }
6208- if ( ( requestedFeatures & TdsEnums . FeatureExtension . FedAuth ) != 0 )
6251+ if ( ( requestedFeatures & TdsEnums . FeatureExtension . UTF8Support ) != 0 )
62096252 {
6210- Debug . Assert ( fedAuthFeatureExtensionData != null , "fedAuthFeatureExtensionData should not null." ) ;
6211- length += WriteFedAuthFeatureRequest ( fedAuthFeatureExtensionData . Value , write : false ) ;
6253+ length += WriteUTF8SupportFeatureRequest ( false ) ;
62126254 }
6255+
62136256 length ++ ; // for terminator
62146257 }
62156258
@@ -6443,15 +6486,20 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures
64436486 {
64446487 length += WriteSessionRecoveryFeatureRequest ( recoverySessionData , true ) ;
64456488 }
6489+ if ( ( requestedFeatures & TdsEnums . FeatureExtension . FedAuth ) != 0 )
6490+ {
6491+ Debug . Assert ( fedAuthFeatureExtensionData != null , "fedAuthFeatureExtensionData should not null." ) ;
6492+ WriteFedAuthFeatureRequest ( fedAuthFeatureExtensionData . Value , write : true ) ;
6493+ }
64466494 if ( ( requestedFeatures & TdsEnums . FeatureExtension . GlobalTransactions ) != 0 )
64476495 {
64486496 WriteGlobalTransactionsFeatureRequest ( true ) ;
64496497 }
6450- if ( ( requestedFeatures & TdsEnums . FeatureExtension . FedAuth ) != 0 )
6498+ if ( ( requestedFeatures & TdsEnums . FeatureExtension . UTF8Support ) != 0 )
64516499 {
6452- Debug . Assert ( fedAuthFeatureExtensionData != null , "fedAuthFeatureExtensionData should not null." ) ;
6453- WriteFedAuthFeatureRequest ( fedAuthFeatureExtensionData . Value , write : true ) ;
6454- } ;
6500+ WriteUTF8SupportFeatureRequest ( true ) ;
6501+ }
6502+
64556503 _physicalStateObj . WriteByte ( 0xFF ) ; // terminator
64566504 }
64576505 }
@@ -8127,6 +8175,12 @@ internal Task WriteBulkCopyValue(object value, SqlMetaDataPriv metadata, TdsPars
81278175 }
81288176 if ( metadata . collation != null )
81298177 {
8178+ // Replace encoding if it is UTF8
8179+ if ( ( metadata . collation . info & TdsEnums . UTF8_IN_TDSCOLLATION ) == TdsEnums . UTF8_IN_TDSCOLLATION )
8180+ {
8181+ _defaultEncoding = Encoding . UTF8 ;
8182+ }
8183+
81308184 _defaultCollation = metadata . collation ;
81318185 _defaultLCID = _defaultCollation . LCID ;
81328186 }
0 commit comments