From e486335550b82b674dea0a726718127689c17aa8 Mon Sep 17 00:00:00 2001 From: Benjamin Gaidioz Date: Mon, 23 Dec 2024 17:12:57 +0100 Subject: [PATCH] Fixed RD-15252: date vs. timestamp comparisons not supported in SOQL --- .../das/salesforce/DASSalesforceTable.scala | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/scala/com/rawlabs/das/salesforce/DASSalesforceTable.scala b/src/main/scala/com/rawlabs/das/salesforce/DASSalesforceTable.scala index 3cbdeec..841c362 100644 --- a/src/main/scala/com/rawlabs/das/salesforce/DASSalesforceTable.scala +++ b/src/main/scala/com/rawlabs/das/salesforce/DASSalesforceTable.scala @@ -206,11 +206,27 @@ abstract class DASSalesforceTable( "SELECT " + salesforceColumns.mkString(", ") + " FROM " + salesforceObjectName } } - val (supportedQuals, unsupportedQuals) = quals.partition(_.hasSimpleQual) // Only simple quals are supported + + def isSupportedQual(q: Qual): Boolean = { + if (!q.hasSimpleQual) { + logger.warn("Unsupported qual (not SimpleQual)") + return false + } + val colType = columnTypes(q.getFieldName) + val dateColVsTimestampValue = colType.hasDate && q.getSimpleQual.getValue.hasTimestamp + if (dateColVsTimestampValue) { + // This isn't supported in SOQL + logger.warn("Unsupported qual (date column vs timestamp value)") + return false + } + true + } + + val (supportedQuals, unsupportedQuals) = quals.partition(isSupportedQual) if (supportedQuals.nonEmpty) { soql += " WHERE " + supportedQuals .map { q => - assert(q.hasSimpleQual, "Only simple quals are supported") + val value = q.getSimpleQual.getValue // at this point we know it's a SimpleQual val op = q.getSimpleQual.getOperator val soqlOp = if (op.hasEquals) "=" @@ -222,7 +238,23 @@ abstract class DASSalesforceTable( assert(op.hasNotEquals) "<>" } - renameToSalesforce(q.getFieldName) + " " + soqlOp + " " + rawValueToSOQLValue(q.getSimpleQual.getValue) + val colType = columnTypes(q.getFieldName) + val colName = renameToSalesforce(q.getFieldName) + if (colType.hasTimestamp && value.hasDate) { + // Turn the date value into a timestamp value (00:00:00) + val timestampValue = { + val date = value.getDate + Value + .newBuilder() + .setTimestamp( + ValueTimestamp.newBuilder().setYear(date.getYear).setMonth(date.getMonth).setDay(date.getDay) + ) + .build() + } + renameToSalesforce(q.getFieldName) + " " + soqlOp + " " + rawValueToSOQLValue(timestampValue) + } else { + colName + " " + soqlOp + " " + rawValueToSOQLValue(value) + } } .mkString(" AND ") }