CDM results cache warming fails for all SQL Server CDM sources with the following error:
PreparedStatementCallback; bad SQL grammar [...
join @vocabTableQualifier.concept c on cc.concept_id = c.concept_id
...]; SQL state [S0002]; error code [137];
Must declare the scalar variable "@vocabTableQualifier".
The @vocabTableQualifier placeholder is never substituted before the SQL is sent to SQL Server, causing the query to fail. This affects all SQL Server CDM sources regardless of version (observed in 2.14.1 and 2.15.1).
Root cause
There is a parameter name mismatch between CDMCacheService.java and the SQL template files.
In CDMCacheService.java, the PreparedStatementRenderer is constructed with the table parameter named "vocabularyTableQualifier":
String[] tables = {"resultTableQualifier", "vocabularyTableQualifier"};
This causes SqlRender to substitute @vocabularyTableQualifier in the SQL. However, the SQL template files (getBatchConceptRecordCount.sql, getConceptRecordCount.sql, and their person-count variants) use @vocabTableQualifier — a different name — so it is never substituted.
Expected behavior
The vocabulary schema name is substituted into the SQL before execution, e.g.:
join OMOP_2025_11_21_HBB_85_DD_18.concept c on cc.concept_id = c.concept_id
Fix
Either:
Rename @vocabTableQualifier → @vocabularyTableQualifier in the 4 affected SQL template files, or
Change "vocabularyTableQualifier" → "vocabTableQualifier" in CDMCacheService.java
Environment
WebAPI versions: 2.14.0, 2.15.1
CDM database: SQL Server
WebAPI database: PostgreSQL
CDM results cache warming fails for all SQL Server CDM sources with the following error:
PreparedStatementCallback; bad SQL grammar [...
join @vocabTableQualifier.concept c on cc.concept_id = c.concept_id
...]; SQL state [S0002]; error code [137];
Must declare the scalar variable "@vocabTableQualifier".
The @vocabTableQualifier placeholder is never substituted before the SQL is sent to SQL Server, causing the query to fail. This affects all SQL Server CDM sources regardless of version (observed in 2.14.1 and 2.15.1).
Root cause
There is a parameter name mismatch between CDMCacheService.java and the SQL template files.
In CDMCacheService.java, the PreparedStatementRenderer is constructed with the table parameter named "vocabularyTableQualifier":
String[] tables = {"resultTableQualifier", "vocabularyTableQualifier"};
This causes SqlRender to substitute @vocabularyTableQualifier in the SQL. However, the SQL template files (getBatchConceptRecordCount.sql, getConceptRecordCount.sql, and their person-count variants) use @vocabTableQualifier — a different name — so it is never substituted.
Expected behavior
The vocabulary schema name is substituted into the SQL before execution, e.g.:
join OMOP_2025_11_21_HBB_85_DD_18.concept c on cc.concept_id = c.concept_id
Fix
Either:
Rename @vocabTableQualifier → @vocabularyTableQualifier in the 4 affected SQL template files, or
Change "vocabularyTableQualifier" → "vocabTableQualifier" in CDMCacheService.java
Environment
WebAPI versions: 2.14.0, 2.15.1
CDM database: SQL Server
WebAPI database: PostgreSQL