ronantakizawa/codereview-bench huggingface dataset:
Repository: directus/directus
File: app/src/modules/content/routes/item.vue (Vue)

Code before:
				v-else
				v-tooltip.bottom="t('back')"
				class="header-icon"
				rounded
				icon
				secondary
				exact
				@click="navigateBack"
			>
				<v-icon name="arrow_back" />
			</v-button>
		</template>

		<template #headline>
			<div class="headline-wrapper" :class="{ 'has-version-menu': shouldShowVersioning }">
				<v-breadcrumb
					v-if="collectionInfo.meta && collectionInfo.meta.singleton === true"
					:items="[{ name: t('content'), to: '/content' }]"
					class="headline-breadcrumb"
				/>
				<v-breadcrumb v-else :items="breadcrumb" class="headline-breadcrumb" />

				<version-menu
					v-if="shouldShowVersioning"
					:collection="collection"
					:primary-key="internalPrimaryKey"
					:update-allowed="updateAllowed"
					:has-edits="hasEdits"
					:current-version="currentVersion"
					:versions="versions"
					@add="addVersion"
					@update="updateVersion"
					@delete="deleteVersion"
					@switch="currentVersion = $event"
				/>
			</div>
		</template>

		<template #title-outer:append></template>

		<template #actions>
			<v-button
				v-if="previewUrl"
				v-tooltip.bottom="t(livePreviewMode === null ? 'live_preview.enable' : 'live_preview.disable')"
				rounded
				icon
				class="action-preview"
				:secondary="livePreviewMode === null"
				@click="toggleSplitView"
			>
				<v-icon name="visibility" outline />

Review comment (suggestion):

```suggestion
					:primary-key="internalPrimaryKey!"
```

Code after:
				v-else
				v-tooltip.bottom="t('back')"
				class="header-icon"
				rounded
				icon
				secondary
				exact
				@click="navigateBack"
			>
				<v-icon name="arrow_back" />
			</v-button>
		</template>

		<template #headline>
			<div class="headline-wrapper" :class="{ 'has-version-menu': shouldShowVersioning }">
				<v-breadcrumb
					v-if="collectionInfo.meta && collectionInfo.meta.singleton === true"
					:items="[{ name: t('content'), to: '/content' }]"
					class="headline-breadcrumb"
				/>
				<v-breadcrumb v-else :items="breadcrumb" class="headline-breadcrumb" />

				<version-menu
					v-if="shouldShowVersioning"
					:collection="collection"
					:primary-key="internalPrimaryKey!"
					:update-allowed="updateAllowed"
					:has-edits="hasEdits"
					:current-version="currentVersion"
					:versions="versions"
					@add="addVersion"
					@update="updateVersion"
					@delete="deleteVersion"
					@switch="currentVersion = $event"
				/>
			</div>
		</template>

		<template #title-outer:append></template>

		<template #actions>
			<v-button
				v-if="previewUrl"
				v-tooltip.bottom="t(livePreviewMode === null ? 'live_preview.enable' : 'live_preview.disable')"
				rounded
				icon
				class="action-preview"
				:secondary="livePreviewMode === null"
				@click="toggleSplitView"
			>
				<v-icon name="visibility" outline />
Repository: directus/directus
File: app/src/modules/content/routes/item.vue (Vue)

Code before:
	@media (min-width: 600px) {
		padding: var(--content-padding);
		padding-bottom: var(--content-padding-bottom);
	}
}

.title-loader {
	width: 260px;
}

:deep(.version-more-options.v-icon) {
	color: var(--theme--foreground-subdued);

	&:hover {
		color: var(--theme--foreground);
	}
}

.type-title {
	margin-top: 14px;
}

