Class ClickHouseSqlExpressionConvertVisitor
- Namespace
- LinqToDB.Internal.DataProvider.ClickHouse
- Assembly
- linq2db.dll
public class ClickHouseSqlExpressionConvertVisitor : SqlExpressionConvertVisitor
- Inheritance
-
objectClickHouseSqlExpressionConvertVisitor
- Inherited Members
- Extension Methods
Constructors
ClickHouseSqlExpressionConvertVisitor(bool, ClickHouseOptions)
public ClickHouseSqlExpressionConvertVisitor(bool allowModify, ClickHouseOptions providerOptions)
Parameters
allowModifyboolproviderOptionsClickHouseOptions
Properties
CanLowerIntervalDifference
Whether an elapsed date difference can be lowered to a value here.
public override bool CanLowerIntervalDifference { get; }
Property Value
Remarks
Declared beside the lowering it describes, and read by the member translator through
ITranslationContext.ProviderFlags. The translator has to ask before it builds anything, because
a difference it does not build stays an ordinary .NET subtraction and is computed on materialisation -
and by the time this visitor runs, the read expression is already bound to its columns, so there is no
going back.
CanLowerIntervalShift
Whether LowerTemporalArithmetic(SqlTemporalArithmeticExpression) can express a date shifted by an interval at all.
public override bool CanLowerIntervalShift { get; }
Property Value
Remarks
Read by the member translator so a declared duration added to a date is declined while the expression is still being built, rather than reaching the builder as a node nothing can render - a refusal there has no client-side fallback left. The default follows what the base implementation needs: it spends the amount through ShiftDate(SqlIntervalUnit, ISqlExpression, ISqlExpression) at FinestDateUnit, so a provider that names no finest unit cannot lower one.
Only the declared half is declined early. A shift by a computed difference is left to be built,
because start + (end - start) cancels against the difference it came from and asks the provider
for nothing - refusing it here would sink a query that works everywhere.
ConcatRequiresExplicitStringCast
When true (default), ConvertConcat(SqlConcatExpression) wraps every non-string
operand in an explicit CAST(... AS VARCHAR(N)) before adding it to the concat chain.
Required for providers whose concat operator is + (SQL Server pre-2025, SqlCe,
Access) — SQL-standard data-type precedence would otherwise try to coerce
string operands to the non-string side's type. Most providers whose final concat operator
is || (PostgreSQL / Oracle / SQLite / SAP HANA / DuckDB / Firebird / DB2 / Informix /
SQL Server 2025+) or CONCAT(...) function (MySQL / ClickHouse) auto-coerce
non-string operands and override this to false for cleaner SQL.
Sybase ASE is the exception: it emits || but keeps this true,
since ASE requires an explicit convert() for non-character operands under both
+ and ||.
protected override bool ConcatRequiresExplicitStringCast { get; }
Property Value
LikeCharactersToEscape
Characters with special meaning in LIKE predicate (defined by LikeCharactersToEscape) that should be escaped to be used as matched character.
Default: ["%", "_", "?", "*", "#", "[", "]"].
public override string[] LikeCharactersToEscape { get; }
Property Value
- string[]
LikeEscapeCharacter
Escape sequence/character to escape special characters in LIKE predicate (defined by LikeCharactersToEscape).
Default: "~".
public override string LikeEscapeCharacter { get; }
Property Value
LikeIsEscapeSupported
public override bool LikeIsEscapeSupported { get; }
Property Value
SupportsNullInColumn
protected override bool SupportsNullInColumn { get; }
Property Value
Methods
ConvertLikePredicate(Like)
public override ISqlPredicate ConvertLikePredicate(SqlPredicate.Like predicate)
Parameters
predicateSqlPredicate.Like
Returns
ConvertSearchStringPredicate(SearchString)
public override ISqlPredicate ConvertSearchStringPredicate(SqlPredicate.SearchString predicate)
Parameters
predicateSqlPredicate.SearchString
Returns
ConvertSqlBinaryExpression(SqlBinaryExpression)
public override IQueryElement ConvertSqlBinaryExpression(SqlBinaryExpression element)
Parameters
elementSqlBinaryExpression
Returns
ConvertSqlExtendedFunction(SqlExtendedFunction)
public override ISqlExpression ConvertSqlExtendedFunction(SqlExtendedFunction func)
Parameters
funcSqlExtendedFunction
Returns
ConvertSqlFunction(SqlFunction)
public override ISqlExpression ConvertSqlFunction(SqlFunction func)
Parameters
funcSqlFunction
Returns
ConvertSqlUnaryExpression(SqlUnaryExpression)
public override ISqlExpression ConvertSqlUnaryExpression(SqlUnaryExpression element)
Parameters
elementSqlUnaryExpression
Returns
ElapsedTicks(SqlIntervalDifferenceExpression)
Elapsed ticks from the nanosecond timestamps, divided by a hundred.
protected override ISqlExpression? ElapsedTicks(SqlIntervalDifferenceExpression element)
Parameters
elementSqlIntervalDifferenceExpression
Returns
Remarks
linq2db maps date/time values to DateTime64(7), which is a tick exactly, so every nanosecond
value here is a whole multiple of a hundred and the division is exact. date_diff is not used
because its finest unit is the second.
Nanoseconds in an long reach from 1678 to 2262, narrower than what a
DateTime64(7) column itself holds. That is the same boundary the millisecond form of
DateAdd already works within on this provider.
The span between two of them is narrower still, because the subtraction is taken in nanoseconds as well: two endpoints inside that window can differ by more than an long holds, so the usable span is about 292 years rather than the 584 the endpoints cover. ClickHouse wraps instead of raising, so a wider difference comes back as a plausible-looking wrong number.
IsWindowOrderByRequired(SqlExtendedFunction)
NTILE alone, and by way of the frame rather than the ordering: unordered, the window defaults to a
frame ClickHouse will not accept for it (Unsupported window frame type for function 'NTILE').
Giving it a sort key restores the default frame it wants.
protected override bool IsWindowOrderByRequired(SqlExtendedFunction func)
Parameters
funcSqlExtendedFunction
Returns
LowerTemporalArithmetic(SqlTemporalArithmeticExpression)
Shifts by the interval expressed in nanoseconds, the unit that matches what a tick is.
protected override ISqlExpression? LowerTemporalArithmetic(SqlTemporalArithmeticExpression element)
Parameters
elementSqlTemporalArithmeticExpression
Returns
Remarks
toIntervalNanosecond takes an expression, so the count needs no decomposition. Scaling ticks up
by a hundred caps the amount at long.MaxValue / 100 - about 292 years, far short of what a
TimeSpan holds, but past any span these timestamps measure exactly: ElapsedTicks(SqlIntervalDifferenceExpression)
above carries the same ceiling, and for the same reason.
TruncateDivide(ISqlExpression, long)
intDiv, because ClickHouse's / produces a float even between two integers.
protected override ISqlExpression TruncateDivide(ISqlExpression value, long divisor)
Parameters
valueISqlExpressiondivisorlong
Returns
WrapColumnExpression(ISqlExpression)
protected override ISqlExpression WrapColumnExpression(ISqlExpression expr)
Parameters
exprISqlExpression