Skip to content

Commit

Permalink
Implemented coalesce function
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnx committed Jul 28, 2023
1 parent 8a43cc2 commit f092c4a
Show file tree
Hide file tree
Showing 3 changed files with 392 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/BabyKusto.Core/Evaluation/BuiltIns/BuiltInScalarFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,36 @@ static BuiltInScalarFunctions()
new ScalarOverloadInfo(new MinOfLongFunctionImpl(), ScalarTypes.Long, ScalarTypes.Long, ScalarTypes.Long),
new ScalarOverloadInfo(new MinOfDoubleFunctionImpl(), ScalarTypes.Real, ScalarTypes.Real, ScalarTypes.Real)));

{
var overloads = new List<ScalarOverloadInfo>();

AddCoalesce(overloads, () => new CoalesceBoolFunctionImpl(), ScalarTypes.Bool);
AddCoalesce(overloads, () => new CoalesceIntFunctionImpl(), ScalarTypes.Int);
AddCoalesce(overloads, () => new CoalesceLongFunctionImpl(), ScalarTypes.Long);
AddCoalesce(overloads, () => new CoalesceDoubleFunctionImpl(), ScalarTypes.Real);
AddCoalesce(overloads, () => new CoalesceDateTimeFunctionImpl(), ScalarTypes.DateTime);
AddCoalesce(overloads, () => new CoalesceTimeSpanFunctionImpl(), ScalarTypes.TimeSpan);
AddCoalesce(overloads, () => new CoalesceStringFunctionImpl(), ScalarTypes.String);

functions.Add(Functions.Coalesce, new ScalarFunctionInfo(overloads.ToArray()));

static void AddCoalesce(List<ScalarOverloadInfo> overloads, Func<IScalarFunctionImpl> factory, ScalarSymbol type)
{
var impl = factory();

for (int numArgs = 2; numArgs <= 4; numArgs++)
{
var argTypes = new ScalarSymbol[numArgs];
for (int i = 0; i < numArgs; i++)
{
argTypes[i] = type;
}

overloads.Add(new ScalarOverloadInfo(impl, type, argTypes));
}
}
}

functions.Add(Functions.Now, new ScalarFunctionInfo(new ScalarOverloadInfo(new NowFunctionImpl(), ScalarTypes.DateTime)));
functions.Add(Functions.Ago, new ScalarFunctionInfo(new ScalarOverloadInfo(new AgoFunctionImpl(), ScalarTypes.DateTime, ScalarTypes.TimeSpan)));

Expand Down
303 changes: 303 additions & 0 deletions src/BabyKusto.Core/Evaluation/BuiltIns/ScalarFunctions/Coalesce.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Diagnostics;
using Kusto.Language.Symbols;

namespace BabyKusto.Core.Evaluation.BuiltIns.Impl
{
internal class CoalesceBoolFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
bool? result = null;
for (int i = 0; i < arguments.Length; i++)
{
var item = (bool?)arguments[i].Value;
if (item.HasValue)
{
result = item.Value;
break;
}
}

return new ScalarResult(ScalarTypes.Bool, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new bool?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<bool?>)arguments[i].Column;
var item = column[j];
if (item.HasValue)
{
data[j] = item.Value;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.Bool, data));
}
}

internal class CoalesceIntFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
int? result = null;
for (int i = 0; i < arguments.Length; i++)
{
var item = (int?)arguments[i].Value;
if (item.HasValue)
{
result = item.Value;
break;
}
}

return new ScalarResult(ScalarTypes.Int, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new int?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<int?>)arguments[i].Column;
var item = column[j];
if (item.HasValue)
{
data[j] = item.Value;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.Int, data));
}
}

internal class CoalesceLongFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
long? result = null;
for (int i = 0; i < arguments.Length; i++)
{
var item = (long?)arguments[i].Value;
if (item.HasValue)
{
result = item.Value;
break;
}
}

return new ScalarResult(ScalarTypes.Long, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new long?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<long?>)arguments[i].Column;
var item = column[j];
if (item.HasValue)
{
data[j] = item.Value;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.Long, data));
}
}

internal class CoalesceDoubleFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
double? result = null;
for (int i = 0; i < arguments.Length; i++)
{
var item = (double?)arguments[i].Value;
if (item.HasValue)
{
result = item.Value;
break;
}
}

return new ScalarResult(ScalarTypes.Real, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new double?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<double?>)arguments[i].Column;
var item = column[j];
if (item.HasValue)
{
data[j] = item.Value;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.Real, data));
}
}

internal class CoalesceDateTimeFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
DateTime? result = null;
for (int i = 0; i < arguments.Length; i++)
{
var item = (DateTime?)arguments[i].Value;
if (item.HasValue)
{
result = item.Value;
break;
}
}

return new ScalarResult(ScalarTypes.DateTime, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new DateTime?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<DateTime?>)arguments[i].Column;
var item = column[j];
if (item.HasValue)
{
data[j] = item.Value;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.DateTime, data));
}
}

internal class CoalesceTimeSpanFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
TimeSpan? result = null;
for (int i = 0; i < arguments.Length; i++)
{
var item = (TimeSpan?)arguments[i].Value;
if (item.HasValue)
{
result = item.Value;
break;
}
}

return new ScalarResult(ScalarTypes.TimeSpan, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new TimeSpan?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<TimeSpan?>)arguments[i].Column;
var item = column[j];
if (item.HasValue)
{
data[j] = item.Value;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.TimeSpan, data));
}
}

internal class CoalesceStringFunctionImpl : IScalarFunctionImpl
{
public ScalarResult InvokeScalar(ScalarResult[] arguments)
{
string? result = string.Empty;
for (int i = 0; i < arguments.Length; i++)
{
var item = (string?)arguments[i].Value;
if (!string.IsNullOrEmpty(item))
{
result = item;
break;
}
}

return new ScalarResult(ScalarTypes.String, result);
}

public ColumnarResult InvokeColumnar(ColumnarResult[] arguments)
{
Debug.Assert(arguments.Length > 0);

int numRows = arguments[0].Column.RowCount;
var data = new string?[numRows];
for (int j = 0; j < numRows; j++)
{
for (int i = 0; i < arguments.Length; i++)
{
var column = (Column<string?>)arguments[i].Column;
var item = column[j];
if (!string.IsNullOrEmpty(item))
{
data[j] = item;
break;
}
}
}

return new ColumnarResult(Column.Create(ScalarTypes.String, data));
}
}
}
Loading

0 comments on commit f092c4a

Please sign in to comment.