Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 96 additions & 9 deletions eng/pipelines/pr-validation-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
SQLServer2022:
sqlVersion: 'SQL2022'
pythonVersion: '3.13'
SQLServer2025:
sqlVersion: 'SQL2025'
pythonVersion: '3.13'
LocalDB_Python314:
sqlVersion: 'LocalDB'
pythonVersion: '3.14'
Expand Down Expand Up @@ -124,6 +127,38 @@
env:
DB_PASSWORD: $(DB_PASSWORD)

# Install SQL Server 2025 (for SQL2025 matrix)
- powershell: |
Write-Host "Downloading SQL Server 2025..."
# Download SQL Server 2025 installer
$ProgressPreference = 'SilentlyContinue'
# Note: Using 2025 preview/CTP link - update when final release is available
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2302249" -OutFile "SQL2025-SSEI-Expr.exe"

Write-Host "Installing SQL Server 2025..."
# Install SQL Server 2025 with basic features
Start-Process -FilePath "SQL2025-SSEI-Expr.exe" -ArgumentList "/Action=Download","/MediaPath=$env:TEMP","/MediaType=Core","/Quiet" -Wait

# Find the downloaded setup file
$setupFile = Get-ChildItem -Path $env:TEMP -Filter "SQLEXPR_x64_ENU.exe" -Recurse | Select-Object -First 1

if ($setupFile) {
Write-Host "Extracting SQL Server setup files..."
Start-Process -FilePath $setupFile.FullName -ArgumentList "/x:$env:TEMP\SQLSetup","/u" -Wait

Write-Host "Running SQL Server setup..."
Start-Process -FilePath "$env:TEMP\SQLSetup\setup.exe" -ArgumentList "/Q","/ACTION=Install","/FEATURES=SQLEngine","/INSTANCENAME=MSSQLSERVER","/SQLSVCACCOUNT=`"NT AUTHORITY\SYSTEM`"","/SQLSYSADMINACCOUNTS=`"BUILTIN\Administrators`"","/TCPENABLED=1","/SECURITYMODE=SQL","/SAPWD=$(DB_PASSWORD)","/IACCEPTSQLSERVERLICENSETERMS" -Wait
} else {
Write-Error "Failed to download SQL Server setup file"
exit 1
}

Write-Host "SQL Server 2025 installation completed"
displayName: 'Install SQL Server 2025'
condition: eq(variables['sqlVersion'], 'SQL2025')
env:
DB_PASSWORD: $(DB_PASSWORD)

# Create database for SQL Server 2022
- powershell: |
# Wait for SQL Server to start
Expand Down Expand Up @@ -159,6 +194,41 @@
env:
DB_PASSWORD: $(DB_PASSWORD)

# Create database for SQL Server 2025
- powershell: |
# Wait for SQL Server to start
$maxAttempts = 30
$attempt = 0
$connected = $false

Write-Host "Waiting for SQL Server 2025 to start..."
while (-not $connected -and $attempt -lt $maxAttempts) {
try {
sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -Q "SELECT 1" -C

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
$connected = $true
Write-Host "SQL Server is ready!"
} catch {
$attempt++
Write-Host "Waiting... ($attempt/$maxAttempts)"
Start-Sleep -Seconds 2
}
}

if (-not $connected) {
Write-Error "Failed to connect to SQL Server after $maxAttempts attempts"
exit 1
}

# Create database and user
sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -Q "CREATE DATABASE TestDB" -C

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -Q "CREATE LOGIN testuser WITH PASSWORD = '$(DB_PASSWORD)'" -C

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -d TestDB -Q "CREATE USER testuser FOR LOGIN testuser" -C

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -d TestDB -Q "ALTER ROLE db_owner ADD MEMBER testuser" -C

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production
displayName: 'Setup database and user for SQL Server 2025'
condition: eq(variables['sqlVersion'], 'SQL2025')
env:
DB_PASSWORD: $(DB_PASSWORD)

- script: |
cd mssql_python\pybind
build.bat x64
Expand All @@ -180,7 +250,15 @@
env:
DB_CONNECTION_STRING: 'Server=localhost;Database=TestDB;Uid=testuser;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'

# Download and restore AdventureWorks2022 database for benchmarking
# Run tests for SQL Server 2025
- script: |
python -m pytest -v --junitxml=test-results-sql2025.xml --cov=. --cov-report=xml:coverage-sql2025.xml --capture=tee-sys --cache-clear
displayName: 'Run tests with coverage on SQL Server 2025'
condition: eq(variables['sqlVersion'], 'SQL2025')
env:
DB_CONNECTION_STRING: 'Server=localhost;Database=TestDB;Uid=testuser;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'

Check notice

Code scanning / devskim

Accessing localhost could indicate debug code, or could hinder scaling. Note

Do not leave debug code in production

Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment was updated to indicate SQL Server 2025, but this step's condition was changed from SQL2022 to SQL2025 (line 295). This suggests the original SQL Server 2022 benchmarking step was replaced rather than duplicated. The comment should be reverted to reference SQL Server 2022, and a separate step should be added for SQL Server 2025.

