Wrong results for queries using virtual schemas that contain the constant condition WHERE FALSE

Details

Detail name Value
Changelog Number 16241
Type Bug
Status Resolved
Affected Versions Exasol 7.1.0, Exasol 8.0.0
Fix Versions Exasol 7.1.23, Exasol 8.21.0
Resolution Date 2023-08-04

Description

A query using virtual schemas may produce wrong results if the following conditions are met:

  • Exasol performs only a partial pushdown to the remote system (i.e., not the complete query).
  • The query contains a WHERE condition that evaluates to FALSE (i.e., 1 = 2).
  • The partial pushdown contains the WHERE condition.
  • The original query does not contain WHERE FALSE.

Preparation

create SCHEMA test;
open schema test;
--/
CREATE OR REPLACE PYTHON3 ADAPTER SCRIPT test.vs_adapter AS
import json
import string
def adapter_call(request):
    # database expects utf-8 encoded string of type str. unicode not yet supported
    root = json.loads(request)
    if root["type"] == "createVirtualSchema":
        res = {
            "type": "createVirtualSchema",
            "schemaMetadata": {'tables': [{'name': 'VT', 'columns': [{'dataType': {'type': 'BOOLEAN'}, 'name': 'VC'}]}]}
        }
        return json.dumps(res)
    elif root["type"] == "dropVirtualSchema":
        return json.dumps({"type": "dropVirtualSchema"})
    elif root["type"] == "setProperties":
        return json.dumps({"type": "setProperties"})
    elif root["type"] == "refresh":
        return json.dumps({"type": "refresh"})
    if root["type"] == "getCapabilities":
        return json.dumps({
            "type": "getCapabilities",
            "capabilities": ["FILTER_EXPRESSIONS", "LITERAL_BOOL"]
            }) # database expects utf-8 encoded string of type str. unicode not yet supported.
    elif root["type"] == "pushdown":
        res = {
            "type": "pushdown",
            "sql": "SELECT true FROM DUAL WHERE FALSE"
        }
        return json.dumps(res)
    else:
        raise ValueError('Unsupported callback')
/
;

DROP VIRTUAL SCHEMA IF EXISTS test_vs CASCADE;
CREATE VIRTUAL SCHEMA test_vs USING test.vs_adapter;

Example

-- returns a | NULL instead of 0 rows
SELECT * FROM (
  SELECT 'a' AS c, vc FROM dual 
  LEFT JOIN test_vs.vt ON true
  ) 
  WHERE c = 'b';

 

Workaround

Use a scalar subquery in the WHERE condition.

-- returns 0 rows
SELECT * FROM (
  SELECT 'a' AS c, vc FROM dual 
  LEFT JOIN test_vs.vt ON true
  ) 
  WHERE c = (SELECT 'b' FROM DUAL);

Fix

Those queries run as expected.