.has-content-versioning {
	.type-title {
		margin-top: 0;
		line-height: 1;
	}

	:deep(.header-bar .title-container) {
		flex-direction: column;
		justify-content: center;
		gap: 0;
		align-items: start;

		.headline {
			opacity: 1;
		}

		@media (min-width: 600px) {
			opacity: 1;
		}
	}

	.headline-wrapper {
		display: flex;
		align-items: center;
		gap: 0.25rem;
	}

	:deep(.header-bar.collapsed.shadow .title-container .headline) {
		opacity: 1;

Review comment (suggestion):
`line-height: 1;` cuts off the underlength of the typeface. I don’t think this is necessary.

Code after:
	@media (min-width: 600px) {
		padding: var(--content-padding);
		padding-bottom: var(--content-padding-bottom);
	}
}

.title-loader {
	width: 260px;
}

:deep(.version-more-options.v-icon) {
	color: var(--theme--foreground-subdued);

	&:hover {
		color: var(--theme--foreground);
	}
}

.has-content-versioning {
	:deep(.header-bar .title-container) {
		flex-direction: column;
		justify-content: center;
		gap: 0;
		align-items: start;

		.headline {
			opacity: 1;
			top: 3px;
		}

		.title {
			top: 4px;
		}

		@media (min-width: 600px) {
			opacity: 1;
		}
	}

	.headline-wrapper {
		display: flex;
		align-items: center;
		gap: 0.25rem;
	}

	:deep(.header-bar.collapsed.shadow .title-container .headline) {
		opacity: 1;
		pointer-events: auto;
	}
	:deep(.header-bar.small.shadow .title-container .headline) {
		opacity: 1;
Repository: directus/directus
File: app/src/modules/content/components/version-menu.vue (Vue)

Code before:

	@include mixins.form-grid;
}

.version-menu-wrapper {
	overflow: hidden;
	position: relative;
	display: flex;
	align-items: center;

	@media (min-width: 600px) {
		padding-left: 1rem; // Add space for the bullet

		&::before {
			content: '';
			position: absolute;
			top: 50%;
			left: 0.25rem;
			width: 0.25rem;
			height: 0.25rem;
			border-radius: 50%;
			transform: translateY(-50%);
			background-color: var(--theme--foreground-subdued);
		}
	}
}

.version-menu {
	flex-shrink: 1;
}

.version-current {
	display: flex;
	align-items: center;
}

.version-item {
	--v-list-item-color-active: var(--foreground-inverted);
	--v-list-item-background-color-active: var(--theme--primary);
	--v-list-item-color-active-hover: var(--white);
	--v-list-item-background-color-active-hover: var(--theme--primary-accent);
}

.version-delete {
	--v-list-item-color: var(--theme--danger);
	--v-list-item-color-hover: var(--theme--danger);
}

.version-name {
	max-width: 80%;
}

Review comment (bug):
Could be simplified:

```suggestion
.version-menu-wrapper {
	overflow: hidden;
	display: flex;
	align-items: center;

	@media (min-width: 600px) {
		&::before {
			content: '•';
			padding-right: 0.25rem;
			color: var(--theme--foreground-subdued);
		}
	}
}
```

Code after:
.version-menu-wrapper {
	overflow: hidden;
	display: flex;
	align-items: center;

	@media (min-width: 600px) {
		&::before {
			content: '•';
			padding-right: 0.25rem;
			color: var(--theme--foreground-subdued);
		}
	}
}

.version-menu {
	flex-shrink: 1;
}

.version-item {
	--v-list-item-color-active: var(--foreground-inverted);
	--v-list-item-background-color-active: var(--theme--primary);
	--v-list-item-color-active-hover: var(--white);
	--v-list-item-background-color-active-hover: var(--theme--primary-accent);
}

.version-delete {
	--v-list-item-color: var(--theme--danger);
	--v-list-item-color-hover: var(--theme--danger);
}

.version-name {
	margin-left: 0.15em;
}

.version-button {
	--v-icon-size: 1rem;
	color: var(--theme--foreground-subdued);
	display: flex;
	align-items: center;
	&:hover {
		color: var(--theme--foreground);
	}
}
</style>
Repository: directus/directus
File: app/src/modules/content/components/version-menu.vue (Vue)

Code before:
		await deleteVersion();
		deleteDialogActive.value = false;
	}
}

function getVersionDisplayName(version: ContentVersion) {
	return isNil(version.name) ? version.key : version.name;
}

async function onPromoteComplete(deleteOnPromote: boolean) {
	isVersionPromoteDrawerOpen.value = false;

	if (deleteOnPromote) {
		await deleteVersion();
	} else {
		emit('switch', null);
	}
}
</script>

