private static ISqlFragment WriteInstanceFunctionCall( SqlGenerator sqlgen, string functionName, DbFunctionExpression functionExpression, bool isPropertyAccess, string castReturnTypeTo) { Debug.Assert( !isPropertyAccess || functionExpression.Arguments.Count == 1, "Property accessor instance functions should have only the single instance argument"); return WrapWithCast( castReturnTypeTo, result => { var instanceExpression = functionExpression.Arguments[0]; // Write the instance - if this is another function call, it need not be enclosed in parentheses. if (instanceExpression.ExpressionKind != DbExpressionKind.Function) { sqlgen.ParenthesizeExpressionIfNeeded(instanceExpression, result); } else { result.Append(instanceExpression.Accept(sqlgen)); } result.Append("."); result.Append(functionName); if (!isPropertyAccess) { WriteFunctionArguments(sqlgen, functionExpression.Arguments.Skip(1), result); } }); }
/// <summary> /// Helper for all date and time types creating functions. /// /// The given expression is in general trainslated into: /// /// CONVERT(@typename, [datePart] + [timePart] + [timeZonePart], 121), where the datePart and the timeZonePart are optional /// /// Only on Katmai, if a date part is present it is wrapped with a call for adding years as shown below. /// The individual parts are translated as: /// /// Date part: /// PRE KATMAI: convert(varchar(255), @year) + '-' + convert(varchar(255), @month) + '-' + convert(varchar(255), @day) /// KATMAI: DateAdd(year, @year-1, covert(@typename, '0001' + '-' + convert(varchar(255), @month) + '-' + convert(varchar(255), @day) + [possibly time ], 121) /// /// Time part: /// PRE KATMAI: convert(varchar(255), @hour)+ ':' + convert(varchar(255), @minute)+ ':' + str(@second, 6, 3) /// KATMAI: convert(varchar(255), @hour)+ ':' + convert(varchar(255), @minute)+ ':' + str(@second, 10, 7) /// /// Time zone part: /// (case when @tzoffset >= 0 then '+' else '-' end) + convert(varchar(255), ABS(@tzoffset)/60) + ':' + convert(varchar(255), ABS(@tzoffset)%60) /// /// </summary> /// <param name="typeName"></param> /// <param name="args"></param> /// <param name="hasDatePart"></param> /// <param name="hasTimeZonePart"></param> /// <returns></returns> private static ISqlFragment HandleCanonicalFunctionDateTimeTypeCreation( SqlGenerator sqlgen, string typeName, IList<DbExpression> args, bool hasDatePart, bool hasTimeZonePart) { Debug.Assert( args.Count == (hasDatePart ? 3 : 0) + 3 + (hasTimeZonePart ? 1 : 0), "Invalid number of parameters for a date time creating function"); var result = new SqlBuilder(); var currentArgumentIndex = 0; if (!sqlgen.IsPreKatmai && hasDatePart) { result.Append("DATEADD(year, "); sqlgen.ParenthesizeExpressionIfNeeded(args[currentArgumentIndex++], result); result.Append(" - 1, "); } result.Append("convert ("); result.Append(typeName); result.Append(","); //Building the string representation if (hasDatePart) { // YEAR: PREKATMAI: CONVERT(VARCHAR, @YEAR) // KATMAI : '0001' if (!sqlgen.IsPreKatmai) { result.Append("'0001'"); } else { AppendConvertToVarchar(sqlgen, result, args[currentArgumentIndex++]); } // MONTH result.Append(" + '-' + "); AppendConvertToVarchar(sqlgen, result, args[currentArgumentIndex++]); // DAY result.Append(" + '-' + "); AppendConvertToVarchar(sqlgen, result, args[currentArgumentIndex++]); result.Append(" + ' ' + "); } // HOUR AppendConvertToVarchar(sqlgen, result, args[currentArgumentIndex++]); // MINUTE result.Append(" + ':' + "); AppendConvertToVarchar(sqlgen, result, args[currentArgumentIndex++]); // SECOND result.Append(" + ':' + str("); result.Append(args[currentArgumentIndex++].Accept(sqlgen)); if (sqlgen.IsPreKatmai) { result.Append(", 6, 3)"); } else { result.Append(", 10, 7)"); } // TZOFFSET if (hasTimeZonePart) { result.Append(" + (CASE WHEN "); sqlgen.ParenthesizeExpressionIfNeeded(args[currentArgumentIndex], result); result.Append(" >= 0 THEN '+' ELSE '-' END) + convert(varchar(255), ABS("); sqlgen.ParenthesizeExpressionIfNeeded(args[currentArgumentIndex], result); result.Append("/60)) + ':' + convert(varchar(255), ABS("); sqlgen.ParenthesizeExpressionIfNeeded(args[currentArgumentIndex], result); result.Append("%60))"); } result.Append(", 121)"); if (!sqlgen.IsPreKatmai && hasDatePart) { result.Append(")"); } return result; }