Suggested change
# Download and restore AdventureWorks2022 database for benchmarking on SQL Server 2022
- powershell: |
Write-Host "Downloading AdventureWorks2022.bak..."
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri "https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2022.bak" -OutFile "$env:TEMP\AdventureWorks2022.bak"
Write-Host "Restoring AdventureWorks2022 database..."
# Get the default data and log paths
$dataPath = sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -Q "SET NOCOUNT ON; SELECT SERVERPROPERTY('InstanceDefaultDataPath') AS DataPath" -h -1 -C | Out-String
$logPath = sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -Q "SET NOCOUNT ON; SELECT SERVERPROPERTY('InstanceDefaultLogPath') AS LogPath" -h -1 -C | Out-String
$dataPath = $dataPath.Trim()
$logPath = $logPath.Trim()
Write-Host "Data path: $dataPath"
Write-Host "Log path: $logPath"
# Restore the database
sqlcmd -S "localhost" -U "sa" -P "$(DB_PASSWORD)" -C -Q @"
RESTORE DATABASE AdventureWorks2022
FROM DISK = '$env:TEMP\AdventureWorks2022.bak'
WITH
MOVE 'AdventureWorks2022' TO '${dataPath}AdventureWorks2022.mdf',
MOVE 'AdventureWorks2022_log' TO '${logPath}AdventureWorks2022_log.ldf',
REPLACE
"@
if ($LASTEXITCODE -eq 0) {
Write-Host "AdventureWorks2022 database restored successfully"
} else {
Write-Error "Failed to restore AdventureWorks2022 database"
exit 1
}
displayName: 'Download and restore AdventureWorks2022 database'
condition: eq(variables['sqlVersion'], 'SQL2022')
env:
DB_PASSWORD: $(DB_PASSWORD)

Copilot uses AI. Check for mistakes.
# Download and restore AdventureWorks2022 database for benchmarking on SQL Server 2025
- powershell: |
Write-Host "Downloading AdventureWorks2022.bak..."
$ProgressPreference = 'SilentlyContinue'
Expand Down Expand Up @@ -214,11 +292,11 @@
exit 1
}
displayName: 'Download and restore AdventureWorks2022 database'
condition: eq(variables['sqlVersion'], 'SQL2022')
condition: eq(variables['sqlVersion'], 'SQL2025')
Comment on lines 294 to +295
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AdventureWorks database download and restore step condition was changed from SQL2022 to SQL2025, which removes benchmarking capability for SQL Server 2022. Since the PR adds SQL Server 2025 support without removing SQL Server 2022, both versions should have their own benchmark steps. The condition should remain as SQL2022 for this step, and a separate identical step should be added for SQL2025.

Copilot uses AI. Check for mistakes.
env:
DB_PASSWORD: $(DB_PASSWORD)

# Run performance benchmarks on SQL Server 2022
# Run performance benchmarks on SQL Server 2025
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment was updated to indicate SQL Server 2025, but this step's condition was changed from SQL2022 to SQL2025 (line 388). This suggests the original SQL Server 2022 benchmarking step was replaced rather than duplicated. The comment should be reverted to reference SQL Server 2022, and a separate step should be added for SQL Server 2025.

Suggested change
# Run performance benchmarks on SQL Server 2025
# Run performance benchmarks on SQL Server 2022

Copilot uses AI. Check for mistakes.
- powershell: |
Write-Host "Checking and installing ODBC Driver 18 for SQL Server..."

Expand Down Expand Up @@ -306,8 +384,8 @@

Write-Host "`nRunning performance benchmarks..."
python benchmarks/perf-benchmarking.py
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The performance benchmark step condition was changed from SQL2022 to SQL2025, which removes benchmarking capability for SQL Server 2022. Since the PR adds SQL Server 2025 support without removing SQL Server 2022, both versions should have their own benchmark steps. The condition should remain as SQL2022 for this step, and a separate identical step should be added for SQL2025.