<template>
	<div class="version-menu-wrapper">
		<v-menu class="version-menu" placement="bottom-start" show-arrow>
			<template #activator="{ toggle }">
				<button secondary rounded class="version-button" :class="{ main: currentVersion === null }" @click="toggle">
					<div class="version-current">
						<v-icon class="version-icon" name="history" />
						<span class="version-name">
							<v-text-overflow
								:text="currentVersion ? getVersionDisplayName(currentVersion) : t('main_version')"
								placement="bottom"
							/>
						</span>

						<v-icon small name="arrow_drop_down" />
					</div>
				</button>
			</template>

			<v-list>
				<v-list-item class="version-item" clickable :active="currentVersion === null" @click="switchVersion(null)">
					{{ t('main_version') }}
				</v-list-item>

				<v-list-item
					v-for="versionItem of versions"
					:key="versionItem.id"
					class="version-item"
					clickable
					:active="versionItem.id === currentVersion?.id"
					@click="switchVersion(versionItem)"

Review comment (refactor):
We can remove this `div.version-current` and put its styles into the `button.version-button` instead (see below)

Code after:
		await deleteVersion();
		deleteDialogActive.value = false;
	}
}

function getVersionDisplayName(version: ContentVersion) {
	return isNil(version.name) ? version.key : version.name;
}

async function onPromoteComplete(deleteOnPromote: boolean) {
	isVersionPromoteDrawerOpen.value = false;

	if (deleteOnPromote) {
		await deleteVersion();
	} else {
		emit('switch', null);
	}
}
</script>

<template>
	<div class="version-menu-wrapper">
		<v-menu class="version-menu" placement="bottom-start" show-arrow>
			<template #activator="{ toggle }">
				<button class="version-button" type="button" @click="toggle">
					<v-icon name="published_with_changes" />
					<v-text-overflow
						class="version-name"
						:text="currentVersion ? getVersionDisplayName(currentVersion) : t('main_version')"
						placement="bottom"
					/>
					<v-icon small name="arrow_drop_down" />
				</button>
			</template>

			<v-list>
				<v-list-item class="version-item" clickable :active="currentVersion === null" @click="switchVersion(null)">
					{{ t('main_version') }}
				</v-list-item>

				<v-list-item
					v-for="versionItem of versions"
					:key="versionItem.id"
					class="version-item"
					clickable
					:active="versionItem.id === currentVersion?.id"
					@click="switchVersion(versionItem)"
				>
					{{ getVersionDisplayName(versionItem) }}
				</v-list-item>
Repository: directus/directus
File: app/src/modules/content/components/version-menu.vue (Vue)

Code before:

	@media (min-width: 600px) {
		padding-left: 1rem; // Add space for the bullet

		&::before {
			content: '';
			position: absolute;
			top: 50%;
			left: 0.25rem;
			width: 0.25rem;
			height: 0.25rem;
			border-radius: 50%;
			transform: translateY(-50%);
			background-color: var(--theme--foreground-subdued);
		}
	}
}

.version-menu {
	flex-shrink: 1;
}

.version-current {
	display: flex;
	align-items: center;
}

.version-item {
	--v-list-item-color-active: var(--foreground-inverted);
	--v-list-item-background-color-active: var(--theme--primary);
	--v-list-item-color-active-hover: var(--white);
	--v-list-item-background-color-active-hover: var(--theme--primary-accent);
}

.version-delete {
	--v-list-item-color: var(--theme--danger);
	--v-list-item-color-hover: var(--theme--danger);
}

.version-name {
	max-width: 80%;
}

.version-icon {
	--v-icon-size: 1rem;
	--v-icon-color: var(--theme--foreground-subdued);
}

.version-button {
	color: var(--theme--foreground-subdued);
	font-size: 12px;

Review comment (suggestion):
As described above, this could be removed and put into `.version-button` below instead.

Code after:
			color: var(--theme--foreground-subdued);
		}
	}
}

.version-menu {
	flex-shrink: 1;
}

.version-item {
	--v-list-item-color-active: var(--foreground-inverted);
	--v-list-item-background-color-active: var(--theme--primary);
	--v-list-item-color-active-hover: var(--white);
	--v-list-item-background-color-active-hover: var(--theme--primary-accent);
}

.version-delete {
	--v-list-item-color: var(--theme--danger);
	--v-list-item-color-hover: var(--theme--danger);
}

.version-name {
	margin-left: 0.15em;
}

.version-button {
	--v-icon-size: 1rem;
	color: var(--theme--foreground-subdued);
	display: flex;
	align-items: center;
	&:hover {
		color: var(--theme--foreground);
	}
}
</style>
Repository: directus/directus
File: app/src/modules/content/components/version-menu.vue (Vue)

