ts-sql-query
Version:
Type-safe SQL query builder like QueryDSL or JOOQ in Java or Linq in .Net for TypeScript with MariaDB, MySql, Oracle, PostgreSql, Sqlite and SqlServer support.
913 lines • 66.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqlServerSqlBuilder = void 0;
const SqlBuilder_1 = require("./SqlBuilder");
const TypeAdapter_1 = require("../TypeAdapter");
const values_1 = require("../expressions/values");
const AbstractSqlBuilder_1 = require("./AbstractSqlBuilder");
const Column_1 = require("../utils/Column");
const values_2 = require("../expressions/values");
const ITableOrView_1 = require("../utils/ITableOrView");
class SqlServerSqlBuilder extends AbstractSqlBuilder_1.AbstractSqlBuilder {
constructor() {
super();
this.sqlServer = true;
this._trueValue = 'convert(bit, 1)';
this._falseValue = 'convert(bit, 0)';
this._trueValueForCondition = '(1=1)';
this._falseValueForCondition = '(0=1)';
this._nullValueForCondition = '(0=null)';
this._updateOldValueInFrom = false;
this._useForJsonInAggreagteArrayWhenPossible = true;
this._operationsThatNeedParenthesis._getMonth = true;
this._operationsThatNeedParenthesis._getDay = true;
}
_appendRawColumnName(column, params) {
const columnPrivate = (0, Column_1.__getColumnPrivate)(column);
const tableOrView = columnPrivate.__tableOrView;
if ((0, ITableOrView_1.__getTableOrViewPrivate)(tableOrView).__oldValues) {
return 'deleted.' + this._escape(columnPrivate.__name, true);
}
return super._appendRawColumnName(column, params);
}
_forceAsIdentifier(identifier) {
return '[' + identifier + ']';
}
_isReservedKeyword(word) {
return word.toUpperCase() in reservedWords;
}
_nextSequenceValue(_params, sequenceName) {
return 'next value for ' + this._escape(sequenceName, false);
}
_currentSequenceValue(_params, sequenceName) {
return "(select current_value from sys.sequences where name = '" + sequenceName + "')";
}
_appendSql(value, params) {
if ((0, values_1.isValueSource)(value) && !(0, Column_1.isColumn)(value)) {
const valueSourcePrivate = (0, values_2.__getValueSourcePrivate)(value);
if (valueSourcePrivate.__isBooleanForCondition) {
if (valueSourcePrivate.__optionalType === 'required') {
return 'cast(case when ' + this._appendConditionSql(value, params) + ' then 1 else 0 end as bit)';
}
else {
return 'cast(case when ' + this._appendConditionSql(value, params) + ' then 1 when not ' + this._appendConditionSqlParenthesis(value, params) + ' then 0 else null end as bit)';
}
}
}
return super._appendSql(value, params);
}
_appendConditionSql(value, params) {
if ((0, values_1.isValueSource)(value) && !(0, Column_1.isColumn)(value) && (0, SqlBuilder_1.hasToSql)(value)) {
const valueSourcePrivate = (0, values_2.__getValueSourcePrivate)(value);
if ((0, values_1.__isBooleanValueSource)(valueSourcePrivate) && !valueSourcePrivate.__isBooleanForCondition) {
const sql = value.__toSqlForCondition(this, params);
if (!sql || sql === this._trueValueForCondition || sql === this._falseValueForCondition) {
return sql;
}
else {
return '(' + sql + ' = 1)';
}
}
}
return super._appendConditionSql(value, params);
}
_isUuid(value) {
if ((0, values_1.isValueSource)(value)) {
const valuePrivate = (0, values_2.__getValueSourcePrivate)(value);
if ((0, values_1.__isUuidValueSource)(valuePrivate) || valuePrivate.__uuidString) {
return true;
}
}
return false;
}
_appendSqlMaybeUuid(value, params) {
if (this._isUuid(value)) {
return 'convert(nvarchar, ' + this._appendSql(value, params) + ')';
}
else {
return this._appendSql(value, params);
}
}
_appendConditionParam(value, params, columnType, columnTypeName, typeAdapter, forceTypeCast) {
if ((0, values_1.__isBooleanValueType)(columnType)) {
if ((0, Column_1.isColumn)(value)) {
const columnPrivate = (0, Column_1.__getColumnPrivate)(value);
const typeAdapter = columnPrivate.__typeAdapter;
if (typeAdapter instanceof TypeAdapter_1.CustomBooleanTypeAdapter) {
return '(' + this._appendRawColumnName(value, params) + ' = ' + this._appendLiteralValue(typeAdapter.trueValue, params) + ')';
}
}
return '(' + this._appendParam(value, params, columnType, columnTypeName, typeAdapter, forceTypeCast) + ' = 1)';
}
return this._appendParam(value, params, columnType, columnTypeName, typeAdapter, forceTypeCast);
}
_appendParam(value, params, columnType, columnTypeName, typeAdapter, forceTypeCast) {
// keep the data type to use in the query runner
Object.defineProperty(params, '@' + params.length, {
value: columnType in nativeTypedValueType ? columnType : columnTypeName,
writable: true,
enumerable: false,
configurable: true
});
return super._appendParam(value, params, columnType, columnTypeName, typeAdapter, forceTypeCast);
}
_appendColumnName(column, params) {
const columnPrivate = (0, Column_1.__getColumnPrivate)(column);
const typeAdapter = columnPrivate.__typeAdapter;
if ((0, values_1.__isBooleanValueSource)(columnPrivate)) {
if (typeAdapter instanceof TypeAdapter_1.CustomBooleanTypeAdapter) {
if (columnPrivate.__optionalType === 'required') {
return 'cast(case when ' + this._appendRawColumnName(column, params) + ' = ' + this._appendLiteralValue(typeAdapter.trueValue, params) + ' then 1 else 0 end as bit)';
}
else {
return 'cast(case ' + this._appendRawColumnName(column, params) + ' when ' + this._appendLiteralValue(typeAdapter.trueValue, params) + ' then 1 when ' + this._appendLiteralValue(typeAdapter.falseValue, params) + ' then 0 else null end as bit)';
}
}
}
return this._appendRawColumnName(column, params);
}
_appendColumnNameForCondition(column, params) {
const columnPrivate = (0, Column_1.__getColumnPrivate)(column);
const typeAdapter = columnPrivate.__typeAdapter;
if ((0, values_1.__isBooleanValueSource)(columnPrivate)) {
if (typeAdapter instanceof TypeAdapter_1.CustomBooleanTypeAdapter) {
return '(' + this._appendRawColumnName(column, params) + ' = ' + this._appendLiteralValue(typeAdapter.trueValue, params) + ')';
}
else {
return '(' + this._appendRawColumnName(column, params) + ' = 1)';
}
}
return this._appendRawColumnName(column, params);
}
_inlineSelectAsValueForCondition(query, params) {
if (query.__oneColumn) {
const columns = query.__columns;
for (const prop in columns) {
const column = columns[prop];
if ((0, values_1.isValueSource)(column) && (0, values_1.__isBooleanValueSource)((0, values_2.__getValueSourcePrivate)(column))) {
return '((' + this._buildInlineSelect(query, params) + ') = 1)';
}
else {
return this._buildInlineSelect(query, params);
}
}
}
return this._buildInlineSelect(query, params);
}
_appendWithKeyword(_recursive) {
// Sql Server doesn't uses the recursive keyword
return 'with';
}
_buildWithValues(withValues, params) {
let result = withValues.__name;
result += ' as (select * from (values ';
const values = withValues.__values;
let valuesSql = '';
for (let i = 0, length = values.length; i < length; i++) {
if (valuesSql) {
valuesSql += ', ';
}
const value = values[i];
let valueSql = '';
for (var columnName in withValues) {
const column = (0, Column_1.__getColumnOfObject)(withValues.__getTableOrView(), columnName);
if (!column) {
continue;
}
if (valueSql) {
valueSql += ', ';
}
valueSql += this._appendValueForColumn(column, value[columnName], params);
}
valuesSql += '(' + valueSql + ')';
}
result += valuesSql;
result += ') as ';
result += withValues.__name;
let columns = '';
for (var columnName in withValues) {
const column = (0, Column_1.__getColumnOfObject)(withValues.__getTableOrView(), columnName);
if (!column) {
continue;
}
if (columns) {
columns += ', ';
}
const columnPrivate = (0, Column_1.__getColumnPrivate)(column);
columns += this._appendColumnAlias(columnPrivate.__name, params);
}
result += '(' + columns + ')';
result += ')';
return result;
}
_buildSelectWithColumnsInfoForCompound(query, params, columnsForInsert, isOutermostQuery) {
const result = this._buildSelectWithColumnsInfo(query, params, columnsForInsert, isOutermostQuery);
if (query.__limit !== undefined || query.__offset !== undefined || query.__orderBy || query.__customization?.beforeOrderByItems || query.__customization?.afterOrderByItems) {
return 'select * from (' + result + ') _t_' + this._generateUnique() + '_';
}
return result;
}
_buildSelectOrderBy(query, params) {
// How to index it: http://www.sqlines.com/oracle/function_based_indexes
const orderBy = query.__orderBy;
if (!orderBy) {
let orderByColumns = '';
const customization = query.__customization;
if (customization && customization.beforeOrderByItems) {
orderByColumns += this._appendRawFragment(customization.beforeOrderByItems, params);
}
if (customization && customization.afterOrderByItems) {
if (orderByColumns) {
orderByColumns += ', ';
}
orderByColumns += this._appendRawFragment(customization.afterOrderByItems, params);
}
if (orderByColumns) {
return ' order by ' + orderByColumns;
}
const limit = query.__limit;
const offset = query.__offset;
if ((offset !== null && offset !== undefined) || (limit !== null && limit !== undefined)) {
// Add fake order by to allow a limit and offset without order by
const columns = {};
(0, SqlBuilder_1.flattenQueryColumns)(query.__columns, columns, '');
let index = 0;
for (const property in columns) {
index++;
const column = columns[property];
if ((0, Column_1.isColumn)(column)) {
if ((0, Column_1.__getColumnPrivate)(column).__isPrimaryKey) {
return ' order by ' + index;
}
}
}
return ' order by 1';
}
else {
return '';
}
}
let orderByColumns = '';
const customization = query.__customization;
if (customization && customization.beforeOrderByItems) {
orderByColumns += this._appendRawFragment(customization.beforeOrderByItems, params);
}
for (const entry of orderBy) {
if (orderByColumns) {
orderByColumns += ', ';
}
const order = entry.order;
if (!order) {
orderByColumns += this._appendOrderByColumnAlias(entry, query, params);
}
else
switch (order) {
case 'asc':
case 'asc nulls first':
orderByColumns += this._appendOrderByColumnAlias(entry, query, params) + ' asc';
break;
case 'desc':
case 'desc nulls last':
orderByColumns += this._appendOrderByColumnAlias(entry, query, params) + ' desc';
break;
case 'asc nulls last':
orderByColumns += 'iif(' + this._appendOrderByColumnAlias(entry, query, params) + ' is null, 1, 0), ' + this._appendOrderByColumnAlias(entry, query, params) + ' asc';
break;
case 'desc nulls first':
orderByColumns += 'iif(' + this._appendOrderByColumnAlias(entry, query, params) + ' is not null, 1, 0), ' + this._appendOrderByColumnAlias(entry, query, params) + ' desc';
break;
case 'insensitive':
orderByColumns += this._appendOrderByColumnAliasInsensitive(entry, query, params);
break;
case 'asc insensitive':
case 'asc nulls first insensitive':
orderByColumns += this._appendOrderByColumnAliasInsensitive(entry, query, params) + ' asc';
break;
case 'desc insensitive':
case 'desc nulls last insensitive':
orderByColumns += this._appendOrderByColumnAliasInsensitive(entry, query, params) + ' desc';
break;
case 'asc nulls last insensitive':
orderByColumns += 'iif(' + this._appendOrderByColumnAlias(entry, query, params) + ' is null, 1, 0), ' + this._appendOrderByColumnAliasInsensitive(entry, query, params) + ' asc';
break;
case 'desc nulls first insensitive':
orderByColumns += 'iif(' + this._appendOrderByColumnAlias(entry, query, params) + ' is not null, 1, 0), ' + this._appendOrderByColumnAliasInsensitive(entry, query, params) + ' desc';
break;
default:
throw new Error('Invalid order by: ' + order);
}
}
if (customization && customization.afterOrderByItems) {
if (orderByColumns) {
orderByColumns += ', ';
}
orderByColumns += this._appendRawFragment(customization.afterOrderByItems, params);
}
if (!orderByColumns) {
return '';
}
return ' order by ' + orderByColumns;
}
_buildSelectLimitOffset(query, params) {
let result = '';
const limit = query.__limit;
const offset = query.__offset;
if (offset !== null && offset !== undefined) {
result += ' offset ' + this._appendValue(offset, params, 'int', 'int', undefined) + ' rows';
}
if (limit !== null && limit !== undefined) {
if (!result) {
result += ' offset 0 rows';
}
result += ' fetch next ' + this._appendValue(limit, params, 'int', 'int', undefined) + ' rows only';
}
if (!result && (query.__orderBy || query.__customization?.beforeOrderByItems || query.__customization?.afterOrderByItems) && !this._isCurrentRootQuery(query, params)) {
// subqueries with order by requires always an offset, this add a noop offset
result += ' offset 0 rows';
}
return result;
}
_buildInsertOutput(query, params) {
const idColumn = query.__idColumn;
if (idColumn) {
this._setContainsInsertReturningClause(params, true);
return ' output inserted.' + this._appendSql(idColumn, params);
}
const result = this._buildQueryOutput(query.__columns, query.__table, 'inserted', params);
this._setContainsInsertReturningClause(params, !!result);
return result;
}
_buildInsertReturning(_query, _params) {
return '';
}
_buildUpdateOutput(query, params) {
return this._buildQueryOutput(query.__columns, query.__table, 'inserted', params);
}
_buildUpdateReturning(_query, _params) {
return '';
}
_buidDeleteUsing(query, params) {
const result = this._buildFromJoins(query.__using, query.__joins, undefined, params);
if (result) {
return ' from ' + result;
}
return '';
}
_buildDeleteOutput(query, params) {
return this._buildQueryOutput(query.__columns, query.__table, 'deleted', params);
}
_buildQueryOutput(queryColumns, table, alias, params) {
if (!queryColumns) {
return '';
}
const columns = {};
(0, SqlBuilder_1.flattenQueryColumns)(queryColumns, columns, '');
const oldForceAliasFor = this._getForceAliasFor(params);
const oldForceAliasAs = this._getForceAliasAs(params);
this._setForceAliasFor(params, table);
this._setForceAliasAs(params, alias);
let requireComma = false;
let result = '';
for (const property in columns) {
if (requireComma) {
result += ', ';
}
result += this._appendSql(columns[property], params);
if (property) {
result += ' as ' + this._appendColumnAlias(property, params);
}
requireComma = true;
}
this._setForceAliasFor(params, oldForceAliasFor);
this._setForceAliasAs(params, oldForceAliasAs);
if (!result) {
return '';
}
return ' output ' + result;
}
_buildDeleteReturning(_query, _params) {
return '';
}
_isNullValue(value) {
if (value === null || value === undefined) {
return true;
}
if (!(0, values_1.isValueSource)(value)) {
return false;
}
const valueSourcePrivate = (0, values_2.__getValueSourcePrivate)(value);
if (valueSourcePrivate.isConstValue()) {
const valueSourceValue = valueSourcePrivate.getConstValue();
if (valueSourceValue === null || valueSourceValue === undefined) {
return true;
}
}
return false;
}
_isOptionalValue(value) {
if (value === null || value === undefined) {
return true;
}
if (!(0, values_1.isValueSource)(value)) {
return false;
}
const valueSourcePrivate = (0, values_2.__getValueSourcePrivate)(value);
if (valueSourcePrivate.isConstValue()) {
const valueSourceValue = valueSourcePrivate.getConstValue();
if (valueSourceValue === null || valueSourceValue === undefined) {
return true;
}
}
return valueSourcePrivate.__optionalType !== 'required';
}
_isNull(params, valueSource) {
if ((0, Column_1.isColumn)(valueSource)) {
return this._appendRawColumnName(valueSource, params) + ' is null';
}
else if ((0, values_1.isValueSource)(valueSource)) {
const valueSourcePrivate = (0, values_2.__getValueSourcePrivate)(valueSource);
if (valueSourcePrivate.__isBooleanForCondition) {
if (valueSourcePrivate.__optionalType === 'required') {
return this._falseValueForCondition;
}
else {
// This is a boolean value (0 or 1 from a column) that need to be use in a boolean expression
return '(case when ' + this._appendConditionSql(valueSource, params) + ' then 0 when not ' + this._appendConditionSqlParenthesis(valueSource, params) + ' then 0 else 1 end = 1)';
}
}
}
return this._appendSqlParenthesis(valueSource, params) + ' is null';
}
_generalIsNull(params, value, columnType, columnTypeName, typeAdapter) {
if ((0, SqlBuilder_1.hasToSql)(value)) {
return this._isNull(params, value);
}
return this._appendValueParenthesis(value, params, columnType, columnTypeName, typeAdapter) + ' is null';
}
_isNotNull(params, valueSource) {
if ((0, Column_1.isColumn)(valueSource)) {
this._appendRawColumnName(valueSource, params) + ' is not null';
}
if ((0, values_1.isValueSource)(valueSource)) {
const valueSourcePrivate = (0, values_2.__getValueSourcePrivate)(valueSource);
if (valueSourcePrivate.__isBooleanForCondition) {
if (valueSourcePrivate.__optionalType === 'required') {
return this._trueValueForCondition;
}
else {
// This is a boolean value (0 or 1 from a column) that need to be use in a boolean expression
return '(case when ' + this._appendConditionSql(valueSource, params) + ' then 1 when not ' + this._appendConditionSqlParenthesis(valueSource, params) + ' then 1 else 0 end = 1)';
}
}
}
return this._appendSqlParenthesis(valueSource, params) + ' is not null';
}
_generalIsNotNull(params, value, columnType, columnTypeName, typeAdapter) {
if ((0, SqlBuilder_1.hasToSql)(value)) {
return this._isNotNull(params, value);
}
return this._appendValueParenthesis(value, params, columnType, columnTypeName, typeAdapter) + ' is not null';
}
_is(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
const valueIsNull = this._isNullValue(value);
const valueSourceIsNull = this._isNullValue(valueSource);
const valueIsOptional = this._isOptionalValue(value);
const valueSourceIsOptional = this._isOptionalValue(valueSource);
if (valueIsNull) {
return this._isNull(params, valueSource);
}
if (valueSourceIsNull) {
// We know value is null or undefined, then, whe need to ensure the value source is null as well
return this._generalIsNull(params, value, columnType, columnTypeName, typeAdapter);
}
if (valueSourceIsOptional && valueIsOptional) {
return 'case when (' + this._equals(params, valueSource, value, columnType, columnTypeName, typeAdapter) + ') or (' + this._isNull(params, valueSource) + ' and ' + this._generalIsNull(params, value, columnType, columnTypeName, typeAdapter) + ') then 1 else 0 end = 1';
}
else if (valueSourceIsOptional || valueIsOptional) {
return 'case when ' + this._equals(params, valueSource, value, columnType, columnTypeName, typeAdapter) + ' then 1 else 0 end = 1';
}
else {
return this._equals(params, valueSource, value, columnType, columnTypeName, typeAdapter);
}
// Alternative implementation that avoid evaluate multiple times the arguments
// return 'exists(select ' + this._appendSqlParenthesis(valueSource, params) + ' intersect select ' + this._appendValueParenthesis(value, params, columnTypeName, typeAdapter) + ')'
}
_isNot(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
const valueIsNull = this._isNullValue(value);
const valueSourceIsNull = this._isNullValue(valueSource);
const valueIsOptional = this._isOptionalValue(value);
const valueSourceIsOptional = this._isOptionalValue(valueSource);
if (valueIsNull) {
return this._isNotNull(params, valueSource);
}
if (valueSourceIsNull) {
// We know value is null or undefined, then, whe need to ensure the value source is null as well
return this._generalIsNotNull(params, value, columnType, columnTypeName, typeAdapter);
}
if (valueSourceIsOptional && valueIsOptional) {
return 'not (case when (' + this._equals(params, valueSource, value, columnType, columnTypeName, typeAdapter) + ') or (' + this._isNull(params, valueSource) + ' and ' + this._generalIsNull(params, value, columnType, columnTypeName, typeAdapter) + ') then 1 else 0 end = 1)';
}
else if (valueSourceIsOptional || valueIsOptional) {
return 'not (case when ' + this._equals(params, valueSource, value, columnType, columnTypeName, typeAdapter) + ' then 1 else 0 end = 1)';
}
else {
return this._notEquals(params, valueSource, value, columnType, columnTypeName, typeAdapter);
}
// Alternative implementation that avoid evaluate multiple times the arguments
// return 'not exists(select ' + this._appendSqlParenthesis(valueSource, params) + ' intersect select ' + this._appendValueParenthesis(value, params, columnTypeName, typeAdapter) + ')'
}
_valueWhenNull(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
let result = 'isnull(';
if ((0, values_1.isValueSource)(valueSource) && (0, values_2.__getValueSourcePrivate)(valueSource).__uuidString) {
result += 'convert(nvarchar, ' + this._appendSql(valueSource, params) + ')';
}
else {
result += this._appendSql(valueSource, params);
}
result += ', ';
if ((0, values_1.isValueSource)(value) && (0, values_2.__getValueSourcePrivate)(value).__uuidString) {
result += 'convert(nvarchar, ' + this._appendValue(value, params, columnType, columnTypeName, typeAdapter) + ')';
}
else {
result += this._appendValue(value, params, columnType, columnTypeName, typeAdapter);
}
result += ')';
return result;
}
_escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) {
if (typeof value === 'string') {
value = value.replace(/\[/g, '[[]');
value = value.replace(/%/g, '[%]');
value = value.replace(/_/g, '[]');
return this._appendValue(value, params, columnType, columnTypeName, typeAdapter);
}
else {
return "replace(replace(replace(" + this._appendValue(value, params, columnType, columnTypeName, typeAdapter) + ", '[', '[[]'), '%', '[%]'), '_', '[]')";
}
}
_startsWith(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return this._appendSqlParenthesis(valueSource, params) + ' like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
_notStartsWith(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return this._appendSqlParenthesis(valueSource, params) + ' not like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
_endsWith(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
_notEndsWith(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
_startsWithInsensitive(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (this._isUuid(valueSource)) {
return this._appendSqlParenthesis(valueSource, params) + ' like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
const collation = this._connectionConfiguration.insesitiveCollation;
if (collation) {
return this._appendSqlParenthesis(valueSource, params) + ' like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%') collate " + collation;
}
else if (collation === '') {
return this._appendSqlParenthesis(valueSource, params) + ' like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
else {
return 'lower(' + this._appendSql(valueSource, params) + ') like lower(' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
}
_notStartsWithInsensitive(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (this._isUuid(valueSource)) {
return this._appendSqlParenthesis(valueSource, params) + ' not like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
const collation = this._connectionConfiguration.insesitiveCollation;
if (collation) {
return this._appendSqlParenthesis(valueSource, params) + ' not like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%') collate " + collation;
}
else if (collation === '') {
return this._appendSqlParenthesis(valueSource, params) + ' not like (' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
else {
return 'lower(' + this._appendSql(valueSource, params) + ') not like lower(' + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
}
_endsWithInsensitive(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (this._isUuid(valueSource)) {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
const collation = this._connectionConfiguration.insesitiveCollation;
if (collation) {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ') collate ' + collation;
}
else if (collation === '') {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
else {
return 'lower(' + this._appendSql(valueSource, params) + ") like lower('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
}
_notEndsWithInsensitive(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (this._isUuid(valueSource)) {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
const collation = this._connectionConfiguration.insesitiveCollation;
if (collation) {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ') collate ' + collation;
}
else if (collation === '') {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
else {
return 'lower(' + this._appendSql(valueSource, params) + ") not like lower('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + ')';
}
}
_contains(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
_notContains(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
_containsInsensitive(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (this._isUuid(valueSource)) {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
const collation = this._connectionConfiguration.insesitiveCollation;
if (collation) {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%') collate " + collation;
}
else if (collation === '') {
return this._appendSqlParenthesis(valueSource, params) + " like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
else {
return 'lower(' + this._appendSql(valueSource, params) + ") like lower('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
}
_notContainsInsensitive(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (this._isUuid(valueSource)) {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
const collation = this._connectionConfiguration.insesitiveCollation;
if (collation) {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%') collate " + collation;
}
else if (collation === '') {
return this._appendSqlParenthesis(valueSource, params) + " not like ('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
else {
return 'lower(' + this._appendSql(valueSource, params) + ") not like lower('%' + " + this._escapeLikeWildcard(params, value, columnType, columnTypeName, typeAdapter) + " + '%')";
}
}
_trim(params, valueSource) {
return 'trim(' + this._appendSqlMaybeUuid(valueSource, params) + ')';
}
_trimLeft(params, valueSource) {
return 'ltrim(' + this._appendSqlMaybeUuid(valueSource, params) + ')';
}
_trimRight(params, valueSource) {
return 'rtrim(' + this._appendSqlMaybeUuid(valueSource, params) + ')';
}
_currentDate() {
return 'getdate()';
}
_currentTime() {
return 'convert(time, current_timestamp)';
}
_random() {
return 'rand()';
}
_divide(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return 'cast(' + this._appendSql(valueSource, params) + ' as float) / cast(' + this._appendValue(value, params, this._getMathArgumentType(columnType, columnTypeName, value), this._getMathArgumentTypeName(columnType, columnTypeName, value), typeAdapter) + ' as float)';
}
_asDouble(params, valueSource) {
return 'cast(' + this._appendSql(valueSource, params) + 'as float)';
}
_concat(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
let result = '';
if (this._isUuid(valueSource)) {
result += 'convert(nvarchar, ' + this._appendSql(valueSource, params) + ')';
}
else {
result += this._appendSqlParenthesisExcluding(valueSource, params, '_concat');
}
result += ' + ';
if (this._isUuid(value)) {
result += 'convert(nvarchar, ' + this._appendValue(value, params, columnType, columnTypeName, typeAdapter) + ')';
}
else {
result += this._appendValueParenthesisExcluding(value, params, columnType, columnTypeName, typeAdapter, '_concat');
}
return result;
}
_length(params, valueSource) {
return 'len(' + valueSource.__toSql(this, params) + ')';
}
_ln(params, valueSource) {
return 'log(' + valueSource.__toSql(this, params) + ')';
}
_log10(params, valueSource) {
return 'log10(' + valueSource.__toSql(this, params) + ')';
}
_cbrt(params, valueSource) {
return 'power(' + valueSource.__toSql(this, params) + ', 3)';
}
_atan2(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
return 'atn2(' + valueSource.__toSql(this, params) + ', ' + this._appendValue(value, params, this._getMathArgumentType(columnType, columnTypeName, value), this._getMathArgumentTypeName(columnType, columnTypeName, value), typeAdapter) + ')';
}
_minimumBetweenTwoValues(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
const argumentType = this._getMathArgumentType(columnType, columnTypeName, value);
const argumentTypeName = this._getMathArgumentTypeName(columnType, columnTypeName, value);
return 'iif(' + this._appendSql(valueSource, params) + ' < ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ', ' + this._appendSql(valueSource, params) + ', ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ')';
// Alternative implementation that avoid evaluate multiple times the arguments
// if (isColumn(valueSource) || !isValueSource(valueSource) || valueSource.isConstValue()) {
// if (isColumn(value) || !isValueSource(value) || value.isConstValue()) {
// // Both values are repeteables, then, we can use the sql that compare both values repeting them
// return 'iif(' + this._appendSql(valueSource, params) + ' < ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ', ' + this._appendSql(valueSource, params) + ', ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ')'
// }
// }
// return '(select min(__minValue__) from (values (' + this._appendSql(valueSource, params) + '), (' + this._appendSql(valueSource, params) + ')) as __minValueTable__(__minValue__))'
}
_maximumBetweenTwoValues(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
const argumentType = this._getMathArgumentType(columnType, columnTypeName, value);
const argumentTypeName = this._getMathArgumentTypeName(columnType, columnTypeName, value);
return 'iif(' + this._appendSql(valueSource, params) + ' > ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ', ' + this._appendSql(valueSource, params) + ', ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ')';
// Alternative implementation that avoid evaluate multiple times the arguments
// if (isColumn(valueSource) || !isValueSource(valueSource) || valueSource.getConstValue()) {
// if (isColumn(value) || !isValueSource(value) || value.isConstValue()) {
// // Both values are repeteables, then, we can use the sql that compare both values repeting them
// return 'iif(' + this._appendSql(valueSource, params) + ' > ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ', ' + this._appendSql(valueSource, params) + ', ' + this._appendValue(value, params, argumentType, argumentTypeName, typeAdapter) + ')'
// }
// }
// return '(select max(__maxValue__) from (values (' + this._appendSql(valueSource, params) + '), (' + this._appendSql(valueSource, params) + ')) as __maxValueTable__(__maxValue__))'
}
_getDate(params, valueSource) {
return 'datepart(day, ' + this._appendSql(valueSource, params) + ')';
}
_getTime(params, valueSource) {
return "datediff_big(millisecond, '1970-01-01 00:00:00', " + this._appendSql(valueSource, params) + ")";
}
_getFullYear(params, valueSource) {
return 'datepart(year, ' + this._appendSql(valueSource, params) + ')';
}
_getMonth(params, valueSource) {
return 'datepart(month, ' + this._appendSql(valueSource, params) + ') - 1';
}
_getDay(params, valueSource) {
return 'datepart(weekday, ' + this._appendSql(valueSource, params) + ') - 1';
}
_getHours(params, valueSource) {
return 'datepart(hour, ' + this._appendSql(valueSource, params) + ')';
}
_getMinutes(params, valueSource) {
return 'datepart(minute, ' + this._appendSql(valueSource, params) + ')';
}
_getSeconds(params, valueSource) {
return 'datepart(second, ' + this._appendSql(valueSource, params) + ')';
}
_getMilliseconds(params, valueSource) {
return 'datepart(millisecond, ' + this._appendSql(valueSource, params) + ')';
}
_buildCallProcedure(params, functionName, functionParams) {
let result = 'exec ' + this._escape(functionName, false);
for (let i = 0, length = functionParams.length; i < length; i++) {
result += ' ' + this._appendSql(functionParams[i], params);
}
return result;
}
_stringConcat(params, separator, value) {
if (separator === undefined || separator === null) {
return 'string_agg(' + this._appendSqlMaybeUuid(value, params) + ", ',')";
}
else if (separator === '') {
return 'string_agg(' + this._appendSqlMaybeUuid(value, params) + ", '')";
}
else {
return 'string_agg(' + this._appendSqlMaybeUuid(value, params) + ', ' + this._appendValue(separator, params, 'string', 'string', undefined) + ')';
}
}
_stringConcatDistinct(params, separator, value) {
if (separator === undefined || separator === null) {
return 'string_agg(distinct ' + this._appendSqlMaybeUuid(value, params) + ", ',')";
}
else if (separator === '') {
return 'string_agg(distinct ' + this._appendSqlMaybeUuid(value, params) + ", '')";
}
else {
return 'string_agg(distinct ' + this._appendSqlMaybeUuid(value, params) + ', ' + this._appendValue(separator, params, 'string', 'string', undefined) + ')';
}
}
_in(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (Array.isArray(value) && value.length <= 0) {
return this._falseValueForCondition;
}
return super._in(params, valueSource, value, columnType, columnTypeName, typeAdapter);
}
_notIn(params, valueSource, value, columnType, columnTypeName, typeAdapter) {
if (Array.isArray(value) && value.length <= 0) {
return this._trueValueForCondition;
}
return super._notIn(params, valueSource, value, columnType, columnTypeName, typeAdapter);
}
_substrToEnd(params, valueSource, value, _columnType, _columnTypeName, typeAdapter) {
if (typeof value === 'number') {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValue(value + 1, params, 'int', 'int', typeAdapter) + ', len(' + this._appendSql(valueSource, params) + ') - ' + this._appendValue(value, params, 'int', 'int', typeAdapter) + ')';
}
else {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValueParenthesis(value, params, 'int', 'int', typeAdapter) + ' + 1, len(' + this._appendSql(valueSource, params) + ') - ' + this._appendValue(value, params, 'int', 'int', typeAdapter) + ')';
}
}
_substringToEnd(params, valueSource, value, _columnType, _columnTypeName, typeAdapter) {
if (typeof value === 'number') {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValue(value + 1, params, 'int', 'int', typeAdapter) + ', len(' + this._appendSql(valueSource, params) + ') - ' + this._appendValue(value, params, 'int', 'int', typeAdapter) + ')';
}
else {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValueParenthesis(value, params, 'int', 'int', typeAdapter) + ' + 1, len(' + this._appendSql(valueSource, params) + ') - ' + this._appendValue(value, params, 'int', 'int', typeAdapter) + ')';
}
}
_substr(params, valueSource, value, value2, _columnType, _columnTypeName, typeAdapter) {
if (typeof value === 'number') {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValue(value + 1, params, 'int', 'int', typeAdapter) + ', ' + this._appendValue(value2, params, 'int', 'int', typeAdapter) + ')';
}
else {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValueParenthesis(value, params, 'int', 'int', typeAdapter) + ' + 1, ' + this._appendValue(value2, params, 'int', 'int', typeAdapter) + ')';
}
}
_substring(params, valueSource, value, value2, _columnType, _columnTypeName, typeAdapter) {
if (typeof value === 'number' && typeof value2 === 'number') {
const count = value2 - value;
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValue(value + 1, params, 'int', 'int', typeAdapter) + ', ' + this._appendValue(count, params, 'int', 'int', typeAdapter) + ')';
}
if (typeof value === 'number') {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValue(value + 1, params, 'int', 'int', typeAdapter) + ', ' + this._appendValue(value2, params, 'int', 'int', typeAdapter) + ' - ' + this._appendValue(value, params, 'int', 'int', typeAdapter) + ')';
}
else {
return 'substring(' + this._appendSqlMaybeUuid(valueSource, params) + ', ' + this._appendValueParenthesis(value, params, 'int', 'int', typeAdapter) + ' + 1, ' + this._appendValue(value2, params, 'int', 'int', typeAdapter) + ' - ' + this._appendValue(value, params, 'int', 'int', typeAdapter) + ')';
}
}
_buildSelectAsAggregatedArray(query, _params) {
if (this._useForJsonInAggreagteArrayWhenPossible && query.__asInlineAggregatedArrayValue && !query.__oneColumn && query.__type === 'plain') {
return ' for json path';
}
return '';
}
_needAgggregateArrayColumnsTransformation(query, _params) {
if (!query.__asInlineAggregatedArrayValue) {
return false;
}
if (!this._useForJsonInAggreagteArrayWhenPossible) {
return true;
}
if (query.__oneColumn) {
return true;
}
return false;
}
_needAgggregateArrayWrapper(query, params) {
if (this._useForJsonInAggreagteArrayWhenPossible && query.__asInlineAggregatedArrayValue && !query.__oneColumn && query.__type === 'plain') {
return false;
}
return super._needAgggregateArrayWrapper(query, params);
}
_appendAggragateArrayWrapperBegin(query, params, aggregateId) {
if (this._useForJsonInAggreagteArrayWhenPossible && query.__type === 'compound' && !query.__oneColumn) {
const columns = query.__columns;
let requireComma = false;
let result = '';
for (const property in columns) {
if (requireComma) {
result += ', ';
}
result += 'a_' + aggregateId + '_.' + this._escape(property, true);
if (property) {
result += ' as ' + this._appendColumnAlias(property, params);
}
requireComma = true;
}
return 'select ' + result + ' from (';
}
return super._appendAggragateArrayWrapperBegin(query, params, aggregateId);
}
_appendAggragateArrayWrapperEnd(query, params, aggregateId) {
if (this._useForJsonInAggreagteArrayWhenPossible && query.__type === 'compound' && !query.__oneColumn) {
let result = ')';
if (this._supportTableAliasWithAs) {
result += ' as ';
}
else {
result += ' ';
}
result += 'a_' + aggregateId + '_ for json path';
return result;
}
return super._appendAggragateArrayWrapperEnd(query, params, aggregateId);
}
_appendAggragateArrayColumns(aggregatedArrayColumns, aggregatedArrayDistinct, params, _query) {
const distict = aggregatedArrayDistinct ? 'distinct ' : '';
if ((0, values_1.isValueSource)(aggregatedArrayColumns)) {
return "concat('[', string_agg(" + distict + this._appendJsonValueForAggregate(aggregatedArrayColumns, params) + ", ','), ']')";
}
else {
const columns = {};
(0, SqlBuilder_1.flattenQueryColumns)(aggregatedArrayColumns, columns, '');
let result = '';
for (let prop in columns) {
if (result) {
result += `, ', "` + prop + `": ', ` + this._appendJsonValueForAggregate(columns[prop], params);
}
else {
result += `'