Skip to content

Commit 1468eba

Browse files
suryaiyer95claude
andcommitted
fix: address code review findings in data-diff orchestrator
- `buildColumnDiscoverySQL`: escape single quotes in all interpolated table name parts to prevent SQL injection via crafted source/target names - `dateTruncExpr`: add Oracle case (`TRUNC(col, 'UNIT')`) — Oracle does not have `DATE_TRUNC`, date-partitioned diffs on Oracle tables previously failed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e3df5a4 commit 1468eba

File tree

1 file changed

+11
-5
lines changed
  • packages/opencode/src/altimate/native/connections

1 file changed

+11
-5
lines changed

packages/opencode/src/altimate/native/connections/data-diff.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,19 +213,22 @@ interface ColumnInfo {
213213
* auto-timestamp defaults without an extra query.
214214
*/
215215
function buildColumnDiscoverySQL(tableName: string, dialect: string): string {
216+
// Escape single quotes for safe interpolation into SQL string literals.
217+
const esc = (s: string) => s.replace(/'/g, "''")
218+
216219
// Parse schema.table or db.schema.table
217220
const parts = tableName.split(".")
218221
let schemaFilter = ""
219222
let tableFilter = ""
220223

221224
if (parts.length === 3) {
222-
schemaFilter = `table_schema = '${parts[1]}'`
223-
tableFilter = `table_name = '${parts[2]}'`
225+
schemaFilter = `table_schema = '${esc(parts[1])}'`
226+
tableFilter = `table_name = '${esc(parts[2])}'`
224227
} else if (parts.length === 2) {
225-
schemaFilter = `table_schema = '${parts[0]}'`
226-
tableFilter = `table_name = '${parts[1]}'`
228+
schemaFilter = `table_schema = '${esc(parts[0])}'`
229+
tableFilter = `table_name = '${esc(parts[1])}'`
227230
} else {
228-
tableFilter = `table_name = '${parts[0]}'`
231+
tableFilter = `table_name = '${esc(parts[0])}'`
229232
}
230233

231234
switch (dialect) {
@@ -390,6 +393,9 @@ function dateTruncExpr(granularity: string, column: string, dialect: string): st
390393
const fmt = { day: "%Y-%m-%d", week: "%Y-%u", month: "%Y-%m-01", year: "%Y-01-01" }[g] ?? "%Y-%m-01"
391394
return `DATE_FORMAT(${column}, '${fmt}')`
392395
}
396+
case "oracle":
397+
// Oracle uses TRUNC(), not DATE_TRUNC()
398+
return `TRUNC(${column}, '${g.toUpperCase()}')`
393399
default:
394400
// Postgres, Snowflake, Redshift, DuckDB, etc.
395401
return `DATE_TRUNC('${g}', ${column})`

0 commit comments

Comments
 (0)