Code before:
	overflow: hidden;
	position: relative;
	display: flex;
	align-items: center;

	@media (min-width: 600px) {
		padding-left: 1rem; // Add space for the bullet

		&::before {
			content: '';
			position: absolute;
			top: 50%;
			left: 0.25rem;
			width: 0.25rem;
			height: 0.25rem;
			border-radius: 50%;
			transform: translateY(-50%);
			background-color: var(--theme--foreground-subdued);
		}
	}
}

.version-menu {
	flex-shrink: 1;
}

.version-current {
	display: flex;
	align-items: center;
}

.version-item {
	--v-list-item-color-active: var(--foreground-inverted);
	--v-list-item-background-color-active: var(--theme--primary);
	--v-list-item-color-active-hover: var(--white);
	--v-list-item-background-color-active-hover: var(--theme--primary-accent);
}

.version-delete {
	--v-list-item-color: var(--theme--danger);
	--v-list-item-color-hover: var(--theme--danger);
}

.version-name {
	max-width: 80%;
}

.version-icon {
	--v-icon-size: 1rem;
	--v-icon-color: var(--theme--foreground-subdued);
}

Review comment (suggestion):
Add some space between the icon and the version name.

```suggestion
.version-name {
    margin-left: 0.15em;
```

Code after:
	@media (min-width: 600px) {
		&::before {
			content: '•';
			padding-right: 0.25rem;
			color: var(--theme--foreground-subdued);
		}
	}
}

.version-menu {
	flex-shrink: 1;
}

.version-item {
	--v-list-item-color-active: var(--foreground-inverted);
	--v-list-item-background-color-active: var(--theme--primary);
	--v-list-item-color-active-hover: var(--white);
	--v-list-item-background-color-active-hover: var(--theme--primary-accent);
}

.version-delete {
	--v-list-item-color: var(--theme--danger);
	--v-list-item-color-hover: var(--theme--danger);
}

.version-name {
	margin-left: 0.15em;
}

.version-button {
	--v-icon-size: 1rem;
	color: var(--theme--foreground-subdued);
	display: flex;
	align-items: center;
	&:hover {
		color: var(--theme--foreground);
	}
}
</style>
Repository: directus/directus
File: api/src/controllers/fields.ts (TypeScript)

Code before:
			throw error;
		}

		return next();
	}),
	respond,
);

router.patch(
	'/:collection',
	validateCollection,
	asyncHandler(async (req, res, next) => {
		const service = new FieldsService({
			accountability: req.accountability,
			schema: req.schema,
		});

		if (Array.isArray(req.body)) {
			for (const fieldData of req.body) {
				if (isSystemField(req.params['collection']!, fieldData['field']!)) {
					const { error } = systemFieldUpdateSchema.validate(fieldData);

					if (error) throw new InvalidPayloadError({ reason: error.message });
				}
			}
		} else {
			throw new InvalidPayloadError({ reason: 'Submitted body has to be an array' });
		}

		await service.updateFields(req.params['collection']!, req.body);

		try {
			const results: any = [];

			for (const field of req.body) {
				const updatedField = await service.readOne(req.params['collection']!, field.field);
				results.push(updatedField);
				res.locals['payload'] = { data: results || null };
			}
		} catch (error: any) {
			if (isDirectusError(error, ErrorCode.Forbidden)) {
				return next();
			}

			throw error;
		}

		return next();
	}),
	respond,
);

Review comment (suggestion):
Let's shift this entire logic down after this array check

```suggestion
		if (Array.isArray(req.body) === false) {
```

Code after:
			throw error;
		}

		return next();
	}),
	respond,
);

router.patch(
	'/:collection',
	validateCollection,
	asyncHandler(async (req, res, next) => {
		const service = new FieldsService({
			accountability: req.accountability,
			schema: req.schema,
		});

		if (Array.isArray(req.body) === false) {
			throw new InvalidPayloadError({ reason: 'Submitted body has to be an array' });
		}

		for (const fieldData of req.body) {
			if (isSystemField(req.params['collection']!, fieldData['field']!)) {
				const { error } = systemFieldUpdateSchema.safeParse(fieldData);

				if (error) throw error.issues.map((details) => new InvalidPayloadError({ reason: details.message }));
			}
		}

		await service.updateFields(req.params['collection']!, req.body);

		try {
			const results: any = [];

			for (const field of req.body) {
				const updatedField = await service.readOne(req.params['collection']!, field.field);
				results.push(updatedField);
				res.locals['payload'] = { data: results || null };
			}
		} catch (error: any) {
			if (isDirectusError(error, ErrorCode.Forbidden)) {
				return next();
			}

			throw error;
		}

		return next();
	}),
	respond,
);
Repository: directus/directus
File: packages/env/src/constants/directus-variables.ts (TypeScript)