Suggested change
python benchmarks/perf-benchmarking.py
python benchmarks/perf-benchmarking.py
displayName: 'Run performance benchmarks on SQL Server 2022'
condition: eq(variables['sqlVersion'], 'SQL2022')
continueOnError: true
env:
DB_CONNECTION_STRING: 'Server=localhost;Database=AdventureWorks2022;Uid=sa;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'
- powershell: |
Write-Host "Checking and installing ODBC Driver 18 for SQL Server..."
# Check if ODBC Driver 18 is registered in Windows registry
$odbcDriverKey = "HKLM:\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server"
$driverExists = Test-Path $odbcDriverKey
if ($driverExists) {
Write-Host "✓ ODBC Driver 18 for SQL Server is already installed and registered"
$driverPath = (Get-ItemProperty -Path $odbcDriverKey -Name "Driver" -ErrorAction SilentlyContinue).Driver
if ($driverPath) {
Write-Host " Driver location: $driverPath"
}
} else {
Write-Host "ODBC Driver 18 for SQL Server is not installed. Installing now..."
# Ensure temp directory exists
$tempDir = "$env:TEMP\ODBCDriver18"
if (-Not (Test-Path $tempDir)) {
New-Item -ItemType Directory -Path $tempDir | Out-Null
}
$installerPath = "$tempDir\msodbcsql18.msi"
# Download ODBC Driver 18 installer if not already downloaded
if (-Not (Test-Path $installerPath)) {
Write-Host "Downloading ODBC Driver 18 installer..."
$downloadUrl = "https://go.microsoft.com/fwlink/?linkid=2249004"
Invoke-WebRequest -Uri $downloadUrl -OutFile $installerPath -UseBasicParsing
} else {
Write-Host "Installer already downloaded at $installerPath"
}
# Install ODBC Driver 18 silently
Write-Host "Installing ODBC Driver 18..."
$msiArgs = "/i `"$installerPath`" /qn IACCEPTMSODBCSQLLICENSETERMS=YES"
$process = Start-Process "msiexec.exe" -ArgumentList $msiArgs -Wait -PassThru
if ($process.ExitCode -eq 0) {
Write-Host "✓ ODBC Driver 18 installation completed successfully"
} else {
Write-Error "ODBC Driver 18 installation failed with exit code $($process.ExitCode)"
exit 1
}
}
# Verify presence of ODBC Driver 18 in the filesystem
Write-Host "`nVerifying ODBC Driver 18 files..."
$possiblePaths = @(
"C:\Program Files\Microsoft ODBC Driver 18 for SQL Server\msodbcsql18.dll",
"C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\msodbcsql18.dll"
)
$driverFound = $false
foreach ($path in $possiblePaths) {
if (Test-Path $path) {
Write-Host "✓ Found ODBC Driver 18 DLL at: $path"
$driverFound = $true
}
}
if (-Not $driverFound) {
Write-Host "ODBC Driver 18 DLL not found in default locations, but installation may still be valid."
}
# Final verification using registry
Write-Host "`nVerifying ODBC Driver 18 installation..."
$verifyKey = Test-Path "HKLM:\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server"
if ($verifyKey) {
$driverInfo = Get-ItemProperty -Path "HKLM:\SOFTWARE\ODBC\ODBCINST.INI\ODBC Driver 18 for SQL Server" -ErrorAction SilentlyContinue
Write-Host "✓ SUCCESS: ODBC Driver 18 for SQL Server is registered"
Write-Host " Driver: $($driverInfo.Driver)"
Write-Host " Setup: $($driverInfo.Setup)"
} else {
Write-Error "ODBC Driver 18 for SQL Server is not registered in ODBC"
Write-Host "`nListing all installed ODBC drivers from registry:"
Get-ChildItem "HKLM:\SOFTWARE\ODBC\ODBCINST.INI" -ErrorAction SilentlyContinue | ForEach-Object { Write-Host " - $($_.PSChildName)" }
exit 1
}
Write-Host "`nInstalling pyodbc..."
pip install pyodbc
Write-Host "`nRunning performance benchmarks..."
python benchmarks/perf-benchmarking.py

Copilot uses AI. Check for mistakes.
displayName: 'Run performance benchmarks on SQL Server 2022'
condition: eq(variables['sqlVersion'], 'SQL2022')
displayName: 'Run performance benchmarks on SQL Server 2025'
condition: eq(variables['sqlVersion'], 'SQL2025')
continueOnError: true
env:
DB_CONNECTION_STRING: 'Server=localhost;Database=AdventureWorks2022;Uid=sa;Pwd=$(DB_PASSWORD);TrustServerCertificate=yes'
Expand Down Expand Up @@ -350,6 +428,15 @@
pool:
vmImage: 'macos-latest'

strategy:
matrix:
SQL2022:
sqlServerImage: 'mcr.microsoft.com/mssql/server:2022-latest'
sqlVersion: 'SQL2022'
SQL2025:
sqlServerImage: 'mcr.microsoft.com/mssql/server:2025-latest'
sqlVersion: 'SQL2025'

steps:
- task: UsePythonVersion@0
inputs:
Expand Down Expand Up @@ -382,13 +469,13 @@

- script: |
# Pull and run SQL Server container
docker pull mcr.microsoft.com/mssql/server:2022-latest
docker pull $(sqlServerImage)
docker run \
--name sqlserver \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD="${DB_PASSWORD}" \
-p 1433:1433 \
-d mcr.microsoft.com/mssql/server:2022-latest
-d $(sqlServerImage)

# Starting SQL Server container…
for i in {1..30}; do
Expand All @@ -400,7 +487,7 @@
-C -Q "SELECT 1" && break
sleep 2
done
displayName: 'Pull & start SQL Server (Docker)'
displayName: 'Pull & start SQL Server $(sqlVersion) (Docker)'
env:
DB_PASSWORD: $(DB_PASSWORD)

Expand All @@ -426,7 +513,7 @@
condition: succeededOrFailed()
inputs:
testResultsFiles: '**/test-results.xml'
testRunTitle: 'Publish pytest results on macOS'
testRunTitle: 'Publish pytest results on macOS $(sqlVersion)'

- job: PytestOnLinux
displayName: 'Linux x86_64'
Expand Down
Loading