diff --git a/src/Npgsql.csproj b/src/Npgsql.csproj
index 0eef897b71..077899d5ff 100644
--- a/src/Npgsql.csproj
+++ b/src/Npgsql.csproj
@@ -267,6 +267,7 @@
+
diff --git a/src/Npgsql/NpgsqlSchema.msl b/src/Npgsql/NpgsqlSchema.msl
index aca1179731..25c20143e7 100644
--- a/src/Npgsql/NpgsqlSchema.msl
+++ b/src/Npgsql/NpgsqlSchema.msl
@@ -303,10 +303,10 @@
-
+
-
+
diff --git a/src/Npgsql/NpgsqlSchema.ssdl b/src/Npgsql/NpgsqlSchema.ssdl
index 3fade99dfe..e495ff8e78 100644
--- a/src/Npgsql/NpgsqlSchema.ssdl
+++ b/src/Npgsql/NpgsqlSchema.ssdl
@@ -388,14 +388,65 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -625,6 +676,7 @@
+
@@ -697,6 +749,7 @@
+
@@ -709,6 +762,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -721,4 +835,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Npgsql/NpgsqlServices.cs b/src/Npgsql/NpgsqlServices.cs
index 4ec020bb34..d11cf01175 100644
--- a/src/Npgsql/NpgsqlServices.cs
+++ b/src/Npgsql/NpgsqlServices.cs
@@ -56,6 +56,7 @@ private void TranslateCommandTree(DbCommandTree commandTree, DbCommand command)
DbInsertCommandTree insert;
DbUpdateCommandTree update;
DbDeleteCommandTree delete;
+ DbFunctionCommandTree function;
if ((select = commandTree as DbQueryCommandTree) != null)
{
sqlGenerator = new SqlSelectGenerator(select);
@@ -72,8 +73,11 @@ private void TranslateCommandTree(DbCommandTree commandTree, DbCommand command)
{
sqlGenerator = new SqlDeleteGenerator(delete);
}
- else
+ else if ((function = commandTree as DbFunctionCommandTree) != null)
{
+ sqlGenerator = new SqlFunctionGenerator(function);
+ }
+ else {
// TODO: get a message (unsupported DbCommandTree type)
throw new ArgumentException();
}
diff --git a/src/Npgsql/SqlGenerators/SqlFunctionGenerator.cs b/src/Npgsql/SqlGenerators/SqlFunctionGenerator.cs
new file mode 100644
index 0000000000..fd33cf12cd
--- /dev/null
+++ b/src/Npgsql/SqlGenerators/SqlFunctionGenerator.cs
@@ -0,0 +1,98 @@
+#if ENTITIES
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+#if ENTITIES6
+using System.Data.Entity.Core.Common.CommandTrees;
+using NpgsqlTypes;
+using System.Data.Entity.Core.Metadata.Edm;
+#else
+using System.Data.Common.CommandTrees;
+using System.Data.Metadata.Edm;
+#endif
+
+namespace Npgsql.SqlGenerators {
+ internal class SqlFunctionGenerator : SqlBaseGenerator {
+ private DbFunctionCommandTree _commandTree;
+
+ public SqlFunctionGenerator(DbFunctionCommandTree commandTree) {
+ _commandTree = commandTree;
+ }
+
+ public override void BuildCommand(DbCommand command) {
+ System.Diagnostics.Debug.Assert(command is NpgsqlCommand);
+
+ var edmFunc = _commandTree.EdmFunction;
+ if (String.IsNullOrEmpty(edmFunc.CommandTextAttribute)) {
+ String text = "";
+ if (false) { }
+#if ENTITIES6
+ else if (!String.IsNullOrEmpty(edmFunc.Schema)) text += QuoteIdentifier(edmFunc.Schema);
+#endif
+ else if (!String.IsNullOrEmpty(edmFunc.NamespaceName)) text += QuoteIdentifier(edmFunc.NamespaceName);
+
+ if (!String.IsNullOrEmpty(text))
+ text += ".";
+
+ if (false) { }
+#if ENTITIES6
+ else if (!String.IsNullOrEmpty(edmFunc.StoreFunctionNameAttribute)) text += QuoteIdentifier(edmFunc.StoreFunctionNameAttribute);
+#endif
+ else if (!String.IsNullOrEmpty(edmFunc.Name)) text += QuoteIdentifier(edmFunc.Name);
+
+ command.CommandType = System.Data.CommandType.StoredProcedure;
+ command.CommandText = text;
+ }
+ else {
+ command.CommandType = System.Data.CommandType.Text;
+ command.CommandText = _commandTree.EdmFunction.CommandTextAttribute;
+ }
+
+ command.Parameters.Clear();
+
+ foreach (var kv in _commandTree.Parameters) {
+ FunctionParameter funcParm;
+ if (edmFunc != null && edmFunc.Parameters.TryGetValue(kv.Key, true, out funcParm)) {
+ //fp.Name; fp.TypeUsage; fp.Mode;
+ var pgParm = new NpgsqlParameter(funcParm.Name, DBNull.Value);
+ if (false) { }
+ else if (funcParm.Mode == ParameterMode.In) pgParm.Direction = System.Data.ParameterDirection.Input;
+ else if (funcParm.Mode == ParameterMode.Out) pgParm.Direction = System.Data.ParameterDirection.Output;
+ else if (funcParm.Mode == ParameterMode.InOut) pgParm.Direction = System.Data.ParameterDirection.InputOutput;
+ else if (funcParm.Mode == ParameterMode.ReturnValue) pgParm.Direction = System.Data.ParameterDirection.ReturnValue;
+ else { }
+
+ if (false) { }
+ else if (funcParm.TypeUsage.EdmType is PrimitiveType) {
+ var pt = (PrimitiveType)funcParm.TypeUsage.EdmType;
+ if (false) { }
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Binary) pgParm.DbType = System.Data.DbType.Binary;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Boolean) pgParm.DbType = System.Data.DbType.Boolean;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Byte) pgParm.DbType = System.Data.DbType.Byte;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.DateTime) pgParm.DbType = System.Data.DbType.DateTime;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.DateTimeOffset) pgParm.DbType = System.Data.DbType.DateTimeOffset;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Decimal) pgParm.DbType = System.Data.DbType.Decimal;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Double) pgParm.DbType = System.Data.DbType.Double;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Guid) pgParm.DbType = System.Data.DbType.Guid;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Int16) pgParm.DbType = System.Data.DbType.Int16;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Int32) pgParm.DbType = System.Data.DbType.Int32;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Int64) pgParm.DbType = System.Data.DbType.Int64;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.SByte) pgParm.DbType = System.Data.DbType.SByte;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Single) pgParm.DbType = System.Data.DbType.Single;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.String) pgParm.DbType = System.Data.DbType.String;
+ else if (pt.PrimitiveTypeKind == PrimitiveTypeKind.Time) pgParm.DbType = System.Data.DbType.Time;
+ else throw new NotSupportedException("Unknown PrimitiveTypeKind: " + pt.PrimitiveTypeKind);
+ }
+ else throw new NotSupportedException("EdmType has to be PrimitiveType");
+
+ command.Parameters.Add(pgParm);
+ }
+ }
+ }
+
+ public override VisitedExpression Visit(DbPropertyExpression expression) {
+ throw new NotImplementedException();
+ }
+ }
+}
+#endif