Code before:
/**
 * Variables in the environment that Directus will read as configuration
 */
export const DIRECTUS_VARIABLES = [
	// general
	'CONFIG_PATH',
	'HOST',
	'PORT',
	'PUBLIC_URL',
	'LOG_LEVEL',
	'LOG_STYLE',
	'LOG_HTTP_IGNORE_PATHS',
	'MAX_PAYLOAD_SIZE',
	'ROOT_REDIRECT',
	'SERVE_APP',
	'GRAPHQL_INTROSPECTION',
	'GRAPHQL_SCHEMA_CACHE_CAPACITY',
	'GRAPHQL_SCHEMA_GENERATION_MAX_CONCURRENT',
	'GRAPHQL_QUERY_TOKEN_LIMIT',
	'MAX_BATCH_MUTATION',
	'LOGGER_.+',
	'QUERY_MAX_DEPTH',
	'QUERY_LIMIT_MAX',
	'QUERY_LIMIT_DEFAULT',
	'ROBOTS_TXT',
	'TEMP_PATH',

	'MARKETPLACE_REGISTRY',
	'MARKETPLACE_TRUST',

	// server
	'SERVER_.+',

	// database
	'DB_.+',

	// security
	'SECRET',

	'ACCESS_TOKEN_TTL',
	'EMAIL_VERIFICATION_TOKEN_TTL',
	'REFRESH_TOKEN_TTL',
	'REFRESH_TOKEN_COOKIE_NAME',
	'REFRESH_TOKEN_COOKIE_DOMAIN',
	'REFRESH_TOKEN_COOKIE_SECURE',
	'REFRESH_TOKEN_COOKIE_SAME_SITE',


Review comment (suggestion):
This can be a bit confusing since `QUERY_LIMIT_MAX` and `QUERY_LIMIT_DEFAULT` already exist. Should we rename it to something more unique?

```suggestion
	'QUERYSTRING_PARSE_MAX_DEPTH',
```

Code after:
/**
 * Variables in the environment that Directus will read as configuration
 */
export const DIRECTUS_VARIABLES = [
	// general
	'CONFIG_PATH',
	'HOST',
	'PORT',
	'PUBLIC_URL',
	'LOG_LEVEL',
	'LOG_STYLE',
	'LOG_HTTP_IGNORE_PATHS',
	'MAX_PAYLOAD_SIZE',
	'ROOT_REDIRECT',
	'SERVE_APP',
	'GRAPHQL_INTROSPECTION',
	'GRAPHQL_SCHEMA_CACHE_CAPACITY',
	'GRAPHQL_SCHEMA_GENERATION_MAX_CONCURRENT',
	'GRAPHQL_QUERY_TOKEN_LIMIT',
	'MAX_BATCH_MUTATION',
	'LOGGER_.+',
	'QUERYSTRING_MAX_PARSE_DEPTH',
	'QUERY_LIMIT_MAX',
	'QUERY_LIMIT_DEFAULT',
	'ROBOTS_TXT',
	'TEMP_PATH',

	'MARKETPLACE_REGISTRY',
	'MARKETPLACE_TRUST',

	// server
	'SERVER_.+',

	// database
	'DB_.+',

	// security
	'SECRET',

	'ACCESS_TOKEN_TTL',
	'EMAIL_VERIFICATION_TOKEN_TTL',
	'REFRESH_TOKEN_TTL',
	'REFRESH_TOKEN_COOKIE_NAME',
	'REFRESH_TOKEN_COOKIE_DOMAIN',
	'REFRESH_TOKEN_COOKIE_SECURE',
	'REFRESH_TOKEN_COOKIE_SAME_SITE',
Repository: directus/directus
File: app/src/interfaces/input-block-editor/input-block-editor.vue (Vue)

Code before:

onMounted(async () => {
	editorjsRef.value = new EditorJS({
		logLevel: 'ERROR' as EditorJS.LogLevels,
		holder: editorElement.value,
		readOnly: false,
		placeholder: props.placeholder,
		minHeight: 72,
		onChange: (api) => emitValue(api),
		tools: tools,
	});

	await editorjsRef.value.isReady;

	const sanitizedValue = sanitizeValue(props.value);

	if (sanitizedValue) {
		await editorjsRef.value.render(sanitizedValue);
	}

	if (props.autofocus) {
		editorjsRef.value.focus();
	}

	editorjsRef.value.on(BlockChanged, () => {
		if (editorjsIsInitialized.value == true) {
			emitValue(editorjsRef.value);
		}
	});

	editorjsIsReady.value = true;
});

onUnmounted(() => {
	editorjsRef.value?.destroy();
	bus.reset();
});

watch(
	() => props.value,
	async (newVal, oldVal) => {
		// First value will be set in 'onMounted'
		if (!editorjsRef.value || !editorjsIsReady.value) return;

		if (haveValuesChanged.value) {
			haveValuesChanged.value = false;
			return;
		}

		if (isEqual(newVal?.blocks, oldVal?.blocks)) {
			editorjsIsInitialized.value = true;

Review comment (suggestion):
any reason not to use type and equality comparison here? `editorjsIsInitialized.value === true`

Code after:

onMounted(async () => {
	editorjsRef.value = new EditorJS({
		logLevel: 'ERROR' as EditorJS.LogLevels,
		holder: editorElement.value,
		readOnly: false,
		placeholder: props.placeholder,
		minHeight: 72,
		onChange: (api) => emitValue(api),
		tools: tools,
	});

	await editorjsRef.value.isReady;

	const sanitizedValue = sanitizeValue(props.value);

	if (sanitizedValue) {
		await editorjsRef.value.render(sanitizedValue);
	}

	if (props.autofocus) {
		editorjsRef.value.focus();
	}

	editorjsRef.value.on(BlockChanged, () => {
		if (editorjsIsInitialized.value === true) {
			emitValue(editorjsRef.value);
		}
	});

	editorjsIsReady.value = true;
});

onUnmounted(() => {
	editorjsRef.value?.destroy();
	bus.reset();
});

watch(
	() => props.value,
	async (newVal, oldVal) => {
		// First value will be set in 'onMounted'
		if (!editorjsRef.value || !editorjsIsReady.value) return;

		if (haveValuesChanged.value) {
			haveValuesChanged.value = false;
			return;
		}

		if (isEqual(newVal?.blocks, oldVal?.blocks)) {
			editorjsIsInitialized.value = true;
Repository: directus/directus
File: api/src/database/helpers/schema/dialects/mssql.ts (TypeScript)

Code before:
		groupByFields: (string | Knex.Raw)[],
		sortRecords: SortRecord[],
		_hasRelationalSort: boolean,
	) {
		/*
		MSSQL requires all selected columns that are not aggregated over are to be present in the GROUP BY clause

		> When the select list has no aggregations, each column in the select list must be included in the GROUP BY list.

		https://learn.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver16#g-syntax-variations-for-group-by

		MSSQL does not support aliases in the GROUP BY clause

		> The column expression cannot contain:
			A column alias that is defined in the SELECT list. It can use a column alias for a derived table that is defined
			in the FROM clause.

		https://learn.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver16
		 */

		if (sortRecords.length > 0) {
			groupByFields.push(...sortRecords.map(({ column }) => column));
		}
	}

	override getColumnMaxLength(): number {
		return 128;
	}

	override getTableMaxLength(): number {
		return 128;
	}
}


Review comment (suggestion):
```suggestion
	override getColumnNameMaxLength(): number {
```

Code after:
		groupByFields: (string | Knex.Raw)[],
		sortRecords: SortRecord[],
		_hasRelationalSort: boolean,
	) {
		/*
		MSSQL requires all selected columns that are not aggregated over are to be present in the GROUP BY clause

		> When the select list has no aggregations, each column in the select list must be included in the GROUP BY list.

		https://learn.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver16#g-syntax-variations-for-group-by

		MSSQL does not support aliases in the GROUP BY clause

		> The column expression cannot contain:
			A column alias that is defined in the SELECT list. It can use a column alias for a derived table that is defined
			in the FROM clause.

		https://learn.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver16
		 */

		if (sortRecords.length > 0) {
			groupByFields.push(...sortRecords.map(({ column }) => column));
		}
	}

	override getColumnNameMaxLength(): number {
		return 128;
	}

	override getTableNameMaxLength(): number {
		return 128;
	}
}